diff --git a/DEPS b/DEPS index 32979fa..c7adc49 100644 --- a/DEPS +++ b/DEPS
@@ -133,11 +133,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '3b7170b34551d49cf123537ff089a9b55f1bd7b2', + 'skia_revision': '44c8131b779b1a21bae524733663014d3614a5ed', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'a4404f08610f8dde2b745329ac5813c4a6a84c70', + 'v8_revision': '72287902200674b17fbc4557a6a9fb6c67f0542c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -145,11 +145,11 @@ # 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': '37b996425a0e72b07a79fd8e86c288ba8021aa4a', + 'angle_revision': '094c40dce6015add9e9524364a4e9b0523b7c31e', # 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': '9b62c5ea2af36ae332392a8a1d48c4b818c3f114', + 'swiftshader_revision': 'af973b67141eb2f8abf7e5bcf109f829fae0abbc', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -264,7 +264,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'ea2c7f20f2f96e15570f7e9416fb6c826f809747', + 'dawn_revision': '5625b63202797c54ff1f5a40d9ee664ca23cfce8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -760,7 +760,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '5d5aed4520ccd3a427528736661b2420ff8e9df9', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '7a62eb7d2b04fa3418bfd1ab4dbc40be74818e64', 'condition': 'checkout_linux', }, @@ -1073,7 +1073,7 @@ 'src/third_party/nasm': { 'url': Var('chromium_git') + '/chromium/deps/nasm.git' + '@' + - '4ee6a69ce33be1e96fd3c44a6e3ae3d8177453da' + '076332ea7c414313ab9d6d5b56396641051df5ea' }, 'src/third_party/netty-tcnative/src': { @@ -1127,7 +1127,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f702532c71518410b9e9c738bd88516b7e6863c4', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '29885798ac66d92369e98bc90a51ee2d2e497ec4', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1194,7 +1194,7 @@ }, 'src/third_party/re2/src': - Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + '96b75fa24527a1475525b4c12d30fe365b6f9650', + Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + '5a982a6dba7c4d98b443471823be0bd9d9677143', 'src/third_party/r8': { 'packages': [ @@ -1339,7 +1339,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@05e8371e668ab2e8ed8dfc4377ef3dfb111a1e4b', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@eae9be8ac5e0e8fbaae7c5af4a5db0fc0f6d2be8', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 119dfe65..0508eda 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -663,6 +663,7 @@ 'android_webview/tools/run_cts.pydeps', 'base/android/jni_generator/jni_generator.pydeps', 'base/android/jni_generator/jni_registration_generator.pydeps', + 'build/android/devil_chromium.pydeps', 'build/android/gyp/aar.pydeps', 'build/android/gyp/aidl.pydeps', 'build/android/gyp/apkbuilder.pydeps',
diff --git a/WATCHLISTS b/WATCHLISTS index 6c84dd9..a4ea778 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -1815,7 +1815,8 @@ 'wnwen+watch@chromium.org'], 'android_crazy_linker': ['johnmaguire+watch@google.com'], 'android_deps': ['wnwen+watch@chromium.org'], - 'android_features': ['wnwen+watch@chromium.org'], + 'android_features': ['wnwen+watch@chromium.org', + 'tiborg+watch@chromium.org'], 'android_infobars': ['dfalcantara+watch@chromium.org'], 'android_infra': ['agrieve+watch@chromium.org', 'estevenson+watch@chromium.org',
diff --git a/android_webview/browser/gfx/browser_view_renderer.cc b/android_webview/browser/gfx/browser_view_renderer.cc index edfdce3..4da521a 100644 --- a/android_webview/browser/gfx/browser_view_renderer.cc +++ b/android_webview/browser/gfx/browser_view_renderer.cc
@@ -16,6 +16,7 @@ #include "base/strings/stringprintf.h" #include "base/supports_user_data.h" #include "base/trace_event/traced_value.h" +#include "cc/base/math_util.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/quads/compositor_frame.h" #include "content/public/browser/render_process_host.h" @@ -232,10 +233,40 @@ offscreen_pre_raster_ ? gfx::Size() : external_draw_constraints_.viewport_size; + gfx::Rect viewport_rect_for_tile_priority_in_view_space; + gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization); + if (transform_for_tile_priority.GetInverse(&screen_to_view)) { + // Convert from screen space to view space. + viewport_rect_for_tile_priority_in_view_space = + cc::MathUtil::ProjectEnclosingClippedRect( + screen_to_view, gfx::Rect(viewport_size_for_tile_priority)); + } + viewport_rect_for_tile_priority_in_view_space.Intersect(gfx::Rect(size_)); + + // Explanation for the various viewports and transforms. There are: + // * "default" viewport" (and identity transform) that's normally used by + // compositor. This is |size_| in this file. + // * "draw" viewport and transform. Compositor applies them at the root at + // draw time. This is contained in SkCanvas for a software draw + // * "tile" viewport and transform. These are set in hardware draw to + // correctly prioritize and raster tiles. + // The draw viewport was added to support software draw's ability to change + // the viewport and transform at draw time to anything the embedding app + // desires. However the tile system was not expecting its viewport to jump + // around, and only move incrementally due to user input. This required adding + // the tile viewport and transform. Tile and default are separate to reduce + // memory in the case when only a small portion of webview (ie the default + // viewport) is actually visible. + // We intersect the tile viewport with the default viewport above so that the + // tile viewport can only shrink and not grow from the default viewport. This + // is because webview can also be small in relation to the surface size, so + // and growing the tile viewport can cause more tiles to be rastered than + // necessary. + scoped_refptr<content::SynchronousCompositor::FrameFuture> future = - compositor_->DemandDrawHwAsync(size_, - gfx::Rect(viewport_size_for_tile_priority), - transform_for_tile_priority); + compositor_->DemandDrawHwAsync( + size_, viewport_rect_for_tile_priority_in_view_space, + transform_for_tile_priority); CopyOutputRequestQueue requests; copy_requests_.swap(requests); for (auto& copy_request_ptr : requests) {
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index 85c82a0..1fca956a 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -554,21 +554,17 @@ const ui::KeyEvent& key_event) { if (key_event.type() == ui::ET_KEY_PRESSED && key_event.key_code() == ui::VKEY_RETURN) { - if (!IsSearchBoxTrimmedQueryEmpty()) { + if (is_search_box_active()) { // Hitting Enter when focus is on search box opens the first result. ui::KeyEvent event(key_event); views::View* first_result_view = contents_view_->search_results_page_view()->first_result_view(); if (first_result_view) first_result_view->OnKeyEvent(&event); - return true; - } - - if (!is_search_box_active()) { + } else { SetSearchBoxActive(true, key_event.type()); - return true; } - return false; + return true; } // Events occurring over an inactive search box are handled elsewhere, with
diff --git a/ash/shelf/shelf_app_button.cc b/ash/shelf/shelf_app_button.cc index 29f04bef..7be32e5 100644 --- a/ash/shelf/shelf_app_button.cc +++ b/ash/shelf/shelf_app_button.cc
@@ -294,8 +294,7 @@ // static const char ShelfAppButton::kViewClassName[] = "ash/ShelfAppButton"; -ShelfAppButton::ShelfAppButton(ShelfView* shelf_view, - const base::string16& title) +ShelfAppButton::ShelfAppButton(ShelfView* shelf_view) : ShelfButton(shelf_view), icon_view_(new views::ImageView()), indicator_(new AppStatusIndicatorView()), @@ -304,7 +303,6 @@ destroyed_flag_(nullptr), is_notification_indicator_enabled_( features::IsNotificationIndicatorEnabled()) { - SetTitle(title); const gfx::ShadowValue kShadows[] = { gfx::ShadowValue(gfx::Vector2d(0, 2), 0, SkColorSetARGB(0x1A, 0, 0, 0)), gfx::ShadowValue(gfx::Vector2d(0, 3), 1, SkColorSetARGB(0x1A, 0, 0, 0)), @@ -343,10 +341,6 @@ image, icon_shadows_)); } -void ShelfAppButton::SetTitle(const base::string16 title) { - SetAccessibleName(title); -} - void ShelfAppButton::SetImage(const gfx::ImageSkia& image) { if (image.isNull()) { // TODO: need an empty image.
diff --git a/ash/shelf/shelf_app_button.h b/ash/shelf/shelf_app_button.h index 34835b5e..4489900 100644 --- a/ash/shelf/shelf_app_button.h +++ b/ash/shelf/shelf_app_button.h
@@ -45,12 +45,9 @@ STATE_ACTIVE = 1 << 6, }; - ShelfAppButton(ShelfView* shelf_view, const base::string16& title); + explicit ShelfAppButton(ShelfView* shelf_view); ~ShelfAppButton() override; - // Sets the textual title for this entry, to be shown in a tooltip. - void SetTitle(const base::string16 title); - // Sets the image to display for this entry. void SetImage(const gfx::ImageSkia& image);
diff --git a/ash/shelf/shelf_button.cc b/ash/shelf/shelf_button.cc index 10279b0..2ca7dcd 100644 --- a/ash/shelf/shelf_button.cc +++ b/ash/shelf/shelf_button.cc
@@ -62,16 +62,8 @@ // triggered by Button::GetAccessibleNodeData. (See https://crbug.com/932200) void ShelfButton::GetAccessibleNodeData(ui::AXNodeData* node_data) { node_data->role = ax::mojom::Role::kButton; - node_data->SetName(GetAccessibleName()); -} - -bool ShelfButton::GetTooltipText(const gfx::Point& p, - base::string16* tooltip) const { - // Copy the proper tooltip text, but return false because we do not want to - // show a tooltip with the standard view mechanism and instead use the - // custom display logic defined in |ShelfTooltipManager|. - *tooltip = GetAccessibleName(); - return false; + const base::string16 title = shelf_view_->GetTitleForView(this); + node_data->SetName(title.empty() ? GetAccessibleName() : title); } ////////////////////////////////////////////////////////////////////////////////
diff --git a/ash/shelf/shelf_button.h b/ash/shelf/shelf_button.h index 00bc50b8..70de19c 100644 --- a/ash/shelf/shelf_button.h +++ b/ash/shelf/shelf_button.h
@@ -25,8 +25,6 @@ bool OnMouseDragged(const ui::MouseEvent& event) override; void AboutToRequestFocusFromTabTraversal(bool reverse) override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; - bool GetTooltipText(const gfx::Point& p, - base::string16* tooltip) const override; protected: ShelfView* shelf_view() { return shelf_view_; }
diff --git a/ash/shelf/shelf_tooltip_manager.cc b/ash/shelf/shelf_tooltip_manager.cc index 864a4b2e..57e6cc6c 100644 --- a/ash/shelf/shelf_tooltip_manager.cc +++ b/ash/shelf/shelf_tooltip_manager.cc
@@ -84,10 +84,8 @@ bubble_ = new ShelfTooltipPreviewBubble(view, open_windows, this, alignment, shelf_background_color); } else { - base::string16 title; - view->GetTooltipText(gfx::Point(), &title); - bubble_ = - new ShelfTooltipBubble(view, alignment, shelf_background_color, title); + bubble_ = new ShelfTooltipBubble(view, alignment, shelf_background_color, + shelf_view_->GetTitleForView(view)); } aura::Window* window = bubble_->GetWidget()->GetNativeWindow();
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index 5880e16..c8b1dd6 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -502,6 +502,14 @@ return ShelfItemForView(view) && !IsShowingMenuForView(view); } +base::string16 ShelfView::GetTitleForView(const views::View* view) const { + if (view == overflow_button_) + return overflow_button_->GetAccessibleName(); + + const ShelfItem* item = ShelfItemForView(view); + return item ? item->title : base::string16(); +} + gfx::Rect ShelfView::GetVisibleItemsBoundsInScreen() { gfx::Size preferred_size = GetPreferredSize(); gfx::Point origin(GetMirroredXWithWidthInView(0, preferred_size.width()), 0); @@ -1330,7 +1338,7 @@ case TYPE_BROWSER_SHORTCUT: case TYPE_APP: case TYPE_DIALOG: { - ShelfAppButton* button = new ShelfAppButton(this, item.title); + ShelfAppButton* button = new ShelfAppButton(this); button->SetImage(item.image); button->ReflectItemStatus(item); view = button; @@ -2115,7 +2123,6 @@ CHECK_EQ(ShelfAppButton::kViewClassName, view->GetClassName()); ShelfAppButton* button = static_cast<ShelfAppButton*>(view); button->ReflectItemStatus(item); - button->SetTitle(item.title); button->SetImage(item.image); button->SchedulePaint(); break;
diff --git a/ash/shelf/shelf_view.h b/ash/shelf/shelf_view.h index c36bf2e..8af59e6 100644 --- a/ash/shelf/shelf_view.h +++ b/ash/shelf/shelf_view.h
@@ -171,6 +171,9 @@ // Returns true if a tooltip should be shown for the shelf item |view|. bool ShouldShowTooltipForView(const views::View* view) const; + // Returns the title of the shelf item |view|. + base::string16 GetTitleForView(const views::View* view) const; + // Returns rectangle bounding all visible launcher items. Used screen // coordinate system. gfx::Rect GetVisibleItemsBoundsInScreen();
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc index 99b7ed55..656b3dd 100644 --- a/ash/shelf/shelf_view_unittest.cc +++ b/ash/shelf/shelf_view_unittest.cc
@@ -1387,9 +1387,8 @@ for (int i = 0; i < test_api_->GetButtonCount(); i++) { ShelfAppButton* button = test_api_->GetButton(i); if (button) { - base::string16 tooltip; - button->GetTooltipText(gfx::Point(), &tooltip); - EXPECT_EQ(tooltip, button->GetAccessibleName()) + EXPECT_EQ(shelf_view_->GetTitleForView(button), + button->GetAccessibleName()) << "Each button's tooltip text should read the same as its " << "accessible name"; }
diff --git a/base/BUILD.gn b/base/BUILD.gn index 6379ad9..a2b1e0a 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2808,7 +2808,6 @@ "debug/elf_reader_unittest.cc", "files/dir_reader_posix_unittest.cc", "files/file_descriptor_watcher_posix_unittest.cc", - "fuchsia/file_utils_unittest.cc", "fuchsia/filtered_service_directory_unittest.cc", "fuchsia/service_directory_test_base.cc", "fuchsia/service_directory_test_base.h",
diff --git a/base/base_paths_win.cc b/base/base_paths_win.cc index 590a9c8c..c516874 100644 --- a/base/base_paths_win.cc +++ b/base/base_paths_win.cc
@@ -54,8 +54,7 @@ cur = FilePath(system_buffer); break; case base::DIR_PROGRAM_FILESX86: - if (base::win::OSInfo::GetInstance()->architecture() != - base::win::OSInfo::X86_ARCHITECTURE) { + if (win::OSInfo::GetArchitecture() != win::OSInfo::X86_ARCHITECTURE) { if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILESX86, NULL, SHGFP_TYPE_CURRENT, wsystem_buffer))) return false;
diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h index d2a5692..35460a66 100644 --- a/base/debug/activity_tracker.h +++ b/base/debug/activity_tracker.h
@@ -801,12 +801,12 @@ // records it's important to ensure that what is returned was created before // the |exit_stamp|. Movement of |process_data| information is allowed. using ProcessExitCallback = - Callback<void(int64_t process_id, - int64_t exit_stamp, - int exit_code, - ProcessPhase exit_phase, - std::string&& command_line, - ActivityUserData::Snapshot&& process_data)>; + RepeatingCallback<void(int64_t process_id, + int64_t exit_stamp, + int exit_code, + ProcessPhase exit_phase, + std::string&& command_line, + ActivityUserData::Snapshot&& process_data)>; // This structure contains information about a loaded module, as shown to // users of the tracker.
diff --git a/base/debug/activity_tracker_unittest.cc b/base/debug/activity_tracker_unittest.cc index 94bb7b6..8ad82ce 100644 --- a/base/debug/activity_tracker_unittest.cc +++ b/base/debug/activity_tracker_unittest.cc
@@ -487,7 +487,7 @@ // Get callbacks for process exit. global->SetProcessExitCallback( - Bind(&ActivityTrackerTest::HandleProcessExit, Unretained(this))); + BindRepeating(&ActivityTrackerTest::HandleProcessExit, Unretained(this))); // Pretend than another process has started. global->RecordProcessLaunch(other_process_id, FILE_PATH_LITERAL("foo --bar"));
diff --git a/base/fuchsia/file_utils.cc b/base/fuchsia/file_utils.cc index d5286b6a..bb012b8 100644 --- a/base/fuchsia/file_utils.cc +++ b/base/fuchsia/file_utils.cc
@@ -4,14 +4,9 @@ #include "base/fuchsia/file_utils.h" -#include <fcntl.h> #include <lib/fdio/fd.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> -#include <utility> - +#include "base/files/file.h" #include "base/fuchsia/fuchsia_logging.h" namespace base { @@ -21,24 +16,26 @@ const char kServiceDirectoryPath[] = "/svc"; const char kPackageRootDirectoryPath[] = "/pkg"; -fidl::InterfaceHandle<::fuchsia::io::Directory> OpenDirectory( - const base::FilePath& path) { - int fd = open(path.value().c_str(), O_DIRECTORY | O_RDONLY); - if (fd < 0) { - DPLOG(ERROR) << "Failed to open " << path; - return fidl::InterfaceHandle<::fuchsia::io::Directory>(); - } - - zx::channel channel; - zx_status_t status = fdio_fd_transfer(fd, channel.reset_and_get_address()); +zx::handle GetHandleFromFile(File file) { + zx::handle handle; + zx_status_t status = + fdio_fd_transfer(file.GetPlatformFile(), handle.reset_and_get_address()); if (status != ZX_ERR_UNAVAILABLE) - PCHECK(close(fd)); - if (status != ZX_OK) { - ZX_DLOG(ERROR, status) << "fdio_fd_transfer"; - return fidl::InterfaceHandle<::fuchsia::io::Directory>(); - } + ignore_result(file.TakePlatformFile()); + if (status == ZX_OK) + return handle; + ZX_DLOG(ERROR, status) << "fdio_fd_transfer"; + return zx::handle(); +} - return fidl::InterfaceHandle<::fuchsia::io::Directory>(std::move(channel)); +base::File GetFileFromHandle(zx::handle handle) { + base::ScopedFD fd; + zx_status_t status = + fdio_fd_create(handle.release(), base::ScopedFD::Receiver(fd).get()); + if (status == ZX_OK) + return base::File(fd.release()); + ZX_LOG(WARNING, status) << "fdio_fd_create"; + return base::File(); } } // namespace fuchsia
diff --git a/base/fuchsia/file_utils.h b/base/fuchsia/file_utils.h index b1df755..1b249929 100644 --- a/base/fuchsia/file_utils.h +++ b/base/fuchsia/file_utils.h
@@ -5,12 +5,14 @@ #ifndef BASE_FUCHSIA_FILE_UTILS_H_ #define BASE_FUCHSIA_FILE_UTILS_H_ -#include <fuchsia/io/cpp/fidl.h> +#include <lib/zx/handle.h> #include "base/base_export.h" -#include "base/files/file_path.h" namespace base { + +class File; + namespace fuchsia { // Persisted data directory, i.e. /data . Returned as DIR_APP_DATA from @@ -23,10 +25,14 @@ // Package root directory, i.e. /pkg . BASE_EXPORT extern const char kPackageRootDirectoryPath[]; -// Returns fuchsia.io.Directory for the specified |path| or null InterfaceHandle -// if the path doesn't exist or it's not a directory. -BASE_EXPORT fidl::InterfaceHandle<::fuchsia::io::Directory> OpenDirectory( - const base::FilePath& path); +// Gets a Zircon handle from a file or directory |path| in the process' +// namespace. +BASE_EXPORT zx::handle GetHandleFromFile(base::File file); + +// Makes a File object from a Zircon handle. +// Returns an empty File if |handle| is invalid or not a valid PA_FDIO_REMOTE +// descriptor. +BASE_EXPORT base::File GetFileFromHandle(zx::handle handle); } // namespace fuchsia } // namespace base
diff --git a/base/fuchsia/file_utils_unittest.cc b/base/fuchsia/file_utils_unittest.cc deleted file mode 100644 index 11bb1a2..0000000 --- a/base/fuchsia/file_utils_unittest.cc +++ /dev/null
@@ -1,44 +0,0 @@ -// 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 "base/fuchsia/file_utils.h" - -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace base { -namespace fuchsia { - -class OpenDirectoryTest : public testing::Test { - protected: - void SetUp() override { - EXPECT_TRUE(temp_dir.CreateUniqueTempDirUnderPath( - base::FilePath(kPersistedDataDirectoryPath))); - } - - ScopedTempDir temp_dir; -}; - -TEST_F(OpenDirectoryTest, Open) { - auto dir = OpenDirectory(temp_dir.GetPath()); - ASSERT_TRUE(dir); -} - -// OpenDirectory() should fail when opening a directory that doesn't exist. -TEST_F(OpenDirectoryTest, OpenNonExistent) { - auto dir = OpenDirectory(temp_dir.GetPath().AppendASCII("non_existent")); - ASSERT_FALSE(dir); -} - -// OpenDirectory() should open only directories. -TEST_F(OpenDirectoryTest, OpenFile) { - auto file_path = temp_dir.GetPath().AppendASCII("test_file"); - ASSERT_TRUE(WriteFile(file_path, "foo", 3)); - auto dir = OpenDirectory(file_path); - ASSERT_FALSE(dir); -} - -} // namespace fuchsia -} // namespace base \ No newline at end of file
diff --git a/base/fuchsia/filtered_service_directory.cc b/base/fuchsia/filtered_service_directory.cc index 0fc3e22f..28ee3a2 100644 --- a/base/fuchsia/filtered_service_directory.cc +++ b/base/fuchsia/filtered_service_directory.cc
@@ -4,7 +4,7 @@ #include "base/fuchsia/filtered_service_directory.h" -#include <lib/fdio/util.h> +#include <lib/fdio/directory.h> #include <utility> #include "base/bind.h"
diff --git a/base/fuchsia/service_directory_client.cc b/base/fuchsia/service_directory_client.cc index 48379a7b..c3b1a47 100644 --- a/base/fuchsia/service_directory_client.cc +++ b/base/fuchsia/service_directory_client.cc
@@ -4,7 +4,7 @@ #include "base/fuchsia/service_directory_client.h" -#include <lib/fdio/util.h> +#include <lib/fdio/directory.h> #include <utility> #include "base/fuchsia/file_utils.h" @@ -17,11 +17,19 @@ namespace { +fidl::InterfaceHandle<::fuchsia::io::Directory> ConnectToServiceRoot() { + fidl::InterfaceHandle<::fuchsia::io::Directory> directory; + zx_status_t result = fdio_service_connect( + kServiceDirectoryPath, directory.NewRequest().TakeChannel().release()); + ZX_CHECK(result == ZX_OK, result) << "Failed to open /svc"; + return directory; +} + // Singleton container for the process-global ServiceDirectoryClient instance. std::unique_ptr<ServiceDirectoryClient>* ProcessServiceDirectoryClient() { static base::NoDestructor<std::unique_ptr<ServiceDirectoryClient>> - service_directory_client_ptr(std::make_unique<ServiceDirectoryClient>( - OpenDirectory(base::FilePath(kServiceDirectoryPath)))); + service_directory_client_ptr( + std::make_unique<ServiceDirectoryClient>(ConnectToServiceRoot())); return service_directory_client_ptr.get(); }
diff --git a/base/fuchsia/service_directory_test_base.cc b/base/fuchsia/service_directory_test_base.cc index 6ec454a..c476c6d 100644 --- a/base/fuchsia/service_directory_test_base.cc +++ b/base/fuchsia/service_directory_test_base.cc
@@ -4,7 +4,7 @@ #include "base/fuchsia/service_directory_test_base.h" -#include <lib/fdio/util.h> +#include <lib/fdio/directory.h> #include <utility> namespace base {
diff --git a/base/fuchsia/service_directory_unittest.cc b/base/fuchsia/service_directory_unittest.cc index 61f8bc9..2f8d1b9 100644 --- a/base/fuchsia/service_directory_unittest.cc +++ b/base/fuchsia/service_directory_unittest.cc
@@ -4,7 +4,7 @@ #include "base/fuchsia/service_directory.h" -#include <lib/fdio/util.h> +#include <lib/fdio/fdio.h> #include <lib/zx/channel.h> #include <utility>
diff --git a/base/fuchsia/service_provider_impl_unittest.cc b/base/fuchsia/service_provider_impl_unittest.cc index 9163031..4a36b30 100644 --- a/base/fuchsia/service_provider_impl_unittest.cc +++ b/base/fuchsia/service_provider_impl_unittest.cc
@@ -4,7 +4,6 @@ #include "base/fuchsia/service_provider_impl.h" -#include <lib/fdio/util.h> #include <lib/zx/channel.h> #include <utility>
diff --git a/base/logging.h b/base/logging.h index 250239a..3b2ac9c 100644 --- a/base/logging.h +++ b/base/logging.h
@@ -300,10 +300,10 @@ // however clients can use this function to override with their own handling // (e.g. a silent one for Unit Tests) using LogAssertHandlerFunction = - base::Callback<void(const char* file, - int line, - const base::StringPiece message, - const base::StringPiece stack_trace)>; + base::RepeatingCallback<void(const char* file, + int line, + const base::StringPiece message, + const base::StringPiece stack_trace)>; class BASE_EXPORT ScopedLogAssertHandler { public:
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h index 702f873..d9c2c58 100644 --- a/base/mac/sdk_forward_declarations.h +++ b/base/mac/sdk_forward_declarations.h
@@ -339,6 +339,7 @@ @interface VNBarcodeObservation : VNRectangleObservation @property(readonly, nonatomic, copy) NSString* payloadStringValue; +@property(readonly, nonatomic, copy) VNBarcodeSymbology symbology; @end #endif // MAC_OS_X_VERSION_10_13
diff --git a/base/memory/memory_pressure_listener.h b/base/memory/memory_pressure_listener.h index 7e97010..084ddd5 100644 --- a/base/memory/memory_pressure_listener.h +++ b/base/memory/memory_pressure_listener.h
@@ -35,13 +35,13 @@ // } // // // Start listening. -// MemoryPressureListener* my_listener = -// new MemoryPressureListener(base::Bind(&OnMemoryPressure)); +// auto listener = std::make_unique<MemoryPressureListener>( +// base::BindRepeating(&OnMemoryPressure)); // // ... // // // Stop listening. -// delete my_listener; +// listener.reset(); // class BASE_EXPORT MemoryPressureListener { public: @@ -63,8 +63,9 @@ MEMORY_PRESSURE_LEVEL_CRITICAL, }; - typedef Callback<void(MemoryPressureLevel)> MemoryPressureCallback; - typedef Callback<void(MemoryPressureLevel)> SyncMemoryPressureCallback; + using MemoryPressureCallback = RepeatingCallback<void(MemoryPressureLevel)>; + using SyncMemoryPressureCallback = + RepeatingCallback<void(MemoryPressureLevel)>; explicit MemoryPressureListener( const MemoryPressureCallback& memory_pressure_callback);
diff --git a/base/memory/memory_pressure_listener_unittest.cc b/base/memory/memory_pressure_listener_unittest.cc index 7c095ec..b536b568 100644 --- a/base/memory/memory_pressure_listener_unittest.cc +++ b/base/memory/memory_pressure_listener_unittest.cc
@@ -20,8 +20,8 @@ test::ScopedTaskEnvironment::MainThreadType::UI) {} void SetUp() override { - listener_.reset(new MemoryPressureListener( - Bind(&MemoryPressureListenerTest::OnMemoryPressure, Unretained(this)))); + listener_ = std::make_unique<MemoryPressureListener>(BindRepeating( + &MemoryPressureListenerTest::OnMemoryPressure, Unretained(this))); } void TearDown() override {
diff --git a/base/memory/memory_pressure_monitor.h b/base/memory/memory_pressure_monitor.h index e48244b..b56a6605 100644 --- a/base/memory/memory_pressure_monitor.h +++ b/base/memory/memory_pressure_monitor.h
@@ -24,7 +24,8 @@ class BASE_EXPORT MemoryPressureMonitor { public: using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel; - using DispatchCallback = base::Callback<void(MemoryPressureLevel level)>; + using DispatchCallback = + base::RepeatingCallback<void(MemoryPressureLevel level)>; virtual ~MemoryPressureMonitor();
diff --git a/base/memory/memory_pressure_monitor_chromeos.cc b/base/memory/memory_pressure_monitor_chromeos.cc index 25ab1e6..018f25f 100644 --- a/base/memory/memory_pressure_monitor_chromeos.cc +++ b/base/memory/memory_pressure_monitor_chromeos.cc
@@ -119,7 +119,7 @@ GetCriticalMemoryThresholdInPercent(thresholds)), low_mem_file_(HANDLE_EINTR(::open(kLowMemFile, O_RDONLY))), dispatch_callback_( - base::Bind(&MemoryPressureListener::NotifyMemoryPressure)), + base::BindRepeating(&MemoryPressureListener::NotifyMemoryPressure)), weak_ptr_factory_(this) { DCHECK(!g_monitor); g_monitor = this; @@ -154,11 +154,11 @@ } void MemoryPressureMonitor::StartObserving() { - timer_.Start(FROM_HERE, - TimeDelta::FromMilliseconds(kMemoryPressureIntervalMs), - Bind(&MemoryPressureMonitor:: - CheckMemoryPressureAndRecordStatistics, - weak_ptr_factory_.GetWeakPtr())); + timer_.Start( + FROM_HERE, TimeDelta::FromMilliseconds(kMemoryPressureIntervalMs), + BindRepeating( + &MemoryPressureMonitor::CheckMemoryPressureAndRecordStatistics, + weak_ptr_factory_.GetWeakPtr())); } void MemoryPressureMonitor::StopObserving() {
diff --git a/base/memory/memory_pressure_monitor_chromeos_unittest.cc b/base/memory/memory_pressure_monitor_chromeos_unittest.cc index 4c9c6ad..0139610a 100644 --- a/base/memory/memory_pressure_monitor_chromeos_unittest.cc +++ b/base/memory/memory_pressure_monitor_chromeos_unittest.cc
@@ -84,8 +84,8 @@ test::ScopedTaskEnvironment::MainThreadType::UI); std::unique_ptr<TestMemoryPressureMonitor> monitor( new TestMemoryPressureMonitor); - std::unique_ptr<MemoryPressureListener> listener( - new MemoryPressureListener(base::Bind(&OnMemoryPressure))); + auto listener = std::make_unique<MemoryPressureListener>( + base::BindRepeating(&OnMemoryPressure)); // Checking the memory pressure while 0% are used should not produce any // events. monitor->SetMemoryInPercentOverride(0);
diff --git a/base/memory/memory_pressure_monitor_mac.cc b/base/memory/memory_pressure_monitor_mac.cc index 678c276..4a19eac 100644 --- a/base/memory/memory_pressure_monitor_mac.cc +++ b/base/memory/memory_pressure_monitor_mac.cc
@@ -56,7 +56,7 @@ DISPATCH_MEMORYPRESSURE_NORMAL, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))), dispatch_callback_( - base::Bind(&MemoryPressureListener::NotifyMemoryPressure)), + base::BindRepeating(&MemoryPressureListener::NotifyMemoryPressure)), last_statistic_report_time_(CFAbsoluteTimeGetCurrent()), last_pressure_level_(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE), subtick_seconds_(0) {
diff --git a/base/memory/memory_pressure_monitor_win.cc b/base/memory/memory_pressure_monitor_win.cc index 1dd48c5..396daf5 100644 --- a/base/memory/memory_pressure_monitor_win.cc +++ b/base/memory/memory_pressure_monitor_win.cc
@@ -57,7 +57,7 @@ MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE), moderate_pressure_repeat_count_(0), dispatch_callback_( - base::Bind(&MemoryPressureListener::NotifyMemoryPressure)), + base::BindRepeating(&MemoryPressureListener::NotifyMemoryPressure)), weak_ptr_factory_(this) { InferThresholds(); StartObserving(); @@ -71,7 +71,7 @@ MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE), moderate_pressure_repeat_count_(0), dispatch_callback_( - base::Bind(&MemoryPressureListener::NotifyMemoryPressure)), + base::BindRepeating(&MemoryPressureListener::NotifyMemoryPressure)), weak_ptr_factory_(this) { DCHECK_GE(moderate_threshold_mb_, critical_threshold_mb_); DCHECK_LE(0, critical_threshold_mb_); @@ -118,11 +118,11 @@ void MemoryPressureMonitor::StartObserving() { DCHECK(thread_checker_.CalledOnValidThread()); - timer_.Start(FROM_HERE, - TimeDelta::FromMilliseconds(kPollingIntervalMs), - Bind(&MemoryPressureMonitor:: - CheckMemoryPressureAndRecordStatistics, - weak_ptr_factory_.GetWeakPtr())); + timer_.Start( + FROM_HERE, TimeDelta::FromMilliseconds(kPollingIntervalMs), + BindRepeating( + &MemoryPressureMonitor::CheckMemoryPressureAndRecordStatistics, + weak_ptr_factory_.GetWeakPtr())); } void MemoryPressureMonitor::StopObserving() {
diff --git a/base/memory/memory_pressure_monitor_win_unittest.cc b/base/memory/memory_pressure_monitor_win_unittest.cc index b85fc46..ec64c547 100644 --- a/base/memory/memory_pressure_monitor_win_unittest.cc +++ b/base/memory/memory_pressure_monitor_win_unittest.cc
@@ -204,8 +204,8 @@ // Large-memory. testing::StrictMock<TestMemoryPressureMonitor> monitor(true); MemoryPressureListener listener( - base::Bind(&TestMemoryPressureMonitor::OnMemoryPressure, - base::Unretained(&monitor))); + base::BindRepeating(&TestMemoryPressureMonitor::OnMemoryPressure, + base::Unretained(&monitor))); // Checking the memory pressure at 0% load should not produce any // events.
diff --git a/base/process/launch_fuchsia.cc b/base/process/launch_fuchsia.cc index 24008ad..53c99f2b 100644 --- a/base/process/launch_fuchsia.cc +++ b/base/process/launch_fuchsia.cc
@@ -7,7 +7,6 @@ #include <lib/fdio/limits.h> #include <lib/fdio/namespace.h> #include <lib/fdio/spawn.h> -#include <lib/fdio/util.h> #include <lib/zx/job.h> #include <stdint.h> #include <unistd.h> @@ -181,15 +180,14 @@ } for (const auto& path_to_clone : options.paths_to_clone) { - fidl::InterfaceHandle<::fuchsia::io::Directory> directory = - base::fuchsia::OpenDirectory(path_to_clone); - if (!directory) { + zx::handle handle = fuchsia::GetHandleFromFile( + base::File(base::FilePath(path_to_clone), + base::File::FLAG_OPEN | base::File::FLAG_READ)); + if (!handle) { LOG(WARNING) << "Could not open handle for path: " << path_to_clone; return base::Process(); } - zx::handle handle = directory.TakeChannel(); - spawn_actions.push_back(FdioSpawnActionAddNamespaceEntry( path_to_clone.value().c_str(), handle.get())); transferred_handles.push_back(std::move(handle));
diff --git a/base/process/process_util_unittest.cc b/base/process/process_util_unittest.cc index b08292b..c694196 100644 --- a/base/process/process_util_unittest.cc +++ b/base/process/process_util_unittest.cc
@@ -264,14 +264,13 @@ // Attach the tempdir to "data", but also try to duplicate the existing "data" // directory. - options.paths_to_clone.push_back( - base::FilePath(base::fuchsia::kPersistedDataDirectoryPath)); + options.paths_to_clone.push_back(base::FilePath("/data")); options.paths_to_clone.push_back(base::FilePath("/tmp")); options.paths_to_transfer.push_back( - {FilePath(base::fuchsia::kPersistedDataDirectoryPath), - base::fuchsia::OpenDirectory( - base::FilePath(tmpdir_with_staged.GetPath())) - .TakeChannel() + {FilePath("/data"), + fuchsia::GetHandleFromFile( + base::File(base::FilePath(tmpdir_with_staged.GetPath()), + base::File::FLAG_OPEN | base::File::FLAG_READ)) .release()}); // Verify from that "/data/staged" exists from the child process' perspective. @@ -308,14 +307,14 @@ staged_file.Close(); // Mount the tempdir to "/foo". - zx::channel tmp_channel = - base::fuchsia::OpenDirectory(new_tmpdir.GetPath()).TakeChannel(); - - ASSERT_TRUE(tmp_channel.is_valid()); + zx::handle tmp_handle = fuchsia::GetHandleFromFile( + base::File(base::FilePath(new_tmpdir.GetPath()), + base::File::FLAG_OPEN | base::File::FLAG_READ)); + ASSERT_TRUE(tmp_handle.is_valid()); LaunchOptions options; options.paths_to_clone.push_back(base::FilePath("/tmp")); options.paths_to_transfer.push_back( - {base::FilePath("/foo"), tmp_channel.release()}); + {base::FilePath("/foo"), tmp_handle.release()}); options.spawn_flags = FDIO_SPAWN_CLONE_STDIO; // Verify from that "/foo/staged" exists from the child process' perspective.
diff --git a/base/task/sequence_manager/sequence_manager.h b/base/task/sequence_manager/sequence_manager.h index b6f08c1..15e635c 100644 --- a/base/task/sequence_manager/sequence_manager.h +++ b/base/task/sequence_manager/sequence_manager.h
@@ -136,7 +136,8 @@ // to identify the culprit if upcoming work results in a crash. // Key names must be thread-specific to avoid races and corrupted crash dumps. virtual void EnableCrashKeys(const char* file_name_crash_key, - const char* function_name_crash_key) = 0; + const char* function_name_crash_key, + const char* async_stack_crash_key) = 0; // Returns the metric recording configuration for the current SequenceManager. virtual const MetricRecordingSettings& GetMetricRecordingSettings() const = 0;
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc index 27b872e7..5d45100b 100644 --- a/base/task/sequence_manager/sequence_manager_impl.cc +++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -105,6 +105,23 @@ : kTaskSamplingRateForRecordingCPUTime); } +// Writes |address| in hexadecimal ("0x11223344") form starting from |output| +// and moving backwards in memory. Returns a pointer to the first digit of the +// result. Does *not* NUL-terminate the number. +#if !defined(OS_NACL) +char* PrependHexAddress(char* output, const void* address) { + uintptr_t value = reinterpret_cast<uintptr_t>(address); + static const char kHexChars[] = "0123456789ABCDEF"; + do { + *output-- = kHexChars[value % 16]; + value /= 16; + } while (value); + *output-- = 'x'; + *output = '0'; + return output; +} +#endif // !defined(OS_NACL) + } // namespace SequenceManagerImpl::SequenceManagerImpl( @@ -549,22 +566,11 @@ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "SequenceManagerImpl::NotifyWillProcessTaskObservers"); + RecordCrashKeys(executing_task->pending_task); + if (executing_task->task_queue->GetQuiescenceMonitored()) main_thread_only().task_was_run_on_quiescence_monitored_queue = true; -#if !defined(OS_NACL) - // SetCrashKeyString is a no-op even if the crash key is null, but we still - // have construct the StringPiece that is passed in. - if (main_thread_only().file_name_crash_key) { - debug::SetCrashKeyString( - main_thread_only().file_name_crash_key, - executing_task->pending_task.posted_from.file_name()); - debug::SetCrashKeyString( - main_thread_only().function_name_crash_key, - executing_task->pending_task.posted_from.function_name()); - } -#endif // OS_NACL - bool record_task_timing = ShouldRecordTaskTiming(executing_task->task_queue); if (record_task_timing) executing_task->task_timing.RecordTaskStart(time_before_task); @@ -941,7 +947,8 @@ void SequenceManagerImpl::EnableCrashKeys( const char* file_name_crash_key_name, - const char* function_name_crash_key_name) { + const char* function_name_crash_key_name, + const char* async_stack_crash_key) { DCHECK(!main_thread_only().file_name_crash_key); DCHECK(!main_thread_only().function_name_crash_key); #if !defined(OS_NACL) @@ -949,6 +956,51 @@ file_name_crash_key_name, debug::CrashKeySize::Size64); main_thread_only().function_name_crash_key = debug::AllocateCrashKeyString( function_name_crash_key_name, debug::CrashKeySize::Size64); + main_thread_only().async_stack_crash_key = debug::AllocateCrashKeyString( + async_stack_crash_key, debug::CrashKeySize::Size64); + static_assert(sizeof(main_thread_only().async_stack_buffer) == + static_cast<size_t>(debug::CrashKeySize::Size64), + "Async stack buffer size must match crash key size."); +#endif // OS_NACL +} + +void SequenceManagerImpl::RecordCrashKeys(const PendingTask& pending_task) { +#if !defined(OS_NACL) + // SetCrashKeyString is a no-op even if the crash key is null, but we'd still + // have construct the StringPiece that is passed in. + if (!main_thread_only().file_name_crash_key) + return; + + debug::SetCrashKeyString(main_thread_only().file_name_crash_key, + pending_task.posted_from.file_name()); + debug::SetCrashKeyString(main_thread_only().function_name_crash_key, + pending_task.posted_from.function_name()); + // Write the async stack trace onto a crash key as whitespace-delimited hex + // addresses. These will be symbolized by the crash reporting system. With + // 63 characters we can fit the address of the task that posted the current + // task and its predecessor. Avoid HexEncode since it incurs a memory + // allocation and snprintf because it's about 3.5x slower on Android this + // this. + // + // See + // https://chromium.googlesource.com/chromium/src/+/master/docs/debugging_with_crash_keys.md + // for instructions for symbolizing these crash keys. + // + // TODO(skyostil): Remove the above crash keys once the async stack trace + // has been verified to be reliable. + // TODO(skyostil): Find a way to extract the destination function address + // from the task. + size_t max_size = main_thread_only().async_stack_buffer.size(); + char* const buffer = &main_thread_only().async_stack_buffer[0]; + char* const buffer_end = &buffer[max_size - 1]; + char* pos = buffer_end; + // Leave space for the NUL terminator. + pos = PrependHexAddress(pos - 1, pending_task.task_backtrace[0]); + *(--pos) = ' '; + pos = PrependHexAddress(pos - 1, pending_task.posted_from.program_counter()); + DCHECK_GE(pos, buffer); + debug::SetCrashKeyString(main_thread_only().async_stack_crash_key, + StringPiece(pos, buffer_end - pos)); #endif // OS_NACL }
diff --git a/base/task/sequence_manager/sequence_manager_impl.h b/base/task/sequence_manager/sequence_manager_impl.h index af84d63..4ca8d599 100644 --- a/base/task/sequence_manager/sequence_manager_impl.h +++ b/base/task/sequence_manager/sequence_manager_impl.h
@@ -17,6 +17,7 @@ #include "base/atomic_sequence_num.h" #include "base/cancelable_callback.h" #include "base/containers/circular_deque.h" +#include "base/debug/crash_logging.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" @@ -38,10 +39,6 @@ namespace base { -namespace debug { -struct CrashKeyString; -} // namespace debug - namespace trace_event { class ConvertableToTraceFormat; } // namespace trace_event @@ -119,7 +116,8 @@ void SetWorkBatchSize(int work_batch_size) override; void SetTimerSlack(TimerSlack timer_slack) override; void EnableCrashKeys(const char* file_name_crash_key, - const char* function_name_crash_key) override; + const char* function_name_crash_key, + const char* async_stack_crash_key) override; const MetricRecordingSettings& GetMetricRecordingSettings() const override; size_t GetPendingTaskCountForTesting() const override; scoped_refptr<TaskQueue> CreateTaskQueue( @@ -249,6 +247,9 @@ // available. debug::CrashKeyString* file_name_crash_key = nullptr; debug::CrashKeyString* function_name_crash_key = nullptr; + debug::CrashKeyString* async_stack_crash_key = nullptr; + std::array<char, static_cast<size_t>(debug::CrashKeySize::Size64)> + async_stack_buffer = {}; std::mt19937_64 random_generator; std::uniform_real_distribution<double> uniform_distribution; @@ -344,6 +345,7 @@ bool ShouldRecordTaskTiming(const internal::TaskQueueImpl* task_queue); bool ShouldRecordCPUTimeForTask(); + void RecordCrashKeys(const PendingTask&); // Helper to terminate all scoped trace events to allow starting new ones // in TakeTask().
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc index 0397763..8ca4c366 100644 --- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc +++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -22,6 +22,7 @@ #include "base/single_thread_task_runner.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/stringprintf.h" #include "base/synchronization/waitable_event.h" #include "base/task/sequence_manager/real_time_domain.h" #include "base/task/sequence_manager/task_queue_impl.h" @@ -4563,6 +4564,56 @@ FastForwardUntilNoTasksRemain(); } +class MockCrashKeyImplementation : public debug::CrashKeyImplementation { + public: + MOCK_METHOD2(Allocate, + debug::CrashKeyString*(const char name[], debug::CrashKeySize)); + MOCK_METHOD2(Set, void(debug::CrashKeyString*, StringPiece)); + MOCK_METHOD1(Clear, void(debug::CrashKeyString*)); +}; + +TEST_P(SequenceManagerTest, CrashKeys) { + testing::InSequence sequence; + auto queue = CreateTaskQueue(); + auto runner = queue->CreateTaskRunner(kTaskTypeNone); + auto crash_key_impl = std::make_unique<MockCrashKeyImplementation>(); + RunLoop run_loop; + + MockCrashKeyImplementation* mock_impl = crash_key_impl.get(); + debug::SetCrashKeyImplementation(std::move(crash_key_impl)); + debug::CrashKeyString dummy_key("dummy", debug::CrashKeySize::Size64); + + // Parent task. + auto parent_location = FROM_HERE; + auto expected_stack1 = StringPrintf( + "0x%zX 0x0", + reinterpret_cast<uintptr_t>(parent_location.program_counter())); + EXPECT_CALL(*mock_impl, Allocate(_, _)).WillRepeatedly(Return(&dummy_key)); + EXPECT_CALL(*mock_impl, Set(_, testing::HasSubstr("sequence_manager_impl"))); + EXPECT_CALL(*mock_impl, Set(_, testing::HasSubstr("TestBody"))); + EXPECT_CALL(*mock_impl, Set(_, testing::StrEq(expected_stack1))); + + // Child task. + auto location = FROM_HERE; + auto expected_stack2 = StringPrintf( + "0x%zX 0x%zX", reinterpret_cast<uintptr_t>(location.program_counter()), + reinterpret_cast<uintptr_t>(parent_location.program_counter())); + EXPECT_CALL(*mock_impl, Set(_, testing::HasSubstr("sequence_manager_impl"))); + EXPECT_CALL(*mock_impl, Set(_, testing::HasSubstr("TestBody"))); + EXPECT_CALL(*mock_impl, Set(_, testing::StrEq(expected_stack2))); + + sequence_manager()->EnableCrashKeys("test-file", "test-function", + "test-async-stack"); + + // Run a task that posts another task to establish an asynchronous call stack. + runner->PostTask(parent_location, BindLambdaForTesting([&]() { + runner->PostTask(location, run_loop.QuitClosure()); + })); + run_loop.Run(); + + debug::SetCrashKeyImplementation(nullptr); +} + } // namespace sequence_manager_impl_unittest } // namespace internal } // namespace sequence_manager
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index ccecde3..a041c55 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -367,8 +367,12 @@ // Bind the new test subdirectory to /data in the child process' namespace. new_options.paths_to_transfer.push_back( - {kDataPath, - base::fuchsia::OpenDirectory(nested_data_path).TakeChannel().release()}); + {kDataPath, base::fuchsia::GetHandleFromFile( + base::File(nested_data_path, + base::File::FLAG_OPEN | base::File::FLAG_READ | + base::File::FLAG_DELETE_ON_CLOSE)) + .release()}); + #endif // defined(OS_FUCHSIA) #if defined(OS_LINUX) @@ -448,8 +452,9 @@ zx_status_t status = job_handle.kill(); ZX_CHECK(status == ZX_OK, status); - // Cleanup the data directory. - CHECK(DeleteFile(nested_data_path, true)); + // The child process' data dir should have been deleted automatically, + // thanks to the DELETE_ON_CLOSE flag. + DCHECK(!base::DirectoryExists(nested_data_path)); #elif defined(OS_POSIX) if (exit_code != 0) { // On POSIX, in case the test does not exit cleanly, either due to a crash
diff --git a/base/test/mock_callback.h b/base/test/mock_callback.h index 7ac4d346..1715f45 100644 --- a/base/test/mock_callback.h +++ b/base/test/mock_callback.h
@@ -11,7 +11,7 @@ // support both OnceCallback and RepeatingCallback. // // Use: -// using FooCallback = base::Callback<int(std::string)>; +// using FooCallback = base::RepeatingCallback<int(std::string)>; // // TEST(FooTest, RunsCallbackWithBarArgument) { // base::MockCallback<FooCallback> callback; @@ -38,13 +38,13 @@ class MockCallback; template <typename R> -class MockCallback<Callback<R()>> { +class MockCallback<RepeatingCallback<R()>> { public: MockCallback() = default; MOCK_METHOD0_T(Run, R()); - Callback<R()> Get() { - return Bind(&MockCallback::Run, Unretained(this)); + RepeatingCallback<R()> Get() { + return BindRepeating(&MockCallback::Run, Unretained(this)); } private: @@ -66,13 +66,13 @@ }; template <typename R, typename A1> -class MockCallback<Callback<R(A1)>> { +class MockCallback<RepeatingCallback<R(A1)>> { public: MockCallback() = default; MOCK_METHOD1_T(Run, R(A1)); - Callback<R(A1)> Get() { - return Bind(&MockCallback::Run, Unretained(this)); + RepeatingCallback<R(A1)> Get() { + return BindRepeating(&MockCallback::Run, Unretained(this)); } private: @@ -94,13 +94,13 @@ }; template <typename R, typename A1, typename A2> -class MockCallback<Callback<R(A1, A2)>> { +class MockCallback<RepeatingCallback<R(A1, A2)>> { public: MockCallback() = default; MOCK_METHOD2_T(Run, R(A1, A2)); - Callback<R(A1, A2)> Get() { - return Bind(&MockCallback::Run, Unretained(this)); + RepeatingCallback<R(A1, A2)> Get() { + return BindRepeating(&MockCallback::Run, Unretained(this)); } private: @@ -122,13 +122,13 @@ }; template <typename R, typename A1, typename A2, typename A3> -class MockCallback<Callback<R(A1, A2, A3)>> { +class MockCallback<RepeatingCallback<R(A1, A2, A3)>> { public: MockCallback() = default; MOCK_METHOD3_T(Run, R(A1, A2, A3)); - Callback<R(A1, A2, A3)> Get() { - return Bind(&MockCallback::Run, Unretained(this)); + RepeatingCallback<R(A1, A2, A3)> Get() { + return BindRepeating(&MockCallback::Run, Unretained(this)); } private: @@ -150,13 +150,13 @@ }; template <typename R, typename A1, typename A2, typename A3, typename A4> -class MockCallback<Callback<R(A1, A2, A3, A4)>> { +class MockCallback<RepeatingCallback<R(A1, A2, A3, A4)>> { public: MockCallback() = default; MOCK_METHOD4_T(Run, R(A1, A2, A3, A4)); - Callback<R(A1, A2, A3, A4)> Get() { - return Bind(&MockCallback::Run, Unretained(this)); + RepeatingCallback<R(A1, A2, A3, A4)> Get() { + return BindRepeating(&MockCallback::Run, Unretained(this)); } private: @@ -179,13 +179,13 @@ template <typename R, typename A1, typename A2, typename A3, typename A4, typename A5> -class MockCallback<Callback<R(A1, A2, A3, A4, A5)>> { +class MockCallback<RepeatingCallback<R(A1, A2, A3, A4, A5)>> { public: MockCallback() = default; MOCK_METHOD5_T(Run, R(A1, A2, A3, A4, A5)); - Callback<R(A1, A2, A3, A4, A5)> Get() { - return Bind(&MockCallback::Run, Unretained(this)); + RepeatingCallback<R(A1, A2, A3, A4, A5)> Get() { + return BindRepeating(&MockCallback::Run, Unretained(this)); } private: @@ -209,13 +209,13 @@ template <typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> -class MockCallback<Callback<R(A1, A2, A3, A4, A5, A6)>> { +class MockCallback<RepeatingCallback<R(A1, A2, A3, A4, A5, A6)>> { public: MockCallback() = default; MOCK_METHOD6_T(Run, R(A1, A2, A3, A4, A5, A6)); - Callback<R(A1, A2, A3, A4, A5, A6)> Get() { - return Bind(&MockCallback::Run, Unretained(this)); + RepeatingCallback<R(A1, A2, A3, A4, A5, A6)> Get() { + return BindRepeating(&MockCallback::Run, Unretained(this)); } private: @@ -239,13 +239,13 @@ template <typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> -class MockCallback<Callback<R(A1, A2, A3, A4, A5, A6, A7)>> { +class MockCallback<RepeatingCallback<R(A1, A2, A3, A4, A5, A6, A7)>> { public: MockCallback() = default; MOCK_METHOD7_T(Run, R(A1, A2, A3, A4, A5, A6, A7)); - Callback<R(A1, A2, A3, A4, A5, A6, A7)> Get() { - return Bind(&MockCallback::Run, Unretained(this)); + RepeatingCallback<R(A1, A2, A3, A4, A5, A6, A7)> Get() { + return BindRepeating(&MockCallback::Run, Unretained(this)); } private: @@ -269,13 +269,13 @@ template <typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> -class MockCallback<Callback<R(A1, A2, A3, A4, A5, A6, A7, A8)>> { +class MockCallback<RepeatingCallback<R(A1, A2, A3, A4, A5, A6, A7, A8)>> { public: MockCallback() = default; MOCK_METHOD8_T(Run, R(A1, A2, A3, A4, A5, A6, A7, A8)); - Callback<R(A1, A2, A3, A4, A5, A6, A7, A8)> Get() { - return Bind(&MockCallback::Run, Unretained(this)); + RepeatingCallback<R(A1, A2, A3, A4, A5, A6, A7, A8)> Get() { + return BindRepeating(&MockCallback::Run, Unretained(this)); } private: @@ -299,13 +299,13 @@ template <typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> -class MockCallback<Callback<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)>> { +class MockCallback<RepeatingCallback<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)>> { public: MockCallback() = default; MOCK_METHOD9_T(Run, R(A1, A2, A3, A4, A5, A6, A7, A8, A9)); - Callback<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> Get() { - return Bind(&MockCallback::Run, Unretained(this)); + RepeatingCallback<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> Get() { + return BindRepeating(&MockCallback::Run, Unretained(this)); } private: @@ -330,13 +330,14 @@ template <typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> -class MockCallback<Callback<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>> { +class MockCallback<RepeatingCallback<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, + A10)>> { public: MockCallback() = default; MOCK_METHOD10_T(Run, R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)); - Callback<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> Get() { - return Bind(&MockCallback::Run, Unretained(this)); + RepeatingCallback<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> Get() { + return BindRepeating(&MockCallback::Run, Unretained(this)); } private:
diff --git a/base/test/mock_callback.h.pump b/base/test/mock_callback.h.pump index 3372789..933d9ae 100644 --- a/base/test/mock_callback.h.pump +++ b/base/test/mock_callback.h.pump
@@ -17,7 +17,7 @@ // support both OnceCallback and RepeatingCallback. // // Use: -// using FooCallback = base::Callback<int(std::string)>; +// using FooCallback = base::RepeatingCallback<int(std::string)>; // // TEST(FooTest, RunsCallbackWithBarArgument) { // base::MockCallback<FooCallback> callback; @@ -49,13 +49,13 @@ $var run_type = [[R($for j, [[A$j]])]] template <typename R$for j [[, typename A$j]]> -class MockCallback<Callback<$run_type>> { +class MockCallback<RepeatingCallback<$run_type>> { public: MockCallback() = default; MOCK_METHOD$(i)_T(Run, $run_type); - Callback<$run_type> Get() { - return Bind(&MockCallback::Run, Unretained(this)); + RepeatingCallback<$run_type> Get() { + return BindRepeating(&MockCallback::Run, Unretained(this)); } private:
diff --git a/base/test/mock_callback_unittest.cc b/base/test/mock_callback_unittest.cc index c5f109f..b232499 100644 --- a/base/test/mock_callback_unittest.cc +++ b/base/test/mock_callback_unittest.cc
@@ -14,11 +14,11 @@ namespace { TEST(MockCallbackTest, ZeroArgs) { - MockCallback<Closure> mock_closure; + MockCallback<RepeatingClosure> mock_closure; EXPECT_CALL(mock_closure, Run()); mock_closure.Get().Run(); - MockCallback<Callback<int()>> mock_int_callback; + MockCallback<RepeatingCallback<int()>> mock_int_callback; { InSequence sequence; EXPECT_CALL(mock_int_callback, Run()).WillOnce(Return(42)); @@ -29,10 +29,11 @@ } TEST(MockCallbackTest, WithArgs) { - MockCallback<Callback<int(int, int)>> mock_two_int_callback; + MockCallback<RepeatingCallback<int(int, int)>> mock_two_int_callback; EXPECT_CALL(mock_two_int_callback, Run(1, 2)).WillOnce(Return(42)); EXPECT_CALL(mock_two_int_callback, Run(0, 0)).WillRepeatedly(Return(-1)); - Callback<int(int, int)> two_int_callback = mock_two_int_callback.Get(); + RepeatingCallback<int(int, int)> two_int_callback = + mock_two_int_callback.Get(); EXPECT_EQ(-1, two_int_callback.Run(0, 0)); EXPECT_EQ(42, two_int_callback.Run(1, 2)); EXPECT_EQ(-1, two_int_callback.Run(0, 0));
diff --git a/base/test/run_all_base_unittests.cc b/base/test/run_all_base_unittests.cc index da52310..aa7a9bf5 100644 --- a/base/test/run_all_base_unittests.cc +++ b/base/test/run_all_base_unittests.cc
@@ -11,5 +11,5 @@ base::TestSuite test_suite(argc, argv); return base::LaunchUnitTests( argc, argv, - base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite))); + base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite))); }
diff --git a/base/test/scoped_mock_time_message_loop_task_runner_unittest.cc b/base/test/scoped_mock_time_message_loop_task_runner_unittest.cc index b08323d..ac3b966 100644 --- a/base/test/scoped_mock_time_message_loop_task_runner_unittest.cc +++ b/base/test/scoped_mock_time_message_loop_task_runner_unittest.cc
@@ -77,10 +77,10 @@ bool task_10_has_run = false; bool task_11_has_run = false; - Closure task_1 = DoNothing(); - Closure task_2 = DoNothing(); - Closure task_10 = Bind(&AssignTrue, &task_10_has_run); - Closure task_11 = Bind(&AssignTrue, &task_11_has_run); + OnceClosure task_1 = DoNothing(); + OnceClosure task_2 = DoNothing(); + OnceClosure task_10 = BindOnce(&AssignTrue, &task_10_has_run); + OnceClosure task_11 = BindOnce(&AssignTrue, &task_11_has_run); constexpr TimeDelta task_1_delay = TimeDelta::FromSeconds(1); constexpr TimeDelta task_2_delay = TimeDelta::FromSeconds(2); @@ -89,10 +89,14 @@ constexpr TimeDelta step_time_by = TimeDelta::FromSeconds(5); - GetCurrentTaskRunner()->PostDelayedTask(FROM_HERE, task_1, task_1_delay); - GetCurrentTaskRunner()->PostDelayedTask(FROM_HERE, task_2, task_2_delay); - GetCurrentTaskRunner()->PostDelayedTask(FROM_HERE, task_10, task_10_delay); - GetCurrentTaskRunner()->PostDelayedTask(FROM_HERE, task_11, task_11_delay); + GetCurrentTaskRunner()->PostDelayedTask(FROM_HERE, std::move(task_1), + task_1_delay); + GetCurrentTaskRunner()->PostDelayedTask(FROM_HERE, std::move(task_2), + task_2_delay); + GetCurrentTaskRunner()->PostDelayedTask(FROM_HERE, std::move(task_10), + task_10_delay); + GetCurrentTaskRunner()->PostDelayedTask(FROM_HERE, std::move(task_11), + task_11_delay); scoped_task_runner_->task_runner()->FastForwardBy(step_time_by);
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index c2ef945..7b895ff 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc
@@ -72,6 +72,10 @@ #include "base/base_paths_fuchsia.h" #endif +#if defined(OS_WIN) && defined(_DEBUG) +#include <crtdbg.h> +#endif + namespace base { namespace { @@ -187,7 +191,7 @@ int RunUnitTestsUsingBaseTestSuite(int argc, char **argv) { TestSuite test_suite(argc, argv); return LaunchUnitTests(argc, argv, - Bind(&TestSuite::Run, Unretained(&test_suite))); + BindOnce(&TestSuite::Run, Unretained(&test_suite))); } TestSuite::TestSuite(int argc, char** argv) {
diff --git a/base/test/trace_to_file.cc b/base/test/trace_to_file.cc index 17aa80b..db2f46fd 100644 --- a/base/test/trace_to_file.cc +++ b/base/test/trace_to_file.cc
@@ -74,13 +74,13 @@ } static void OnTraceDataCollected( - Closure quit_closure, + OnceClosure quit_closure, trace_event::TraceResultBuffer* buffer, const scoped_refptr<RefCountedString>& json_events_str, bool has_more_events) { buffer->AddFragment(json_events_str->data()); if (!has_more_events) - quit_closure.Run(); + std::move(quit_closure).Run(); } void TraceToFile::EndTracingIfNeeded() {
diff --git a/base/timer/hi_res_timer_manager_win.cc b/base/timer/hi_res_timer_manager_win.cc index 49fe399..8d88179 100644 --- a/base/timer/hi_res_timer_manager_win.cc +++ b/base/timer/hi_res_timer_manager_win.cc
@@ -37,7 +37,7 @@ // Start polling the high resolution timer usage. Time::ResetHighResolutionTimerUsage(); timer_.Start(FROM_HERE, kUsageSampleInterval, - Bind(&ReportHighResolutionTimerUsage)); + BindRepeating(&ReportHighResolutionTimerUsage)); } HighResolutionTimerManager::~HighResolutionTimerManager() {
diff --git a/base/timer/mock_timer_unittest.cc b/base/timer/mock_timer_unittest.cc index b624742..0b51ed4 100644 --- a/base/timer/mock_timer_unittest.cc +++ b/base/timer/mock_timer_unittest.cc
@@ -20,8 +20,7 @@ base::MockOneShotTimer timer; base::TimeDelta delay = base::TimeDelta::FromSeconds(2); timer.Start(FROM_HERE, delay, - base::Bind(&CallMeMaybe, - base::Unretained(&calls))); + base::BindOnce(&CallMeMaybe, base::Unretained(&calls))); EXPECT_EQ(delay, timer.GetCurrentDelay()); EXPECT_TRUE(timer.IsRunning()); timer.Fire(); @@ -34,8 +33,7 @@ base::MockRepeatingTimer timer; base::TimeDelta delay = base::TimeDelta::FromSeconds(2); timer.Start(FROM_HERE, delay, - base::Bind(&CallMeMaybe, - base::Unretained(&calls))); + base::BindRepeating(&CallMeMaybe, base::Unretained(&calls))); timer.Fire(); EXPECT_TRUE(timer.IsRunning()); timer.Fire(); @@ -49,8 +47,7 @@ base::MockRepeatingTimer timer; base::TimeDelta delay = base::TimeDelta::FromSeconds(2); timer.Start(FROM_HERE, delay, - base::Bind(&CallMeMaybe, - base::Unretained(&calls))); + base::BindRepeating(&CallMeMaybe, base::Unretained(&calls))); EXPECT_TRUE(timer.IsRunning()); timer.Stop(); EXPECT_FALSE(timer.IsRunning()); @@ -72,8 +69,8 @@ base::TimeDelta delay = base::TimeDelta::FromSeconds(2); ASSERT_TRUE(weak_ptr.get()); timer.Start(FROM_HERE, delay, - base::Bind(base::DoNothing::Repeatedly<HasWeakPtr*>(), - base::Owned(has_weak_ptr))); + base::BindOnce(base::DoNothing::Once<HasWeakPtr*>(), + base::Owned(has_weak_ptr))); ASSERT_TRUE(weak_ptr.get()); timer.Fire(); ASSERT_FALSE(weak_ptr.get());
diff --git a/base/timer/timer_unittest.cc b/base/timer/timer_unittest.cc index ed0c1ee..7129fea 100644 --- a/base/timer/timer_unittest.cc +++ b/base/timer/timer_unittest.cc
@@ -189,7 +189,7 @@ int counter_; RunLoop run_loop_; - Closure quit_closure_; + RepeatingClosure quit_closure_; WaitableEvent* const did_run_; const TimeDelta delay_;
diff --git a/base/win/message_window_unittest.cc b/base/win/message_window_unittest.cc index 00248bf..f11b56b4 100644 --- a/base/win/message_window_unittest.cc +++ b/base/win/message_window_unittest.cc
@@ -29,20 +29,20 @@ // Checks that a window can be created. TEST(MessageWindowTest, Create) { win::MessageWindow window; - EXPECT_TRUE(window.Create(base::Bind(&HandleMessage))); + EXPECT_TRUE(window.Create(base::BindRepeating(&HandleMessage))); } // Checks that a named window can be created. TEST(MessageWindowTest, CreateNamed) { win::MessageWindow window; - EXPECT_TRUE(window.CreateNamed(base::Bind(&HandleMessage), - UTF8ToUTF16("test_message_window"))); + EXPECT_TRUE(window.CreateNamed(base::BindRepeating(&HandleMessage), + UTF8ToUTF16("test_message_window"))); } // Verifies that the created window can receive messages. TEST(MessageWindowTest, SendMessage) { win::MessageWindow window; - EXPECT_TRUE(window.Create(base::Bind(&HandleMessage))); + EXPECT_TRUE(window.Create(base::BindRepeating(&HandleMessage))); EXPECT_EQ(SendMessage(window.hwnd(), WM_USER, 100, 0), 100); } @@ -51,7 +51,7 @@ TEST(MessageWindowTest, FindWindow) { string16 name = UTF8ToUTF16(base::GenerateGUID()); win::MessageWindow window; - EXPECT_TRUE(window.CreateNamed(base::Bind(&HandleMessage), name)); + EXPECT_TRUE(window.CreateNamed(base::BindRepeating(&HandleMessage), name)); HWND hwnd = win::MessageWindow::FindWindow(name); EXPECT_TRUE(hwnd != NULL);
diff --git a/base/win/object_watcher.cc b/base/win/object_watcher.cc index 4c1c235..2a3824d 100644 --- a/base/win/object_watcher.cc +++ b/base/win/object_watcher.cc
@@ -86,8 +86,8 @@ // DoneWaiting can be synchronously called from RegisterWaitForSingleObject, // so set up all state now. - callback_ = - Bind(&ObjectWatcher::Signal, weak_factory_.GetWeakPtr(), delegate); + callback_ = BindRepeating(&ObjectWatcher::Signal, weak_factory_.GetWeakPtr(), + delegate); object_ = object; if (!RegisterWaitForSingleObject(&wait_object_, object, DoneWaiting,
diff --git a/base/win/object_watcher.h b/base/win/object_watcher.h index b7ed76d..0d26276 100644 --- a/base/win/object_watcher.h +++ b/base/win/object_watcher.h
@@ -107,7 +107,7 @@ // A callback pre-bound to Signal() that is posted to the caller's task runner // when the wait completes. - Closure callback_; + RepeatingClosure callback_; // The object being watched. HANDLE object_ = nullptr;
diff --git a/base/win/registry_unittest.cc b/base/win/registry_unittest.cc index 7d631d5..a8d10b4 100644 --- a/base/win/registry_unittest.cc +++ b/base/win/registry_unittest.cc
@@ -385,8 +385,8 @@ ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ)); - ASSERT_TRUE(key.StartWatching(Bind(&TestChangeDelegate::OnKeyChanged, - Unretained(&delegate)))); + ASSERT_TRUE(key.StartWatching( + BindRepeating(&TestChangeDelegate::OnKeyChanged, Unretained(&delegate)))); EXPECT_FALSE(delegate.WasCalled()); // Make some change. @@ -404,8 +404,8 @@ ASSERT_TRUE(delegate.WasCalled()); EXPECT_FALSE(delegate.WasCalled()); - ASSERT_TRUE(key.StartWatching(Bind(&TestChangeDelegate::OnKeyChanged, - Unretained(&delegate)))); + ASSERT_TRUE(key.StartWatching( + BindRepeating(&TestChangeDelegate::OnKeyChanged, Unretained(&delegate)))); // Change something else. EXPECT_EQ(ERROR_SUCCESS, key2.WriteValue(STRING16_LITERAL("name2"), @@ -413,8 +413,8 @@ RunLoop().Run(); ASSERT_TRUE(delegate.WasCalled()); - ASSERT_TRUE(key.StartWatching(Bind(&TestChangeDelegate::OnKeyChanged, - Unretained(&delegate)))); + ASSERT_TRUE(key.StartWatching( + BindRepeating(&TestChangeDelegate::OnKeyChanged, Unretained(&delegate)))); RunLoop().RunUntilIdle(); EXPECT_FALSE(delegate.WasCalled()); }
diff --git a/base/win/windows_version.h b/base/win/windows_version.h index fef7c9e..efd88e3 100644 --- a/base/win/windows_version.h +++ b/base/win/windows_version.h
@@ -126,8 +126,6 @@ VersionType version_type() const { return version_type_; } ServicePack service_pack() const { return service_pack_; } std::string service_pack_str() const { return service_pack_str_; } - // TODO(thestig): Switch callers to GetArchitecture(). - WindowsArchitecture architecture() const { return GetArchitecture(); } int processors() const { return processors_; } size_t allocation_granularity() const { return allocation_granularity_; } WOW64Status wow64_status() const { return wow64_status_; }
diff --git a/build/android/BUILD.gn b/build/android/BUILD.gn index df8c865d..5e61187 100644 --- a/build/android/BUILD.gn +++ b/build/android/BUILD.gn
@@ -66,10 +66,17 @@ write_file(android_build_vars, _data) } +python_library("devil_chromium_py") { + pydeps_file = "devil_chromium.pydeps" + data = [ + "devil_chromium.py", + "devil_chromium.json", + ] +} + python_library("test_runner_py") { pydeps_file = "test_runner.pydeps" data = [ - "devil_chromium.json", "pylib/gtest/filter/", "pylib/instrumentation/render_test.html.jinja", "test_wrapper/logdog_wrapper.py", @@ -81,6 +88,9 @@ "//third_party/catapult/third_party/gsutil/", "//third_party/catapult/devil/devil/devil_dependencies.json", ] + data_deps = [ + ":devil_chromium_py", + ] # Proguard is needed only when using apks (rather than native executables). if (enable_java_templates) {
diff --git a/build/android/devil_chromium.pydeps b/build/android/devil_chromium.pydeps new file mode 100644 index 0000000..ea8f0c2 --- /dev/null +++ b/build/android/devil_chromium.pydeps
@@ -0,0 +1,38 @@ +# Generated by running: +# build/print_python_deps.py --root build/android --output build/android/devil_chromium.pydeps build/android/devil_chromium.py +../../third_party/catapult/common/py_utils/py_utils/__init__.py +../../third_party/catapult/common/py_utils/py_utils/cloud_storage.py +../../third_party/catapult/common/py_utils/py_utils/cloud_storage_global_lock.py +../../third_party/catapult/common/py_utils/py_utils/lock.py +../../third_party/catapult/dependency_manager/dependency_manager/__init__.py +../../third_party/catapult/dependency_manager/dependency_manager/archive_info.py +../../third_party/catapult/dependency_manager/dependency_manager/base_config.py +../../third_party/catapult/dependency_manager/dependency_manager/cloud_storage_info.py +../../third_party/catapult/dependency_manager/dependency_manager/dependency_info.py +../../third_party/catapult/dependency_manager/dependency_manager/dependency_manager_util.py +../../third_party/catapult/dependency_manager/dependency_manager/exceptions.py +../../third_party/catapult/dependency_manager/dependency_manager/local_path_info.py +../../third_party/catapult/dependency_manager/dependency_manager/manager.py +../../third_party/catapult/dependency_manager/dependency_manager/uploader.py +../../third_party/catapult/devil/devil/__init__.py +../../third_party/catapult/devil/devil/android/__init__.py +../../third_party/catapult/devil/devil/android/constants/__init__.py +../../third_party/catapult/devil/devil/android/constants/chrome.py +../../third_party/catapult/devil/devil/android/ndk/__init__.py +../../third_party/catapult/devil/devil/android/ndk/abis.py +../../third_party/catapult/devil/devil/android/sdk/__init__.py +../../third_party/catapult/devil/devil/android/sdk/keyevent.py +../../third_party/catapult/devil/devil/android/sdk/version_codes.py +../../third_party/catapult/devil/devil/base_error.py +../../third_party/catapult/devil/devil/constants/__init__.py +../../third_party/catapult/devil/devil/constants/exit_codes.py +../../third_party/catapult/devil/devil/devil_env.py +../../third_party/catapult/devil/devil/utils/__init__.py +../../third_party/catapult/devil/devil/utils/reraiser_thread.py +../../third_party/catapult/devil/devil/utils/timeout_retry.py +../../third_party/catapult/devil/devil/utils/watchdog_timer.py +../../third_party/catapult/third_party/zipfile/zipfile_2_7_13.py +devil_chromium.py +pylib/__init__.py +pylib/constants/__init__.py +pylib/constants/host_paths.py
diff --git a/build/android/resource_sizes.py b/build/android/resource_sizes.py index 30064c1..115ccb5e 100755 --- a/build/android/resource_sizes.py +++ b/build/android/resource_sizes.py
@@ -108,9 +108,6 @@ # enable_resource_whitelist_generation=true. _RC_HEADER_RE = re.compile(r'^#define (?P<name>\w+).* (?P<id>\d+)\)?$') _RE_NON_LANGUAGE_PAK = re.compile(r'^assets/.*(resources|percent)\.pak$') -_RE_COMPRESSED_LANGUAGE_PAK = re.compile( - r'\.lpak$|^assets/(?!stored-locales/).*(?!resources|percent)\.pak$') -_RE_STORED_LANGUAGE_PAK = re.compile(r'^assets/stored-locales/.*\.pak$') _READELF_SIZES_METRICS = { 'text': ['.text'], 'data': ['.data', '.rodata', '.data.rel.ro', '.data.rel.ro.local'], @@ -365,12 +362,13 @@ java_code.AddZipInfo(member, extracted_multiplier=dex_multiplier) elif re.search(_RE_NON_LANGUAGE_PAK, filename): native_resources_no_translations.AddZipInfo(member) - elif re.search(_RE_COMPRESSED_LANGUAGE_PAK, filename): - translations.AddZipInfo( - member, - extracted_multiplier=int('en_' in filename or 'en-' in filename)) - elif re.search(_RE_STORED_LANGUAGE_PAK, filename): - stored_translations.AddZipInfo(member) + elif filename.endswith('.pak') or filename.endswith('.lpak'): + compressed = member.compress_type != zipfile.ZIP_STORED + bucket = translations if compressed else stored_translations + extracted_multiplier = 0 + if compressed: + extracted_multiplier = int('en_' in filename or 'en-' in filename) + bucket.AddZipInfo(member, extracted_multiplier=extracted_multiplier) elif filename == 'assets/icudtl.dat': icu_data.AddZipInfo(member) elif filename.endswith('.bin'):
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 11fe9bd0..98f909c 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -3643,12 +3643,6 @@ # Otherwise, dex_path is undefined and we retrieve the module's dex file # using its build_config. # -# native_lib_placeholders: List of placeholder filenames to add to each -# APK split (optional). TODO(huangs): Remove. -# -# secondary_native_lib_placeholders: List of placeholder filenames to add -# to each APK split's secondary ABI (optional). TODO(huangs): Remove. -# template("create_android_app_bundle_module") { _build_config = invoker.build_config _rebased_build_config = rebase_path(_build_config, root_build_dir) @@ -3689,6 +3683,8 @@ "$_rebased_build_config:uncompressed_assets)", "--native-libs=@FileArg($_rebased_build_config:native:libraries)", "--native-libs=@FileArg($_rebased_build_config:native:extra_shared_libraries)", + "--native-lib-placeholders=@FileArg($_rebased_build_config:native:native_library_placeholders)", + "--secondary-native-lib-placeholders=@FileArg($_rebased_build_config:native:secondary_native_library_placeholders)", "--android-abi=$android_app_abi", "--uncompress-shared-libraries=@FileArg(" + "$_rebased_build_config:native:uncompress_shared_libraries)", @@ -3700,18 +3696,6 @@ "--secondary-android-abi=$android_app_secondary_abi", ] } - if (defined(invoker.native_lib_placeholders) && - invoker.native_lib_placeholders != []) { - args += [ "--native-lib-placeholders=${invoker.native_lib_placeholders}" ] - } else { - args += [ "--native-lib-placeholders=@FileArg($_rebased_build_config:native:native_library_placeholders)" ] - } - if (defined(invoker.secondary_native_lib_placeholders) && - invoker.secondary_native_lib_placeholders != []) { - args += [ "--secondary-native-lib-placeholders=${invoker.secondary_native_lib_placeholders}" ] - } else { - args += [ "--secondary-native-lib-placeholders=@FileArg($_rebased_build_config:native:secondary_native_library_placeholders)" ] - } # Use either provided dex path or build config path based on type of module. if (defined(invoker.dex_path)) {
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 24a3cbe8..8ebf456 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -3955,9 +3955,6 @@ # such that they are extracted upon install. Libraries prefixed with # "crazy." are never compressed. # - # add_native_lib_placeholders_for_base_module: Optional. Whether to add - # native library placeholders to the base module. TODO(huangs): Remove. - # # Example: # android_app_bundle("chrome_public_bundle") { # base_module_target = "//chrome/android:chrome_public_apk" @@ -4152,20 +4149,6 @@ _module_zip_path = "$target_gen_dir/$target_name/${_module.name}.zip" create_android_app_bundle_module(_create_module_target) { - # TODO(huangs): Remove, after removing downstream usage. - if (defined(invoker.add_native_lib_placeholders_for_base_module) && - invoker.add_native_lib_placeholders_for_base_module) { - if (_module.name == "base") { - # Include placeholder libraries to support multiarch. This allows - # the "32-bit" and "64-bit" versions of the module to depend on - # their respective versions of the shared library APK even though - # they're functionally the same. - native_lib_placeholders = [ "libdummy.so" ] - if (android_64bit_target_cpu && build_apk_secondary_abi) { - secondary_native_lib_placeholders = [ "libdummy.so" ] - } - } - } build_config = _module_build_config module_zip_path = _module_zip_path
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 1ef3795..0afd629 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -ddcb12bc41acc7d54223765e22f78a305954bcbc \ No newline at end of file +1fdc2abd281892f5d2c914bb83b6bae6108619c6 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 077fa9d8..1249cc9 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -bf01df1020cecebcf7bcc39fdd72c783bb14a923 \ No newline at end of file +d5208460c502e92a7c0c718f986b482617ec1c90 \ No newline at end of file
diff --git a/build/fuchsia/run_package.py b/build/fuchsia/run_package.py index 0d12e65..c828a60 100644 --- a/build/fuchsia/run_package.py +++ b/build/fuchsia/run_package.py
@@ -267,8 +267,6 @@ # Serve the |tuf_root| using 'pm serve' and configure the target to pull # from it. - # TODO(kmarshall): Use -q to suppress pm serve output once blob push - # is confirmed to be running stably on bots. serve_port = common.GetAvailableTcpPort() pm_serve_task = subprocess.Popen( [PM, 'serve', '-d', os.path.join(tuf_root, 'repository'), '-l',
diff --git a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc index cf7f706..6f2da14 100644 --- a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc +++ b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
@@ -71,8 +71,7 @@ settings.image_provider = &image_provider; raster_source->PlaybackToCanvas( - &canvas, gfx::ColorSpace(), - raster_source->GetContentSize(contents_scale), content_rect, + &canvas, raster_source->GetContentSize(contents_scale), content_rect, content_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), settings);
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc index 6d317814..366013e 100644 --- a/cc/layers/heads_up_display_layer_impl.cc +++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -375,7 +375,8 @@ { ScopedGpuRaster gpu_raster(context_provider); viz::ClientResourceProvider::ScopedSkSurface scoped_surface( - context_provider->GrContext(), mailbox_texture_id, + context_provider->GrContext(), + pool_resource.color_space().ToSkColorSpace(), mailbox_texture_id, backing->texture_target, pool_resource.size(), pool_resource.format(), false /* can_use_lcd_text */, 0 /* msaa_sample_count */);
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 2af18ee..1ecd3df 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -320,25 +320,20 @@ viewport_rect_for_tile_priority, transform_for_tile_priority); host_impl()->active_tree()->UpdateDrawProperties(); - gfx::Rect viewport_rect_for_tile_priority_in_view_space = - viewport_rect_for_tile_priority; - // Verify the viewport rect for tile priority is used in picture layer tiling. - EXPECT_EQ(viewport_rect_for_tile_priority_in_view_space, + EXPECT_EQ(viewport_rect_for_tile_priority, active_layer()->viewport_rect_for_tile_priority_in_content_space()); PictureLayerTilingSet* tilings = active_layer()->tilings(); for (size_t i = 0; i < tilings->num_tilings(); i++) { PictureLayerTiling* tiling = tilings->tiling_at(i); - EXPECT_EQ( - tiling->GetCurrentVisibleRectForTesting(), - gfx::ScaleToEnclosingRect(viewport_rect_for_tile_priority_in_view_space, - tiling->contents_scale_key())); + EXPECT_EQ(tiling->GetCurrentVisibleRectForTesting(), + gfx::ScaleToEnclosingRect(viewport_rect_for_tile_priority, + tiling->contents_scale_key())); } // Update tiles with viewport for tile priority as (200, 200, 100, 100) in - // screen space and the transform for tile priority is translated and - // rotated. The actual viewport for tile priority used by PictureLayerImpl - // should be (200, 200, 100, 100) applied with the said transform. + // root layer space and the transform for tile priority is translated and + // rotated. host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); viewport_rect_for_tile_priority = gfx::Rect(200, 200, 100, 100); @@ -348,27 +343,14 @@ viewport_rect_for_tile_priority, transform_for_tile_priority); host_impl()->active_tree()->UpdateDrawProperties(); - gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization); - bool success = transform_for_tile_priority.GetInverse(&screen_to_view); - EXPECT_TRUE(success); - - // Note that we don't clip this to the layer bounds, since it is expected that - // the rect will sometimes be outside of the layer bounds. If we clip to - // bounds, then tile priorities will end up being incorrect in cases of fully - // offscreen layer. - viewport_rect_for_tile_priority_in_view_space = - MathUtil::ProjectEnclosingClippedRect(screen_to_view, - viewport_rect_for_tile_priority); - - EXPECT_EQ(viewport_rect_for_tile_priority_in_view_space, + EXPECT_EQ(viewport_rect_for_tile_priority, active_layer()->viewport_rect_for_tile_priority_in_content_space()); tilings = active_layer()->tilings(); for (size_t i = 0; i < tilings->num_tilings(); i++) { PictureLayerTiling* tiling = tilings->tiling_at(i); - EXPECT_EQ( - tiling->GetCurrentVisibleRectForTesting(), - gfx::ScaleToEnclosingRect(viewport_rect_for_tile_priority_in_view_space, - tiling->contents_scale_key())); + EXPECT_EQ(tiling->GetCurrentVisibleRectForTesting(), + gfx::ScaleToEnclosingRect(viewport_rect_for_tile_priority, + tiling->contents_scale_key())); } }
diff --git a/cc/paint/oop_pixeltest.cc b/cc/paint/oop_pixeltest.cc index 2ac24c2..3e90ba7 100644 --- a/cc/paint/oop_pixeltest.cc +++ b/cc/paint/oop_pixeltest.cc
@@ -295,7 +295,8 @@ SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType); } SkImageInfo image_info = SkImageInfo::MakeN32Premul( - options.resource_size.width(), options.resource_size.height()); + options.resource_size.width(), options.resource_size.height(), + options.color_space.ToSkColorSpace()); auto surface = SkSurface::MakeRenderTarget( gles2_context_provider_->GrContext(), SkBudgeted::kYes, image_info); SkCanvas* canvas = surface->getCanvas(); @@ -307,9 +308,8 @@ gfx::AxisTransform2d raster_transform(options.post_scale, options.post_translate); raster_source->PlaybackToCanvas( - canvas, options.color_space, options.content_size, - options.full_raster_rect, options.playback_rect, raster_transform, - settings); + canvas, options.content_size, options.full_raster_rect, + options.playback_rect, raster_transform, settings); surface->prepareForExternalIO(); EXPECT_EQ(gles2_context_provider_->ContextGL()->GetError(), static_cast<unsigned>(GL_NO_ERROR));
diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc index 394e02e5..bef3681 100644 --- a/cc/raster/gpu_raster_buffer_provider.cc +++ b/cc/raster/gpu_raster_buffer_provider.cc
@@ -7,6 +7,7 @@ #include <stdint.h> #include <algorithm> +#include <utility> #include "base/metrics/histogram_macros.h" #include "base/rand_util.h" @@ -44,6 +45,7 @@ public: ScopedSkSurfaceForUnpremultiplyAndDither( viz::RasterContextProvider* context_provider, + sk_sp<SkColorSpace> color_space, const gfx::Rect& playback_rect, const gfx::Rect& raster_full_rect, const gfx::Size& max_tile_size, @@ -71,8 +73,9 @@ // Allocate a 32-bit surface for raster. We will copy from that into our // actual surface in destruction. - SkImageInfo n32Info = SkImageInfo::MakeN32Premul( - intermediate_size.width(), intermediate_size.height()); + SkImageInfo n32Info = SkImageInfo::MakeN32Premul(intermediate_size.width(), + intermediate_size.height(), + std::move(color_space)); SkSurfaceProps surface_props = viz::ClientResourceProvider::ScopedSkSurface::ComputeSurfaceProps( can_use_lcd_text); @@ -206,16 +209,18 @@ base::Optional<ScopedSkSurfaceForUnpremultiplyAndDither> scoped_dither_surface; SkSurface* surface; + sk_sp<SkColorSpace> sk_color_space = color_space.ToSkColorSpace(); if (!unpremultiply_and_dither) { - scoped_surface.emplace(context_provider->GrContext(), texture_id, - texture_target, resource_size, resource_format, - playback_settings.use_lcd_text, msaa_sample_count); + scoped_surface.emplace(context_provider->GrContext(), sk_color_space, + texture_id, texture_target, resource_size, + resource_format, playback_settings.use_lcd_text, + msaa_sample_count); surface = scoped_surface->surface(); } else { scoped_dither_surface.emplace( - context_provider, playback_rect, raster_full_rect, max_tile_size, - texture_id, resource_size, playback_settings.use_lcd_text, - msaa_sample_count); + context_provider, sk_color_space, playback_rect, raster_full_rect, + max_tile_size, texture_id, resource_size, + playback_settings.use_lcd_text, msaa_sample_count); surface = scoped_dither_surface->surface(); } @@ -233,8 +238,8 @@ canvas->discard(); gfx::Size content_size = raster_source->GetContentSize(transform.scale()); - raster_source->PlaybackToCanvas(canvas, color_space, content_size, - raster_full_rect, playback_rect, transform, + raster_source->PlaybackToCanvas(canvas, content_size, raster_full_rect, + playback_rect, transform, playback_settings); }
diff --git a/cc/raster/raster_buffer_provider.cc b/cc/raster/raster_buffer_provider.cc index 0e7d1c71..f5935e2 100644 --- a/cc/raster/raster_buffer_provider.cc +++ b/cc/raster/raster_buffer_provider.cc
@@ -74,7 +74,8 @@ // Uses kPremul_SkAlphaType since the result is not known to be opaque. SkImageInfo info = - SkImageInfo::MakeN32(size.width(), size.height(), kPremul_SkAlphaType); + SkImageInfo::MakeN32(size.width(), size.height(), kPremul_SkAlphaType, + target_color_space.ToSkColorSpace()); // Use unknown pixel geometry to disable LCD text. SkSurfaceProps surface_props(0, kUnknown_SkPixelGeometry); @@ -100,19 +101,18 @@ // invalid content, just crash the renderer and try again. // See: http://crbug.com/721744. CHECK(surface); - raster_source->PlaybackToCanvas(surface->getCanvas(), target_color_space, - content_size, canvas_bitmap_rect, - canvas_playback_rect, transform, - playback_settings); + raster_source->PlaybackToCanvas(surface->getCanvas(), content_size, + canvas_bitmap_rect, canvas_playback_rect, + transform, playback_settings); return; } case viz::RGBA_4444: { sk_sp<SkSurface> surface = SkSurface::MakeRaster(info, &surface_props); // TODO(reveman): Improve partial raster support by reducing the size of // playback rect passed to PlaybackToCanvas. crbug.com/519070 - raster_source->PlaybackToCanvas( - surface->getCanvas(), target_color_space, content_size, - canvas_bitmap_rect, canvas_bitmap_rect, transform, playback_settings); + raster_source->PlaybackToCanvas(surface->getCanvas(), content_size, + canvas_bitmap_rect, canvas_bitmap_rect, + transform, playback_settings); TRACE_EVENT0("cc", "RasterBufferProvider::PlaybackToMemory::ConvertRGBA4444");
diff --git a/cc/raster/raster_source.cc b/cc/raster/raster_source.cc index 8f510fa..8c490e48 100644 --- a/cc/raster/raster_source.cc +++ b/cc/raster/raster_source.cc
@@ -16,7 +16,6 @@ #include "cc/paint/skia_paint_canvas.h" #include "components/viz/common/traced_value.h" #include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkColorSpaceXformCanvas.h" #include "third_party/skia/include/core/SkPictureRecorder.h" #include "ui/gfx/geometry/axis_transform2d.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -111,8 +110,7 @@ } void RasterSource::PlaybackToCanvas( - SkCanvas* input_canvas, - const gfx::ColorSpace& target_color_space, + SkCanvas* raster_canvas, const gfx::Size& content_size, const gfx::Rect& canvas_bitmap_rect, const gfx::Rect& canvas_playback_rect, @@ -125,15 +123,6 @@ // Treat all subnormal values as zero for performance. ScopedSubnormalFloatDisabler disabler; - // TODO(enne): color transform needs to be replicated in gles2_cmd_decoder - SkCanvas* raster_canvas = input_canvas; - std::unique_ptr<SkCanvas> color_transform_canvas; - if (target_color_space.IsValid()) { - color_transform_canvas = SkCreateColorSpaceXformCanvas( - input_canvas, target_color_space.ToSkColorSpace()); - raster_canvas = color_transform_canvas.get(); - } - bool is_partial_raster = canvas_bitmap_rect != canvas_playback_rect; if (!requires_clear_) { // Clear opaque raster sources. Opaque rasters sources guarantee that all
diff --git a/cc/raster/raster_source.h b/cc/raster/raster_source.h index c62ce0e..43ec5f3 100644 --- a/cc/raster/raster_source.h +++ b/cc/raster/raster_source.h
@@ -53,7 +53,6 @@ // canvas_playback_rect can be used to replay only part of the recording in, // the content space, so only a sub-rect of the tile gets rastered. void PlaybackToCanvas(SkCanvas* canvas, - const gfx::ColorSpace& target_color_space, const gfx::Size& content_size, const gfx::Rect& canvas_bitmap_rect, const gfx::Rect& canvas_playback_rect,
diff --git a/cc/raster/raster_source_unittest.cc b/cc/raster/raster_source_unittest.cc index c694083..21338cf 100644 --- a/cc/raster/raster_source_unittest.cc +++ b/cc/raster/raster_source_unittest.cc
@@ -30,10 +30,6 @@ namespace cc { namespace { -gfx::ColorSpace ColorSpaceForTesting() { - return gfx::ColorSpace(); -} - TEST(RasterSourceTest, AnalyzeIsSolidUnscaled) { gfx::Size layer_bounds(400, 400); @@ -346,8 +342,8 @@ canvas.clear(SK_ColorTRANSPARENT); raster->PlaybackToCanvas( - &canvas, ColorSpaceForTesting(), content_bounds, canvas_rect, - canvas_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), + &canvas, content_bounds, canvas_rect, canvas_rect, + gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), RasterSource::PlaybackSettings()); SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); @@ -398,8 +394,8 @@ gfx::Rect raster_full_rect(content_bounds); gfx::Rect playback_rect(content_bounds); raster->PlaybackToCanvas( - &canvas, ColorSpaceForTesting(), content_bounds, raster_full_rect, - playback_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), + &canvas, content_bounds, raster_full_rect, playback_rect, + gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), RasterSource::PlaybackSettings()); { @@ -430,8 +426,8 @@ // that touches the edge pixels of the recording. playback_rect.Inset(1, 2, 0, 1); raster->PlaybackToCanvas( - &canvas, ColorSpaceForTesting(), content_bounds, raster_full_rect, - playback_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), + &canvas, content_bounds, raster_full_rect, playback_rect, + gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), RasterSource::PlaybackSettings()); SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); @@ -495,8 +491,8 @@ gfx::Rect raster_full_rect(content_bounds); gfx::Rect playback_rect(content_bounds); raster->PlaybackToCanvas( - &canvas, ColorSpaceForTesting(), content_bounds, raster_full_rect, - playback_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), + &canvas, content_bounds, raster_full_rect, playback_rect, + gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), RasterSource::PlaybackSettings()); { @@ -535,8 +531,8 @@ playback_rect = gfx::Rect(gfx::ScaleToCeiledSize(partial_bounds, contents_scale)); raster->PlaybackToCanvas( - &canvas, ColorSpaceForTesting(), content_bounds, raster_full_rect, - playback_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), + &canvas, content_bounds, raster_full_rect, playback_rect, + gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), RasterSource::PlaybackSettings()); // Test that the whole playback_rect was cleared and repainted with new alpha. @@ -576,7 +572,7 @@ SkCanvas canvas(bitmap); raster->PlaybackToCanvas( - &canvas, ColorSpaceForTesting(), content_bounds, canvas_rect, canvas_rect, + &canvas, content_bounds, canvas_rect, canvas_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), RasterSource::PlaybackSettings()); @@ -623,9 +619,8 @@ EXPECT_CALL(mock_canvas, willRestore()).InSequence(s); gfx::Size small_size(50, 50); - raster_source->PlaybackToCanvas(&mock_canvas, ColorSpaceForTesting(), size, - gfx::Rect(small_size), gfx::Rect(small_size), - gfx::AxisTransform2d(), + raster_source->PlaybackToCanvas(&mock_canvas, size, gfx::Rect(small_size), + gfx::Rect(small_size), gfx::AxisTransform2d(), RasterSource::PlaybackSettings()); }
diff --git a/cc/trees/effect_node.cc b/cc/trees/effect_node.cc index 389be1ab..3701e4c 100644 --- a/cc/trees/effect_node.cc +++ b/cc/trees/effect_node.cc
@@ -101,6 +101,8 @@ has_potential_filter_animation); value->SetBoolean("has_potential_opacity_animation", has_potential_opacity_animation); + value->SetBoolean("has_masking_child", has_masking_child); + value->SetBoolean("is_masked", is_masked); value->SetBoolean("effect_changed", effect_changed); value->SetInteger("subtree_has_copy_request", subtree_has_copy_request); value->SetInteger("transform_id", transform_id);
diff --git a/cc/trees/effect_node.h b/cc/trees/effect_node.h index fe7920c9..7302bcee 100644 --- a/cc/trees/effect_node.h +++ b/cc/trees/effect_node.h
@@ -77,9 +77,11 @@ bool is_currently_animating_opacity : 1; // Whether this node has a child node with kDstIn blend mode. bool has_masking_child : 1; - // Whether this node has an ancestor with a mask layer or the node itself has - // a mask. + // Whether this node has a mask. This bit is not used when using layer lists. bool is_masked : 1; + // Whether layers associated with this node have a mask or ancestor mask that + // could affect the layer's hit testable bit. + bool hit_test_may_be_affected_by_mask : 1; // Whether this node's effect has been changed since the last // frame. Needed in order to compute damage rect. bool effect_changed : 1;
diff --git a/cc/trees/layer_tree_frame_sink_client.h b/cc/trees/layer_tree_frame_sink_client.h index 8037825..fc298c8 100644 --- a/cc/trees/layer_tree_frame_sink_client.h +++ b/cc/trees/layer_tree_frame_sink_client.h
@@ -85,6 +85,8 @@ // For SynchronousCompositor (WebView) to change which tiles should be // included in submitted CompositorFrames independently of what the viewport // is. + // |viewport_rect| is in device viewport space. + // |transform| transforms from from device viewport space to screen space. virtual void SetExternalTilePriorityConstraints( const gfx::Rect& viewport_rect, const gfx::Transform& transform) = 0;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index e3c7641d..e94360c 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -1732,20 +1732,9 @@ void LayerTreeHostImpl::SetExternalTilePriorityConstraints( const gfx::Rect& viewport_rect, const gfx::Transform& transform) { - gfx::Rect viewport_rect_for_tile_priority_in_view_space; - gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization); - if (transform.GetInverse(&screen_to_view)) { - // Convert from screen space to view space. - viewport_rect_for_tile_priority_in_view_space = - MathUtil::ProjectEnclosingClippedRect(screen_to_view, viewport_rect); - } - const bool tile_priority_params_changed = - viewport_rect_for_tile_priority_ != - viewport_rect_for_tile_priority_in_view_space; - - viewport_rect_for_tile_priority_ = - viewport_rect_for_tile_priority_in_view_space; + viewport_rect_for_tile_priority_ != viewport_rect; + viewport_rect_for_tile_priority_ = viewport_rect; if (tile_priority_params_changed) { active_tree_->set_needs_update_draw_properties(); @@ -2661,8 +2650,8 @@ bool layer_hit_test_region_is_masked = active_tree() ->property_trees() - ->effect_tree.Node(surface_layer->effect_tree_index()) - ->is_masked; + ->effect_tree.HitTestMayBeAffectedByMask( + surface_layer->effect_tree_index()); if (surface_layer->is_clipped() || layer_hit_test_region_is_masked) { bool layer_hit_test_region_is_rectangle = !layer_hit_test_region_is_masked &&
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index d0d2a54..0d7e71d 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -14132,6 +14132,8 @@ ->AddChild(std::move(overlapping_layer)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); + draw_property_utils::ComputeEffects( + &host_impl_->active_tree()->property_trees()->effect_tree); constexpr gfx::Rect kFrameRect(0, 0, 1024, 768);
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc index 456f2a6..da485a0 100644 --- a/cc/trees/property_tree.cc +++ b/cc/trees/property_tree.cc
@@ -835,9 +835,14 @@ parent_node->has_masking_child = true; } -void EffectTree::UpdateIsMasked(EffectNode* node, EffectNode* parent_node) { - node->is_masked = (parent_node && parent_node->is_masked) || - node->mask_layer_id != Layer::INVALID_ID; +void EffectTree::UpdateHitTestMayBeAffectedByMask(EffectNode* node, + EffectNode* parent_node) { + node->hit_test_may_be_affected_by_mask = + node->is_masked || node->has_masking_child; + if (parent_node) { + node->hit_test_may_be_affected_by_mask |= + parent_node->hit_test_may_be_affected_by_mask; + } } void EffectTree::UpdateSurfaceContentsScale(EffectNode* effect_node) { @@ -916,7 +921,7 @@ UpdateEffectChanged(node, parent_node); UpdateBackfaceVisibility(node, parent_node); UpdateHasMaskingChild(node, parent_node); - UpdateIsMasked(node, parent_node); + UpdateHitTestMayBeAffectedByMask(node, parent_node); UpdateSurfaceContentsScale(node); } @@ -1195,6 +1200,13 @@ return true; } +bool EffectTree::HitTestMayBeAffectedByMask(int effect_id) const { + const EffectNode* effect_node = Node(effect_id); + if (effect_node) + return effect_node->hit_test_may_be_affected_by_mask; + return false; +} + void TransformTree::UpdateNodeAndAncestorsHaveIntegerTranslations( TransformNode* node, TransformNode* parent_node) {
diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h index 779a94a..42635e1 100644 --- a/cc/trees/property_tree.h +++ b/cc/trees/property_tree.h
@@ -372,13 +372,18 @@ // 2) There are no mask layers. bool ClippedHitTestRegionIsRectangle(int effect_node_id) const; + // This function checks if the associated layer can use its layer bounds to + // correctly hit test. It returns true if the layer bounds cannot be trusted. + bool HitTestMayBeAffectedByMask(int effect_node_id) const; + private: void UpdateOpacities(EffectNode* node, EffectNode* parent_node); void UpdateSubtreeHidden(EffectNode* node, EffectNode* parent_node); void UpdateIsDrawn(EffectNode* node, EffectNode* parent_node); void UpdateBackfaceVisibility(EffectNode* node, EffectNode* parent_node); void UpdateHasMaskingChild(EffectNode* node, EffectNode* parent_node); - void UpdateIsMasked(EffectNode* node, EffectNode* parent_node); + void UpdateHitTestMayBeAffectedByMask(EffectNode* node, + EffectNode* parent_node); // Stores copy requests, keyed by node id. std::unordered_multimap<int, std::unique_ptr<viz::CopyOutputRequest>>
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index b49e76d..58ff863 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc
@@ -1083,6 +1083,7 @@ if (MaskLayer(layer)) { node->mask_layer_id = MaskLayer(layer)->id(); effect_tree_.AddMaskLayerId(node->mask_layer_id); + node->is_masked = true; } if (HasRoundedCorner(layer)) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index d738ea3..0e9a823 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -164,6 +164,8 @@ public void didAddTab(Tab tab, int type) { int index = TabModelUtils.getTabIndexById( mTabModelSelector.getCurrentModel(), tab.getId()); + if (index == TabModel.INVALID_TAB_INDEX) return; + addTabInfoToModel(tab, index, mTabModelSelector.getCurrentModel().index() == index); }
diff --git a/chrome/android/java/res/values-v27/styles.xml b/chrome/android/java/res/values-v27/styles.xml index 5b25e89..8cf73455 100644 --- a/chrome/android/java/res/values-v27/styles.xml +++ b/chrome/android/java/res/values-v27/styles.xml
@@ -9,27 +9,27 @@ <!--suppress NewApi: crbug.com/856861--> <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> <!--suppress NewApi: crbug.com/856861--> - <item name="android:windowLightNavigationBar">true</item> + <item name="android:windowLightNavigationBar">@bool/window_light_navigation_bar</item> </style> <style name="Theme.Chromium.Fullscreen" parent="Base.Theme.Chromium.Fullscreen"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> <!--suppress NewApi: crbug.com/856861--> <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> <!--suppress NewApi: crbug.com/856861--> - <item name="android:windowLightNavigationBar">true</item> + <item name="android:windowLightNavigationBar">@bool/window_light_navigation_bar</item> </style> <style name="Theme.Chromium.WithActionBar" parent="Base.Theme.Chromium.WithActionBar"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> <!--suppress NewApi: crbug.com/856861--> <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> <!--suppress NewApi: crbug.com/856861--> - <item name="android:windowLightNavigationBar">true</item> + <item name="android:windowLightNavigationBar">@bool/window_light_navigation_bar</item> </style> <style name="Theme.Chromium.DialogWhenLarge" parent="Base.Theme.Chromium.DialogWhenLarge"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> <!--suppress NewApi: crbug.com/856861--> <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> <!--suppress NewApi: crbug.com/856861--> - <item name="android:windowLightNavigationBar">true</item> + <item name="android:windowLightNavigationBar">@bool/window_light_navigation_bar</item> </style> </resources>
diff --git a/chrome/android/java/res/values/values.xml b/chrome/android/java/res/values/values.xml index e695da1..1082eeb8 100644 --- a/chrome/android/java/res/values/values.xml +++ b/chrome/android/java/res/values/values.xml
@@ -80,4 +80,7 @@ <integer name="download_infobar_bar_start_offset">800</integer> <integer name="download_infobar_bar_fill_in_delay">400</integer> <integer name="download_infobar_bar_fill_out_delay">200</integer> + + <!-- Bottom navigation bar styling. --> + <bool name="window_light_navigation_bar">true</bool> </resources>
diff --git a/chrome/android/java/res_night/values-night/colors.xml b/chrome/android/java/res_night/values-night/colors.xml index 5ea902e..af70351 100644 --- a/chrome/android/java/res_night/values-night/colors.xml +++ b/chrome/android/java/res_night/values-night/colors.xml
@@ -11,4 +11,7 @@ <color name="toolbar_background_primary">@color/modern_grey_900_with_white_alpha_8</color> <color name="toolbar_text_box_background">@color/modern_grey_800</color> -</resources> \ No newline at end of file + + <color name="bottom_system_nav_color">@android:color/black</color> + <color name="bottom_system_nav_divider_color">@android:color/black</color> +</resources>
diff --git a/chrome/android/java/res_night/values-night/values.xml b/chrome/android/java/res_night/values-night/values.xml new file mode 100644 index 0000000..17a9f59 --- /dev/null +++ b/chrome/android/java/res_night/values-night/values.xml
@@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-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. --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- Bottom navigation bar styling. --> + <bool name="window_light_navigation_bar">false</bool> +</resources> +
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index a1204c2..fd2bf2a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -61,7 +61,6 @@ import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.NavigationEntry; import org.chromium.content_public.common.BrowserControlsState; -import org.chromium.net.NetworkChangeNotifier; import org.chromium.ui.mojom.WindowOpenDisposition; import java.net.URI; @@ -356,8 +355,7 @@ DownloadManagerService.getDownloadManagerService().checkForExternallyRemovedDownloads( /*isOffTheRecord=*/false); - RecordHistogram.recordBooleanHistogram( - "NewTabPage.MobileIsUserOnline", NetworkChangeNotifier.isOnline()); + NewTabPageUma.recordIsUserOnline(); NewTabPageUma.recordLoadType(activity); NewTabPageUma.recordContentSuggestionsDisplayStatus(); TraceEvent.end(TAG); @@ -375,7 +373,8 @@ mNewTabPageView.initialize(mNewTabPageManager, mTab, mTileGroupDelegate, mSearchProviderHasLogo, TemplateUrlService.getInstance().isDefaultSearchEngineGoogle(), - getScrollPositionFromNavigationEntry(), mConstructedTimeNs); + getScrollPositionFromNavigationEntry(NAVIGATION_ENTRY_SCROLL_POSITION_KEY, mTab), + mConstructedTimeNs); } /** @@ -385,9 +384,26 @@ int scrollPosition = mNewTabPageView.getScrollPosition(); if (scrollPosition == RecyclerView.NO_POSITION) return; - if (mTab.getWebContents() == null) return; + saveScrollPositionToNavigationEntry( + NAVIGATION_ENTRY_SCROLL_POSITION_KEY, mTab, scrollPosition); + } - NavigationController controller = mTab.getWebContents().getNavigationController(); + /** + * Saves the scroll position (just a number) to the navigation entry. + * It is up to the caller to interpret the value when it's extracted later. + * @param scrollPositionKey The key under which the scroll position will be stored in the + * NavigationEntryExtraData + * + * @param tab A Tab that is used to access the NavigationController + * @param scrollPosition The scroll position (an opaque integer) to save. + * + * TODO(https://crbug.com/941581): Refactor this to be reusable across NativePage components. + **/ + public static void saveScrollPositionToNavigationEntry( + String scrollPositionKey, Tab tab, int scrollPosition) { + if (tab.getWebContents() == null) return; + + NavigationController controller = tab.getWebContents().getNavigationController(); int index = controller.getLastCommittedEntryIndex(); NavigationEntry entry = controller.getEntryAtIndex(index); if (entry == null) return; @@ -398,8 +414,7 @@ // committed entry is for the NTP. The extra data must only be set in the latter case. if (!isNTPUrl(entry.getUrl())) return; - controller.setEntryExtraData( - index, NAVIGATION_ENTRY_SCROLL_POSITION_KEY, Integer.toString(scrollPosition)); + controller.setEntryExtraData(index, scrollPositionKey, Integer.toString(scrollPosition)); } /** @@ -585,15 +600,18 @@ * Returns the value of the adapter scroll position that was stored in the last committed * navigation entry. Returns {@code RecyclerView.NO_POSITION} if there is no last committed * navigation entry, or if no data is found. + * @param scrollPositionKey The key under which the scroll position has been stored in the + * NavigationEntryExtraData. + * @param tab A tab that is used to access the NavigationController and the NavigationEntry + * extras. * @return The adapter scroll position. */ - private int getScrollPositionFromNavigationEntry() { - if (mTab.getWebContents() == null) return RecyclerView.NO_POSITION; + public static int getScrollPositionFromNavigationEntry(String scrollPositionKey, Tab tab) { + if (tab.getWebContents() == null) return RecyclerView.NO_POSITION; - NavigationController controller = mTab.getWebContents().getNavigationController(); + NavigationController controller = tab.getWebContents().getNavigationController(); int index = controller.getLastCommittedEntryIndex(); - String scrollPositionData = - controller.getEntryExtraData(index, NAVIGATION_ENTRY_SCROLL_POSITION_KEY); + String scrollPositionData = controller.getEntryExtraData(index, scrollPositionKey); if (TextUtils.isEmpty(scrollPositionData)) return RecyclerView.NO_POSITION; try {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java index 597c667..cd963ab 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java
@@ -21,6 +21,7 @@ import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.util.UrlUtilities; +import org.chromium.net.NetworkChangeNotifier; import org.chromium.ui.base.PageTransition; import java.lang.annotation.Retention; @@ -225,7 +226,8 @@ } /** - * Record a NTP impression (even potential ones to make informed product decisions). + * Record a NTP impression (even potential ones to make informed product decisions). If the + * impression type is {@link NewTabPageUma#NTP_IMPRESSION_REGULAR}, also records a user action. * @param impressionType Type of the impression from NewTabPageUma.java */ public static void recordNTPImpression(int impressionType) { @@ -265,6 +267,23 @@ } /** + * Records the network status of the user. + */ + public static void recordIsUserOnline() { + RecordHistogram.recordBooleanHistogram( + "NewTabPage.MobileIsUserOnline", NetworkChangeNotifier.isOnline()); + } + + /** + * Records the time duration that the NTP was visible. + * @param lastShownTimeNs A long as returned by System#nanoTime() - this should have been + * called at the moment the new tab page is shown. + */ + public static void recordTimeSpentOnNtp(long lastShownTimeNs) { + RecordHistogram.recordMediumTimesHistogram("NewTabPage.TimeSpent", + (System.nanoTime() - lastShownTimeNs) / TimeUtils.NANOSECONDS_PER_MILLISECOND); + } + /** * Records how much time elapsed from start until the search box became available to the user. */ public static void recordSearchAvailableLoadTime(ChromeActivity activity) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java index cf30200..ce25254 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java
@@ -55,18 +55,6 @@ return mFakeboxDelegate == null || !mFakeboxDelegate.isUrlBarFocused(); } - /** - * Returns the approximate adapter position that the user has scrolled to. The purpose of this - * value is that it can be stored and later retrieved to restore a scroll position that is - * familiar to the user, showing (part of) the same content the user was previously looking at. - * This position is valid for that purpose regardless of device orientation changes. Note that - * if the underlying data has changed in the meantime, different content would be shown for this - * position. - */ - public int getScrollPosition() { - return getLinearLayoutManager().findFirstVisibleItemPosition(); - } - @Override public boolean gatherTransparentRegion(Region region) { ViewUtils.gatherTransparentRegionsForOpaqueView(this, region);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsRecyclerView.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsRecyclerView.java index 7c370d0..3fd0bad 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsRecyclerView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsRecyclerView.java
@@ -133,6 +133,18 @@ } /** + * Returns the approximate adapter position that the user has scrolled to. The purpose of this + * value is that it can be stored and later retrieved to restore a scroll position that is + * familiar to the user, showing (part of) the same content the user was previously looking at. + * This position is valid for that purpose regardless of device orientation changes. Note that + * if the underlying data has changed in the meantime, different content would be shown for this + * position. + */ + public int getScrollPosition() { + return getLinearLayoutManager().findFirstVisibleItemPosition(); + } + + /** * @return Whether the {@link SuggestionsRecyclerView} and its children should react to touch * events. */
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index a63babf..764103f 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -1828,9 +1828,16 @@ if (notouch_build) { chrome_java_sources += [ + "touchless/java/src/org/chromium/chrome/browser/touchless/ContentSuggestionsViewBinder.java", "touchless/java/src/org/chromium/chrome/browser/touchless/NoTouchActivity.java", + "touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsAdapter.java", + "touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsController.java", + "touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsViewHolderFactory.java", "touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java", "touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java", + "touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageMediator.java", + "touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageProperties.java", + "touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageTopLayout.java", "touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessTabObserver.java", ] } else {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ServicificationBackgroundService.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ServicificationBackgroundService.java index f8f37cf..90006f1f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ServicificationBackgroundService.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ServicificationBackgroundService.java
@@ -6,17 +6,17 @@ import android.content.Context; +import com.google.android.gms.gcm.TaskParams; + import org.junit.Assert; import org.chromium.base.ThreadUtils; import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.ProcessInitException; -import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.init.BrowserParts; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.init.EmptyBrowserParts; import org.chromium.content_public.browser.BrowserStartupController; -import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; @@ -24,22 +24,34 @@ * Class for launching the service manager only mode for tests. */ public class ServicificationBackgroundService extends ChromeBackgroundService { - private boolean mDidLaunchBrowser; - private boolean mDidStartServiceManager; + private boolean mLaunchBrowserCalled; + private boolean mNativeLoaded; + private boolean mSupportsServiceManagerOnly; + + public ServicificationBackgroundService(boolean supportsServiceManagerOnly) { + mSupportsServiceManagerOnly = supportsServiceManagerOnly; + } + + @Override + public int onRunTask(final TaskParams params) { + mLaunchBrowserCalled = false; + return super.onRunTask(params); + } @Override protected void launchBrowser(Context context, String tag) { - mDidLaunchBrowser = true; + mLaunchBrowserCalled = true; + mNativeLoaded = false; final BrowserParts parts = new EmptyBrowserParts() { @Override public void finishNativeInitialization() { - mDidStartServiceManager = true; + mNativeLoaded = true; } @Override public boolean startServiceManagerOnly() { - return true; + return mSupportsServiceManagerOnly; } }; @@ -54,34 +66,54 @@ // Posts an assertion task to the UI thread. Since this is only called after the call // to onRunTask, it will be enqueued after any possible call to launchBrowser, and we // can reliably check whether launchBrowser was called. - protected void checkExpectations(final boolean expectedLaunchBrowser) { - ThreadUtils.runOnUiThread(() -> { - Assert.assertEquals("StartedService", expectedLaunchBrowser, mDidLaunchBrowser); - }); + protected void assertLaunchBrowserCalled() { + ThreadUtils.runOnUiThreadBlocking(() -> { Assert.assertTrue(mLaunchBrowserCalled); }); } - public void waitForServiceManagerStart() { + public void waitForNativeLoaded() { CriteriaHelper.pollUiThread( new Criteria("Failed while waiting for starting Service Manager.") { @Override public boolean isSatisfied() { - return mDidStartServiceManager; + return mNativeLoaded; } }); } - public void postTaskAndVerifyFullBrowserNotStarted() { + public void setSupportsServiceManagerOnly(boolean supportsServiceManagerOnly) { + mSupportsServiceManagerOnly = supportsServiceManagerOnly; + } + + public static void assertOnlyServiceManagerStarted() { // This task will always be queued and executed after // the BrowserStartupControllerImpl#browserStartupComplete() is called on the UI thread when // the full browser starts. So we can use it to checks whether the // {@link mFullBrowserStartupDone} has been set to true. - PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { + ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { + Assert.assertTrue("The native service manager has not been started.", + BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) + .isServiceManagerSuccessfullyStarted()); Assert.assertFalse("The full browser is started instead of ServiceManager only.", BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) .isStartupSuccessfullyCompleted()); } }); } + + public static void assertFullBrowserStarted() { + // This task will always be queued and executed after + // the BrowserStartupControllerImpl#browserStartupComplete() is called on the UI thread when + // the full browser starts. So we can use it to checks whether the + // {@link mFullBrowserStartupDone} has been set to true. + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + Assert.assertTrue("The full browser has not been started", + BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) + .isStartupSuccessfullyCompleted()); + } + }); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ServicificationBackgroundServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ServicificationBackgroundServiceTest.java index 0d2b2cc..df1d5ce1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ServicificationBackgroundServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ServicificationBackgroundServiceTest.java
@@ -31,28 +31,36 @@ @Before public void setUp() { + mServicificationBackgroundService = + new ServicificationBackgroundService(true /*supportsServiceManagerOnly*/); BackgroundSyncLauncher.setGCMEnabled(false); RecordHistogram.setDisabledForTests(true); - mServicificationBackgroundService = new ServicificationBackgroundService(); } @After - public void tearDown() throws Exception { + public void tearDown() { RecordHistogram.setDisabledForTests(false); } - private void startOnRunTaskAndVerify(String taskTag, boolean shouldStart) { - mServicificationBackgroundService.onRunTask(new TaskParams(taskTag)); - mServicificationBackgroundService.checkExpectations(shouldStart); - mServicificationBackgroundService.waitForServiceManagerStart(); - mServicificationBackgroundService.postTaskAndVerifyFullBrowserNotStarted(); + private static void startServiceAndWaitForNative( + ServicificationBackgroundService backgroundService) { + backgroundService.onRunTask(new TaskParams(ServiceManagerStartupUtils.TASK_TAG)); + backgroundService.assertLaunchBrowserCalled(); + backgroundService.waitForNativeLoaded(); } @Test @MediumTest @Feature({"ServicificationStartup"}) @CommandLineFlags.Add({"enable-features=NetworkService,AllowStartingServiceManagerOnly"}) - public void testSeriveManagerStarts() { - startOnRunTaskAndVerify(ServiceManagerStartupUtils.TASK_TAG, true); + public void testFullBrowserStartsAfterServiceManager() { + startServiceAndWaitForNative(mServicificationBackgroundService); + ServicificationBackgroundService.assertOnlyServiceManagerStarted(); + + // Now native is loaded in service manager only mode, lets try and load the full browser to + // test the transition from service manager only to full browser. + mServicificationBackgroundService.setSupportsServiceManagerOnly(false); + startServiceAndWaitForNative(mServicificationBackgroundService); + ServicificationBackgroundService.assertFullBrowserStarted(); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ServicificationDownloadTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ServicificationDownloadTest.java index 82554c6..d86c518 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ServicificationDownloadTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ServicificationDownloadTest.java
@@ -70,7 +70,8 @@ @Before public void setUp() throws InterruptedException { RecordHistogram.setDisabledForTests(true); - mServicificationBackgroundService = new ServicificationBackgroundService(); + mServicificationBackgroundService = + new ServicificationBackgroundService(true /*supportsServiceManagerOnly*/); ThreadUtils.runOnUiThreadBlocking( () -> { mNotificationService = new MockDownloadNotificationService(); }); } @@ -87,8 +88,8 @@ public void testResumeInterruptedDownload() { mServicificationBackgroundService.onRunTask( new TaskParams(ServiceManagerStartupUtils.TASK_TAG)); - mServicificationBackgroundService.waitForServiceManagerStart(); - mServicificationBackgroundService.postTaskAndVerifyFullBrowserNotStarted(); + mServicificationBackgroundService.waitForNativeLoaded(); + ServicificationBackgroundService.assertOnlyServiceManagerStarted(); String tempFile = InstrumentationRegistry.getInstrumentation() .getTargetContext()
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/init/OWNERS b/chrome/android/junit/src/org/chromium/chrome/browser/init/OWNERS new file mode 100644 index 0000000..ce0ca9f --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/init/OWNERS
@@ -0,0 +1 @@ +file://chrome/android/java/src/org/chromium/chrome/browser/init/OWNERS
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 08def2747..ad7eb14 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-74.0.3729.12_rc-r1-merged.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-74.0.3725.0_rc-r1-merged.afdo.bz2 \ No newline at end of file
diff --git a/chrome/android/touchless/OWNERS b/chrome/android/touchless/OWNERS index af2050f..8bf7b59 100644 --- a/chrome/android/touchless/OWNERS +++ b/chrome/android/touchless/OWNERS
@@ -1,4 +1,9 @@ +chili@chromium.org +dewittj@chromium.org mthiesse@chromium.org +pavely@chromium.org +skym@chromium.org +wylieb@chromium.org yfriedman@chromium.org # COMPONENT: Mobile>Touchless
diff --git a/chrome/android/touchless/java/res/layout/most_likely_touchless.xml b/chrome/android/touchless/java/res/layout/most_likely_touchless.xml new file mode 100644 index 0000000..1ad35fa --- /dev/null +++ b/chrome/android/touchless/java/res/layout/most_likely_touchless.xml
@@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-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. --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:gravity="center_horizontal"> + + <android.support.v7.widget.RecyclerView + android:id="@+id/most_likely_launcher_recycler" + android:background="@color/modern_primary_color" + android:scrollbars="none" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" /> + + <TextView + android:id="@+id/most_likely_web_title_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:textAppearance="@style/TextAppearance.BlackCaption" /> + +</LinearLayout> \ No newline at end of file
diff --git a/chrome/android/touchless/java/res/layout/new_tab_page_touchless.xml b/chrome/android/touchless/java/res/layout/new_tab_page_touchless.xml index 36607d8..080c70f 100644 --- a/chrome/android/touchless/java/res/layout/new_tab_page_touchless.xml +++ b/chrome/android/touchless/java/res/layout/new_tab_page_touchless.xml
@@ -3,9 +3,10 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<org.chromium.chrome.browser.touchless.TouchlessNewTabPageTopLayout + xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center"> @@ -16,9 +17,7 @@ <ViewStub android:id="@+id/most_likely_stub" android:layout_width="match_parent" - android:layout_height="wrap_content" /> + android:layout_height="wrap_content" + android:layout="@layout/most_likely_touchless" /> - <ViewStub android:id="@+id/feed_stub" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> -</LinearLayout> +</org.chromium.chrome.browser.touchless.TouchlessNewTabPageTopLayout>
diff --git a/chrome/android/touchless/java/res/layout/new_tab_page_touchless_view.xml b/chrome/android/touchless/java/res/layout/new_tab_page_touchless_view.xml new file mode 100644 index 0000000..936f7c7 --- /dev/null +++ b/chrome/android/touchless/java/res/layout/new_tab_page_touchless_view.xml
@@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-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. --> + +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView + android:id="@+id/suggestions_recycler_view" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:scrollbars="vertical" + android:scrollbarStyle="outsideOverlay" + android:paddingStart="@dimen/touchless_new_tab_view_padding_horizontal" + android:paddingEnd="@dimen/touchless_new_tab_view_padding_horizontal" /> +</FrameLayout> \ No newline at end of file
diff --git a/chrome/android/touchless/java/res/values/dimens.xml b/chrome/android/touchless/java/res/values/dimens.xml new file mode 100644 index 0000000..d5bc56e --- /dev/null +++ b/chrome/android/touchless/java/res/values/dimens.xml
@@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-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. --> +<resources> + <dimen name="touchless_new_tab_view_padding_horizontal">12dp</dimen> +</resources>
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/ContentSuggestionsViewBinder.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/ContentSuggestionsViewBinder.java new file mode 100644 index 0000000..0c98489 --- /dev/null +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/ContentSuggestionsViewBinder.java
@@ -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. + +package org.chromium.chrome.browser.touchless; + +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; + +import org.chromium.base.Callback; +import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; + +final class ContentSuggestionsViewBinder { + public static void bind( + PropertyModel model, SuggestionsRecyclerView view, PropertyKey propertyKey) { + if (TouchlessNewTabPageProperties.SCROLL_POSITION_CALLBACK == propertyKey) { + Callback<Integer> callback = + model.get(TouchlessNewTabPageProperties.SCROLL_POSITION_CALLBACK); + view.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + callback.onResult(((LinearLayoutManager) recyclerView.getLayoutManager()) + .findFirstVisibleItemPosition()); + } + }); + } else if (TouchlessNewTabPageProperties.INITIAL_SCROLL_POSITION == propertyKey) { + view.getLinearLayoutManager().scrollToPosition( + model.get(TouchlessNewTabPageProperties.INITIAL_SCROLL_POSITION)); + } + } +}
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsAdapter.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsAdapter.java new file mode 100644 index 0000000..cdf470e --- /dev/null +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsAdapter.java
@@ -0,0 +1,64 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touchless; + +import static org.chromium.chrome.browser.touchless.SiteSuggestionsController.SUGGESTIONS_KEY; + +import android.content.Context; +import android.graphics.drawable.BitmapDrawable; +import android.widget.ImageView; + +import org.chromium.chrome.browser.suggestions.SiteSuggestion; +import org.chromium.chrome.browser.widget.RoundedIconGenerator; +import org.chromium.chrome.touchless.R; +import org.chromium.ui.modelutil.ForwardingListObservable; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.RecyclerViewAdapter; + +/** + * Recycler view adapter for Touchless Suggestions carousel. + * + * Allows for an infinite side-scrolling carousel with snapping focus in the center. + */ +public class SiteSuggestionsAdapter + extends ForwardingListObservable<Void> implements RecyclerViewAdapter.Delegate< + SiteSuggestionsViewHolderFactory.SiteSuggestionsViewHolder, Void> { + private PropertyModel mModel; + private RoundedIconGenerator mIconGenerator; + private Context mContext; + + public SiteSuggestionsAdapter( + PropertyModel model, RoundedIconGenerator iconGenerator, Context ctx) { + mModel = model; + mIconGenerator = iconGenerator; + mContext = ctx; + + mModel.get(SUGGESTIONS_KEY).addObserver(this); + } + + @Override + public int getItemCount() { + if (mModel.get(SUGGESTIONS_KEY).size() > 0) { + return Integer.MAX_VALUE; + } + return 0; + } + + @Override + public int getItemViewType(int position) { + return 0; + } + + @Override + public void onBindViewHolder(SiteSuggestionsViewHolderFactory.SiteSuggestionsViewHolder holder, + int position, Void payload) { + SiteSuggestion item = + mModel.get(SUGGESTIONS_KEY).get(position % mModel.get(SUGGESTIONS_KEY).size()); + // TODO(chili): Update when tileview is created with no textview. + ImageView image = holder.itemView.findViewById(R.id.tile_view_icon); + image.setImageDrawable(new BitmapDrawable( + mContext.getResources(), mIconGenerator.generateIconForText(item.title))); + } +} \ No newline at end of file
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsController.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsController.java new file mode 100644 index 0000000..6b52268 --- /dev/null +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsController.java
@@ -0,0 +1,75 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touchless; + +import android.content.Context; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.view.ViewStub; + +import org.chromium.chrome.browser.suggestions.SiteSuggestion; +import org.chromium.chrome.browser.util.ViewUtils; +import org.chromium.chrome.browser.widget.RoundedIconGenerator; +import org.chromium.chrome.touchless.R; +import org.chromium.ui.modelutil.ListModel; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.RecyclerViewAdapter; + +import java.util.Date; + +/** + * Controller for the carousel version of most likely, to be shown on touchless devices. + */ +public class SiteSuggestionsController { + static final PropertyModel.WritableIntPropertyKey CURRENT_INDEX_KEY = + new PropertyModel.WritableIntPropertyKey(); + static final PropertyModel + .ReadableObjectPropertyKey<ListModel<SiteSuggestion>> SUGGESTIONS_KEY = + new PropertyModel.ReadableObjectPropertyKey<>(); + + private View mSuggestionsView; + private PropertyModel mModel; + + public SiteSuggestionsController(View parentView) { + mSuggestionsView = ((ViewStub) parentView.findViewById(R.id.most_likely_stub)).inflate(); + mModel = new PropertyModel.Builder(CURRENT_INDEX_KEY, SUGGESTIONS_KEY) + .with(CURRENT_INDEX_KEY, Integer.MAX_VALUE / 2) + .with(SUGGESTIONS_KEY, new ListModel<>()) + .build(); + + // TODO(chili): Remove when we add suggestions fetching. + mModel.get(SUGGESTIONS_KEY) + .add(new SiteSuggestion( + "All Apps", "http://www.example.com", "", 0, 1, 2, new Date())); + mModel.get(SUGGESTIONS_KEY) + .add(new SiteSuggestion("Fie", "http://www.example.com", "", 0, 1, 2, new Date())); + mModel.get(SUGGESTIONS_KEY) + .add(new SiteSuggestion("Fi", "http://www.example.com", "", 0, 1, 2, new Date())); + mModel.get(SUGGESTIONS_KEY) + .add(new SiteSuggestion("Fo", "http://www.example.com", "", 0, 1, 2, new Date())); + mModel.get(SUGGESTIONS_KEY) + .add(new SiteSuggestion("Fum", "http://www.example.com", "", 0, 1, 2, new Date())); + + Context context = parentView.getContext(); + + RoundedIconGenerator iconGenerator = ViewUtils.createDefaultRoundedIconGenerator( + context.getResources(), /* circularIcon = */ true); + + LinearLayoutManager layoutManager = new LinearLayoutManager( + context, LinearLayoutManager.HORIZONTAL, /* reverseLayout= */ false); + RecyclerView recyclerView = + mSuggestionsView.findViewById(R.id.most_likely_launcher_recycler); + SiteSuggestionsAdapter adapterDelegate = + new SiteSuggestionsAdapter(mModel, iconGenerator, context); + + RecyclerViewAdapter<SiteSuggestionsViewHolderFactory.SiteSuggestionsViewHolder, Void> + adapter = new RecyclerViewAdapter<>( + adapterDelegate, new SiteSuggestionsViewHolderFactory()); + + recyclerView.setLayoutManager(layoutManager); + recyclerView.setAdapter(adapter); + } +} \ No newline at end of file
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsViewHolderFactory.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsViewHolderFactory.java new file mode 100644 index 0000000..0b783ce3 --- /dev/null +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsViewHolderFactory.java
@@ -0,0 +1,35 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touchless; + +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import org.chromium.chrome.touchless.R; +import org.chromium.ui.modelutil.RecyclerViewAdapter; + +/** + * ViewHolderFactory for touchless suggestion tiles. + */ +public class SiteSuggestionsViewHolderFactory implements RecyclerViewAdapter.ViewHolderFactory< + SiteSuggestionsViewHolderFactory.SiteSuggestionsViewHolder> { + /** + * Actual ViewHolder for a touchless suggestion. + */ + public static class SiteSuggestionsViewHolder extends RecyclerView.ViewHolder { + public SiteSuggestionsViewHolder(View view) { + super(view); + } + } + + @Override + public SiteSuggestionsViewHolder createViewHolder(ViewGroup parent, int viewType) { + return new SiteSuggestionsViewHolder( + LayoutInflater.from(parent.getContext()) + .inflate(R.layout.explore_sites_tile_view, parent, false)); + } +} \ No newline at end of file
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java index 9fd815b..922a82a 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java
@@ -4,31 +4,139 @@ package org.chromium.chrome.browser.touchless; +import android.support.v4.view.ViewCompat; +import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; +import android.widget.FrameLayout; +import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.TraceEvent; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.native_page.BasicNativePage; +import org.chromium.chrome.browser.native_page.ContextMenuManager; import org.chromium.chrome.browser.native_page.NativePageHost; +import org.chromium.chrome.browser.ntp.NewTabPage; +import org.chromium.chrome.browser.ntp.NewTabPageUma; +import org.chromium.chrome.browser.ntp.cards.NewTabPageAdapter; +import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.suggestions.SuggestionsDependencyFactory; +import org.chromium.chrome.browser.suggestions.SuggestionsEventReporter; +import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegate; +import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; +import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; +import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegateImpl; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.widget.displaystyle.UiConfig; import org.chromium.chrome.touchless.R; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyModelChangeProcessor; /** * Condensed new tab page for touchless devices. + * + * Acts as Coordinator for the new tab view structure, a recyclerview, that recycles content + * suggestions. Will own the coordinators for the other subsections: + * - Most Likley carousel + * - Recent tab button */ public class TouchlessNewTabPage extends BasicNativePage { - private ViewGroup mView; + private static final String TAG = "TouchlessNewTabPage"; + private String mTitle; + private int mBackgroundColor; + + private TouchlessNewTabPageMediator mMediator; + + private FrameLayout mView; + private TouchlessNewTabPageTopLayout mRecyclerTopmostView; + private SuggestionsRecyclerView mRecyclerView; + private Tab mTab; + private ContextMenuManager mContextMenuManager; public TouchlessNewTabPage(ChromeActivity activity, NativePageHost host) { - super(activity, host); + super(activity, host); // Super calls initialize at the beginning of the constructor. } @Override - protected void initialize(ChromeActivity activity, NativePageHost host) { - mView = (ViewGroup) activity.getLayoutInflater().inflate( - R.layout.new_tab_page_touchless, null); + protected void initialize(ChromeActivity activity, NativePageHost nativePageHost) { + TraceEvent.begin(TAG); + mTitle = activity.getResources().getString(R.string.button_new_tab); + mBackgroundColor = ApiCompatibilityUtils.getColor( + activity.getResources(), R.color.modern_primary_color); + + mView = (FrameLayout) LayoutInflater.from(activity).inflate( + R.layout.new_tab_page_touchless_view, null); + + PropertyModel model = + new PropertyModel.Builder(TouchlessNewTabPageProperties.ALL_KEYS).build(); + + mMediator = new TouchlessNewTabPageMediator(model, nativePageHost.getActiveTab()); + + mRecyclerView = mView.findViewById(R.id.suggestions_recycler_view); + mRecyclerTopmostView = (TouchlessNewTabPageTopLayout) LayoutInflater.from(activity).inflate( + R.layout.new_tab_page_touchless, mRecyclerView, false); + + // TODO(dewittj): Initialize the recent tab coordinator here. + // TODO(dewittj): Initialize the tile suggestions coordinator here. + + initializeContentSuggestions(activity, nativePageHost, model); + + NewTabPageUma.recordIsUserOnline(); + NewTabPageUma.recordLoadType(activity); + TraceEvent.end(TAG); + } + + /* + * TODO(dewittj): This uses SuggestionsRecyclerView and NewTabPageAdapter in a legacy manner + * that does not properly support modern MVC code architecture. + */ + private void initializeContentSuggestions( + ChromeActivity activity, NativePageHost nativePageHost, PropertyModel model) { + long constructedTimeNs = System.nanoTime(); + + NewTabPageUma.trackTimeToFirstDraw(mRecyclerView, constructedTimeNs); + + mTab = activity.getActivityTab(); + Profile profile = mTab.getProfile(); + SuggestionsDependencyFactory depsFactory = SuggestionsDependencyFactory.getInstance(); + SuggestionsSource suggestionsSource = depsFactory.createSuggestionSource(profile); + SuggestionsEventReporter eventReporter = depsFactory.createEventReporter(); + SuggestionsNavigationDelegate navigationDelegate = new SuggestionsNavigationDelegate( + activity, profile, nativePageHost, mTab.getTabModelSelector()); + SuggestionsUiDelegate suggestionsUiDelegate = new SuggestionsUiDelegateImpl( + suggestionsSource, eventReporter, navigationDelegate, profile, nativePageHost, + activity.getChromeApplication().getReferencePool(), activity.getSnackbarManager()); + suggestionsUiDelegate.addDestructionObserver(this::destroy); + + assert suggestionsUiDelegate.getSuggestionsSource() != null; + + // Don't store a direct reference to the activity, because it might change later if the tab + // is reparented. + Runnable closeContextMenuCallback = () -> mTab.getActivity().closeContextMenu(); + mContextMenuManager = new ContextMenuManager(suggestionsUiDelegate.getNavigationDelegate(), + mRecyclerView::setTouchEnabled, closeContextMenuCallback, + NewTabPage.CONTEXT_MENU_USER_ACTION_PREFIX); + mTab.getWindowAndroid().addContextMenuCloseListener(mContextMenuManager); + + UiConfig uiConfig = new UiConfig(mRecyclerView); + mRecyclerView.init(uiConfig, mContextMenuManager); + + NewTabPageAdapter newTabPageAdapter = + new NewTabPageAdapter(suggestionsUiDelegate, mRecyclerTopmostView, uiConfig, + SuggestionsDependencyFactory.getInstance().getOfflinePageBridge(profile), + mContextMenuManager); + + PropertyModelChangeProcessor.create( + model, mRecyclerView, ContentSuggestionsViewBinder::bind); + + newTabPageAdapter.refreshSuggestions(); + + // Set after the Mediator is constructed so that it has time to refresh the suggestions + // before requesting a layout. + mRecyclerView.setAdapter(newTabPageAdapter); } @Override @@ -45,4 +153,20 @@ public String getTitle() { return mTitle; } -} \ No newline at end of file + + @Override + public int getBackgroundColor() { + return mBackgroundColor; + } + + @Override + public void destroy() { + assert !ViewCompat.isAttachedToWindow(getView()) + : "Destroy called before removed from window"; + + mMediator.destroy(); + mTab.getWindowAndroid().removeContextMenuCloseListener(mContextMenuManager); + + super.destroy(); + } +}
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageMediator.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageMediator.java new file mode 100644 index 0000000..9fdd65c4 --- /dev/null +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageMediator.java
@@ -0,0 +1,82 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touchless; + +import android.support.v7.widget.RecyclerView; + +import org.chromium.base.metrics.RecordUserAction; +import org.chromium.chrome.browser.ntp.NewTabPage; +import org.chromium.chrome.browser.ntp.NewTabPageUma; +import org.chromium.chrome.browser.suggestions.SuggestionsMetrics; +import org.chromium.chrome.browser.tab.EmptyTabObserver; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabSelectionType; +import org.chromium.ui.modelutil.PropertyModel; + +class TouchlessNewTabPageMediator extends EmptyTabObserver { + private static final String NAVIGATION_ENTRY_SCROLL_POSITION_KEY = "TouchlessScrollPosition"; + + private final PropertyModel mModel; + private final Tab mTab; + private long mLastShownTimeNs; + + private int mScrollPosition = RecyclerView.NO_POSITION; + + public TouchlessNewTabPageMediator(PropertyModel model, Tab tab) { + mModel = model; + mTab = tab; + mTab.addObserver(this); + + mModel.set(TouchlessNewTabPageProperties.INITIAL_SCROLL_POSITION, + NewTabPage.getScrollPositionFromNavigationEntry( + NAVIGATION_ENTRY_SCROLL_POSITION_KEY, mTab)); + + mModel.set(TouchlessNewTabPageProperties.SCROLL_POSITION_CALLBACK, + (scrollPosition) -> mScrollPosition = scrollPosition); + } + + @Override + public void onShown(Tab tab, @TabSelectionType int type) { + // TODO(dewittj): Track loading status of the tiles before we record + // shown and hidden states. + recordNTPShown(); + } + + @Override + public void onHidden(Tab tab, @Tab.TabHidingType int type) { + recordNTPHidden(); + } + + @Override + public void onPageLoadStarted(Tab tab, String url) { + if (mScrollPosition == RecyclerView.NO_POSITION) return; + + NewTabPage.saveScrollPositionToNavigationEntry( + NAVIGATION_ENTRY_SCROLL_POSITION_KEY, tab, mScrollPosition); + } + + void destroy() { + if (!mTab.isHidden()) recordNTPHidden(); + + mTab.removeObserver(this); + } + + /** + * Records UMA for the NTP being shown. This includes a fresh page load or being brought to + * the foreground. + */ + private void recordNTPShown() { + mLastShownTimeNs = System.nanoTime(); + NewTabPageUma.recordNTPImpression(NewTabPageUma.NTP_IMPRESSION_REGULAR); + RecordUserAction.record("MobileNTPShown"); + SuggestionsMetrics.recordSurfaceVisible(); + } + + /** Records UMA for the NTP being hidden and the time spent on it. */ + private void recordNTPHidden() { + NewTabPageUma.recordTimeSpentOnNtp(mLastShownTimeNs); + SuggestionsMetrics.recordSurfaceHidden(); + } +}
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageProperties.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageProperties.java new file mode 100644 index 0000000..4ef571b7 --- /dev/null +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageProperties.java
@@ -0,0 +1,21 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.touchless; + +import org.chromium.base.Callback; +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; + +class TouchlessNewTabPageProperties { + public static final PropertyModel.WritableIntPropertyKey INITIAL_SCROLL_POSITION = + new PropertyModel.WritableIntPropertyKey(); + + public static final PropertyModel + .WritableObjectPropertyKey<Callback<Integer>> SCROLL_POSITION_CALLBACK = + new PropertyModel.WritableObjectPropertyKey<>(); + + public static final PropertyKey[] ALL_KEYS = { + INITIAL_SCROLL_POSITION, SCROLL_POSITION_CALLBACK}; +}
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageTopLayout.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageTopLayout.java new file mode 100644 index 0000000..653a5dc0 --- /dev/null +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPageTopLayout.java
@@ -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. + +package org.chromium.chrome.browser.touchless; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.LinearLayout; + +/** + * ViewGroup representing the widgets on top of the content suggestions area in the touchless NTP. + */ +class TouchlessNewTabPageTopLayout extends LinearLayout { + public TouchlessNewTabPageTopLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + // TODO(dewittj): Fill in with various Explore views. +}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 5b9c13bd..65ea7792 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -914,6 +914,8 @@ "notifications/notification_platform_bridge_mac.mm", "notifications/notification_schedule_service_factory.cc", "notifications/notification_schedule_service_factory.h", + "notifications/notification_trigger_scheduler.cc", + "notifications/notification_trigger_scheduler.h", "notifications/notification_ui_manager.h", "notifications/notifier_state_tracker.cc", "notifications/notifier_state_tracker.h", @@ -1080,6 +1082,9 @@ "performance_manager/graph/graph_introspector_impl.h", "performance_manager/graph/graph_node_provider_impl.cc", "performance_manager/graph/graph_node_provider_impl.h", + "performance_manager/graph/node_attached_data.cc", + "performance_manager/graph/node_attached_data.h", + "performance_manager/graph/node_attached_data_impl.h", "performance_manager/graph/node_base.cc", "performance_manager/graph/node_base.h", "performance_manager/graph/page_node_impl.cc", @@ -1481,6 +1486,14 @@ "search_engines/ui_thread_search_terms_data_android.h", "search_provider_logos/logo_service_factory.cc", "search_provider_logos/logo_service_factory.h", + "security_events/security_event_recorder.h", + "security_events/security_event_recorder_factory.cc", + "security_events/security_event_recorder_factory.h", + "security_events/security_event_recorder_impl.cc", + "security_events/security_event_recorder_impl.h", + "security_events/security_event_sync_bridge.h", + "security_events/security_event_sync_bridge_impl.cc", + "security_events/security_event_sync_bridge_impl.h", "send_tab_to_self/receiving_ui_handler.h", "send_tab_to_self/receiving_ui_handler_registry.cc", "send_tab_to_self/receiving_ui_handler_registry.h", @@ -1828,7 +1841,6 @@ "//chrome/browser/push_messaging:budget_proto", "//chrome/browser/resource_coordinator:mojo_bindings", "//chrome/browser/safe_browsing", - "//chrome/browser/security_events", "//chrome/browser/ssl:proto", "//chrome/browser/ui", "//chrome/browser/ui/webui/bluetooth_internals", @@ -4766,6 +4778,8 @@ "supervised_user/experimental/supervised_user_blacklist.h", "supervised_user/experimental/supervised_user_filtering_switches.cc", "supervised_user/experimental/supervised_user_filtering_switches.h", + "supervised_user/kids_management_url_checker_client.cc", + "supervised_user/kids_management_url_checker_client.h", "supervised_user/permission_request_creator.h", "supervised_user/supervised_user_constants.cc", "supervised_user/supervised_user_constants.h",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 361e146..e352258 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3072,12 +3072,6 @@ flag_descriptions::kParallelDownloadingDescription, kOsAll, FEATURE_VALUE_TYPE(download::features::kParallelDownloading)}, - {"enable-html-base-username-detector", - flag_descriptions::kHtmlBasedUsernameDetectorName, - flag_descriptions::kHtmlBasedUsernameDetectorDescription, kOsAll, - FEATURE_VALUE_TYPE( - password_manager::features::kHtmlBasedUsernameDetector)}, - #if defined(OS_ANDROID) {"enable-async-dns", flag_descriptions::kAsyncDnsName, flag_descriptions::kAsyncDnsDescription, kOsAndroid,
diff --git a/chrome/browser/android/vr/arcore_device/arcore_device.cc b/chrome/browser/android/vr/arcore_device/arcore_device.cc index c90ffdaf..2092cdcc 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_device.cc +++ b/chrome/browser/android/vr/arcore_device/arcore_device.cc
@@ -108,43 +108,6 @@ arcore_gl_thread_ = nullptr; } -void ArCoreDevice::PauseTracking() { - DCHECK(IsOnMainThread()); - - if (is_paused_) - return; - - is_paused_ = true; - - if (!is_arcore_gl_initialized_) - return; - - PostTaskToGlThread(base::BindOnce( - &ArCoreGl::Pause, arcore_gl_thread_->GetArCoreGl()->GetWeakPtr())); -} - -void ArCoreDevice::ResumeTracking() { - DCHECK(IsOnMainThread()); - - if (!is_paused_) - return; - - is_paused_ = false; - - // TODO(crbug.com/883046): ResumeTracking does not fire after ArCore has been - // updated/installed or the update/installation was cancelled. Thus, we never - // handle queued up session requests. - if (on_request_arcore_install_or_update_result_callback_) - std::move(on_request_arcore_install_or_update_result_callback_) - .Run(!arcore_install_utils_->ShouldRequestInstallSupportedArCore()); - - if (!is_arcore_gl_initialized_) - return; - - PostTaskToGlThread(base::BindOnce( - &ArCoreGl::Resume, arcore_gl_thread_->GetArCoreGl()->GetWeakPtr())); -} - void ArCoreDevice::OnMailboxBridgeReady() { DCHECK(IsOnMainThread()); DCHECK(!arcore_gl_thread_); @@ -309,26 +272,38 @@ DCHECK(!success || is_arcore_gl_thread_initialized_); for (auto& deferred_callback : deferred_request_session_callbacks_) { - mojom::XRSessionControllerPtr controller; - mojom::XRSessionPtr session; - if (success) { - mojom::XRFrameDataProviderPtr data_provider; - magic_window_sessions_.push_back(std::make_unique<VRDisplayImpl>( - this, mojo::MakeRequest(&data_provider), - mojo::MakeRequest(&controller))); - - session = mojom::XRSession::New(); - session->data_provider = data_provider.PassInterface(); - session->display_info = display_info_.Clone(); - } // We don't expect this call to alter deferred_request_session_callbacks_. // The call may request another session, which should be handled right here // in this loop as well. - std::move(deferred_callback).Run(std::move(session), std::move(controller)); + + auto callback = + base::BindOnce(&ArCoreDevice::OnCreateSessionCallback, GetWeakPtr()); + + PostTaskToGlThread( + base::BindOnce(&ArCoreGl::CreateSession, + arcore_gl_thread_->GetArCoreGl()->GetWeakPtr(), + display_info_->Clone(), std::move(deferred_callback), + CreateMainThreadCallback(std::move(callback)))); } deferred_request_session_callbacks_.clear(); } +void ArCoreDevice::OnCreateSessionCallback( + mojom::XRFrameDataProviderPtrInfo frame_data_provider_info, + mojom::VRDisplayInfoPtr display_info, + mojom::XRSessionControllerPtrInfo session_controller_info, + mojom::XRRuntime::RequestSessionCallback deferred_callback) { + DCHECK(IsOnMainThread()); + + mojom::XRSessionPtr session = mojom::XRSession::New(); + session->data_provider = std::move(frame_data_provider_info); + session->display_info = std::move(display_info); + + mojom::XRSessionControllerPtr controller(std::move(session_controller_info)); + + std::move(deferred_callback).Run(std::move(session), std::move(controller)); +} + void ArCoreDevice::PostTaskToGlThread(base::OnceClosure task) { DCHECK(IsOnMainThread()); arcore_gl_thread_->GetArCoreGl()->GetGlThreadTaskRunner()->PostTask( @@ -376,64 +351,7 @@ is_arcore_gl_initialized_ = true; - if (!is_paused_) { - PostTaskToGlThread(base::BindOnce( - &ArCoreGl::Resume, arcore_gl_thread_->GetArCoreGl()->GetWeakPtr())); - } - CallDeferredRequestSessionCallbacks(/*success=*/true); } -bool ArCoreDevice::ShouldPauseTrackingWhenFrameDataRestricted() { - return true; -} - -void ArCoreDevice::OnGetInlineFrameData( - mojom::XRFrameDataProvider::GetFrameDataCallback callback) { - TRACE_EVENT0("gpu", __FUNCTION__); - DCHECK(IsOnMainThread()); - // We should not be able to reach this point if we are not initialized. - DCHECK(is_arcore_gl_thread_initialized_); - - if (is_paused_) { - DVLOG(3) << "ARCore is paused and cannot fulfill frame data requests."; - std::move(callback).Run(nullptr); - return; - } - - // TODO(https://crbug.com/836496) This current implementation does not handle - // multiple sessions well. There should be a better way to handle this than - // taking the max of all sessions. - gfx::Size max_size(0, 0); - display::Display::Rotation rotation; - for (auto& session : magic_window_sessions_) { - max_size.SetToMax(session->sessionFrameSize()); - // We have to pick a rotation so just go with the last one. - rotation = session->sessionRotation(); - } - - if (max_size.IsEmpty()) { - DLOG(ERROR) << "No valid AR frame size provided!"; - std::move(callback).Run(nullptr); - return; - } - - PostTaskToGlThread(base::BindOnce( - &ArCoreGl::ProduceFrame, arcore_gl_thread_->GetArCoreGl()->GetWeakPtr(), - max_size, rotation, CreateMainThreadCallback(std::move(callback)))); -} - -void ArCoreDevice::RequestHitTest( - mojom::XRRayPtr ray, - mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback callback) { - DVLOG(2) << __func__ << ": ray origin=" << ray->origin.ToString() - << ", direction=" << ray->direction.ToString(); - - DCHECK(IsOnMainThread()); - - PostTaskToGlThread(base::BindOnce( - &ArCoreGl::RequestHitTest, arcore_gl_thread_->GetArCoreGl()->GetWeakPtr(), - std::move(ray), CreateMainThreadCallback(std::move(callback)))); -} - } // namespace device
diff --git a/chrome/browser/android/vr/arcore_device/arcore_device.h b/chrome/browser/android/vr/arcore_device/arcore_device.h index 711d3a6..8d517a0 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_device.h +++ b/chrome/browser/android/vr/arcore_device/arcore_device.h
@@ -41,8 +41,6 @@ ~ArCoreDevice() override; // VRDeviceBase implementation. - void PauseTracking() override; - void ResumeTracking() override; void RequestSession( mojom::XRRuntimeSessionOptionsPtr options, mojom::XRRuntime::RequestSessionCallback callback) override; @@ -58,14 +56,6 @@ private: // VRDeviceBase implementation - bool ShouldPauseTrackingWhenFrameDataRestricted() override; - void OnGetInlineFrameData( - mojom::XRFrameDataProvider::GetFrameDataCallback callback) override; - void RequestHitTest( - mojom::XRRayPtr ray, - mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback callback) - override; - void OnMailboxBridgeReady(); void OnArCoreGlThreadInitialized(); void OnRequestCameraPermissionComplete(bool success); @@ -111,6 +101,12 @@ void RequestArCoreGlInitialization(); void OnArCoreGlInitializationComplete(bool success); + void OnCreateSessionCallback( + mojom::XRFrameDataProviderPtrInfo frame_data_provider_info, + mojom::VRDisplayInfoPtr display_info, + mojom::XRSessionControllerPtrInfo session_controller_info, + mojom::XRRuntime::RequestSessionCallback deferred_callback); + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; std::unique_ptr<ArCoreFactory> arcore_factory_; std::unique_ptr<ArImageTransportFactory> ar_image_transport_factory_; @@ -127,12 +123,6 @@ // to be taken. base::OnceClosure pending_request_ar_module_callback_; - // This object is not paused when it is created. Although it is not - // necessarily running during initialization, it is not paused. If it is - // paused before initialization completes, then the underlying runtime will - // not be resumed. - bool is_paused_ = false; - std::vector<mojom::XRRuntime::RequestSessionCallback> deferred_request_session_callbacks_;
diff --git a/chrome/browser/android/vr/arcore_device/arcore_gl.cc b/chrome/browser/android/vr/arcore_device/arcore_gl.cc index 970f5f4..eeb1323f 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_gl.cc +++ b/chrome/browser/android/vr/arcore_device/arcore_gl.cc
@@ -96,6 +96,9 @@ ArCoreGl::ArCoreGl(std::unique_ptr<ArImageTransport> ar_image_transport) : gl_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), ar_image_transport_(std::move(ar_image_transport)), + frame_data_binding_(this), + session_controller_binding_(this), + environment_binding_(this), weak_ptr_factory_(this) {} ArCoreGl::~ArCoreGl() {} @@ -103,6 +106,8 @@ void ArCoreGl::Initialize(vr::ArCoreInstallUtils* install_utils, ArCoreFactory* arcore_factory, base::OnceCallback<void(bool)> callback) { + DVLOG(3) << __func__; + DCHECK(IsOnGlThread()); // Do not DCHECK !is_initialized to allow multiple calls to correctly @@ -146,7 +151,29 @@ std::move(callback).Run(true); } +void ArCoreGl::CreateSession( + mojom::VRDisplayInfoPtr display_info, + mojom::XRRuntime::RequestSessionCallback deferred_callback, + ArCoreGlCreateSessionCallback callback) { + DVLOG(3) << __func__; + + DCHECK(IsOnGlThread()); + DCHECK(is_initialized_); + + mojom::XRFrameDataProviderPtrInfo frame_data_provider_info; + frame_data_binding_.Bind(mojo::MakeRequest(&frame_data_provider_info)); + + mojom::XRSessionControllerPtrInfo controller_info; + session_controller_binding_.Bind(mojo::MakeRequest(&controller_info)); + + std::move(callback).Run(std::move(frame_data_provider_info), + std::move(display_info), std::move(controller_info), + std::move(deferred_callback)); +} + bool ArCoreGl::InitializeGl() { + DVLOG(3) << __func__; + DCHECK(IsOnGlThread()); DCHECK(!is_initialized_); @@ -187,14 +214,23 @@ return true; } -void ArCoreGl::ProduceFrame( - const gfx::Size& frame_size, - display::Display::Rotation display_rotation, +void ArCoreGl::GetFrameData( mojom::XRFrameDataProvider::GetFrameDataCallback callback) { TRACE_EVENT0("gpu", __FUNCTION__); + + DVLOG(3) << __func__ << ": should_update_display_geometry_=" + << should_update_display_geometry_ + << ", transfer_size_=" << transfer_size_.ToString() + << ", display_rotation_=" << display_rotation_; + DCHECK(IsOnGlThread()); DCHECK(is_initialized_); + if (restrict_frame_data_) { + std::move(callback).Run(nullptr); + return; + } + // Check if the frame_size and display_rotation updated last frame. If yes, // apply the update for this frame. if (should_recalculate_uvs_) { @@ -217,19 +253,15 @@ // check above to ensure it executes with the needed one-frame delay. // The delay is needed due to the fact that ArCoreImpl already got a frame // and we don't want to calculate uvs for stale frame with new geometry. - if (transfer_size_ != frame_size || display_rotation_ != display_rotation) { + if (should_update_display_geometry_) { // Set display geometry before calling Update. It's a pending request that // applies to the next frame. - arcore_->SetDisplayGeometry(frame_size, display_rotation); - - // Store the passed in values to ensure that we can update them only if they - // change. - transfer_size_ = frame_size; - display_rotation_ = display_rotation; + arcore_->SetDisplayGeometry(transfer_size_, display_rotation_); // Tell the uvs to recalculate on the next animation frame, by which time // SetDisplayGeometry will have set the new values in arcore_. should_recalculate_uvs_ = true; + should_update_display_geometry_ = false; } TRACE_EVENT_BEGIN0("gpu", "ArCore Update"); @@ -242,6 +274,14 @@ return; } + // First frame will be requested without a prior call to SetDisplayGeometry - + // handle this case. + if (transfer_size_.IsEmpty()) { + DLOG(ERROR) << "No valid AR frame size provided!"; + std::move(callback).Run(nullptr); + return; + } + // Transfer the camera image texture to a MailboxHolder for transport to // the renderer process. gpu::MailboxHolder buffer_holder = @@ -269,6 +309,32 @@ base::Passed(&frame_data), base::Passed(&callback))); } +void ArCoreGl::GetEnvironmentIntegrationProvider( + device::mojom::XREnvironmentIntegrationProviderAssociatedRequest + environment_request) { + DVLOG(3) << __func__; + + DCHECK(IsOnGlThread()); + DCHECK(is_initialized_); + + environment_binding_.Bind(std::move(environment_request)); +} + +void ArCoreGl::UpdateSessionGeometry( + const gfx::Size& frame_size, + display::Display::Rotation display_rotation) { + DVLOG(3) << __func__ << ": frame_size=" << frame_size.ToString() + << ", display_rotation=" << display_rotation; + + DCHECK(IsOnGlThread()); + DCHECK(is_initialized_); + + transfer_size_ = frame_size; + display_rotation_ = display_rotation; + + should_update_display_geometry_ = true; +} + void ArCoreGl::RequestHitTest( mojom::XRRayPtr ray, mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback callback) { @@ -278,6 +344,11 @@ DCHECK(IsOnGlThread()); DCHECK(is_initialized_); + if (restrict_frame_data_) { + std::move(callback).Run(base::nullopt); + return; + } + std::unique_ptr<ArCoreHitTestRequest> request = std::make_unique<ArCoreHitTestRequest>(); request->ray = std::move(ray); @@ -285,9 +356,23 @@ hit_test_requests_.push_back(std::move(request)); } +void ArCoreGl::SetFrameDataRestricted(bool frame_data_restricted) { + DCHECK(IsOnGlThread()); + DCHECK(is_initialized_); + + restrict_frame_data_ = frame_data_restricted; + if (restrict_frame_data_) { + Pause(); + } else { + Resume(); + } +} + void ArCoreGl::ProcessFrame( mojom::XRFrameDataPtr frame_data, mojom::XRFrameDataProvider::GetFrameDataCallback callback) { + DVLOG(3) << __func__; + DCHECK(IsOnGlThread()); DCHECK(is_initialized_);
diff --git a/chrome/browser/android/vr/arcore_device/arcore_gl.h b/chrome/browser/android/vr/arcore_device/arcore_gl.h index 867a15e..3d2f13a 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_gl.h +++ b/chrome/browser/android/vr/arcore_device/arcore_gl.h
@@ -14,8 +14,10 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" +#include "device/vr/public/mojom/isolated_xr_service.mojom.h" #include "device/vr/public/mojom/vr_service.mojom.h" #include "device/vr/util/fps_meter.h" +#include "mojo/public/cpp/bindings/associated_binding.h" #include "mojo/public/cpp/bindings/binding.h" #include "ui/display/display.h" #include "ui/gfx/geometry/quaternion.h" @@ -39,34 +41,58 @@ struct ArCoreHitTestRequest; class ArImageTransport; +using ArCoreGlCreateSessionCallback = base::OnceCallback<void( + mojom::XRFrameDataProviderPtrInfo frame_data_provider_info, + mojom::VRDisplayInfoPtr display_info, + mojom::XRSessionControllerPtrInfo session_controller_info, + mojom::XRRuntime::RequestSessionCallback deferred_callback)>; + // All of this class's methods must be called on the same valid GL thread with // the exception of GetGlThreadTaskRunner() and GetWeakPtr(). -class ArCoreGl { +class ArCoreGl : public mojom::XRFrameDataProvider, + public mojom::XREnvironmentIntegrationProvider, + public mojom::XRSessionController { public: explicit ArCoreGl(std::unique_ptr<ArImageTransport> ar_image_transport); - ~ArCoreGl(); + ~ArCoreGl() override; void Initialize(vr::ArCoreInstallUtils* install_utils, ArCoreFactory* arcore_factory, base::OnceCallback<void(bool)> callback); - void ProduceFrame(const gfx::Size& frame_size, - display::Display::Rotation display_rotation, - mojom::XRFrameDataProvider::GetFrameDataCallback); - void Pause(); - void Resume(); + void CreateSession(mojom::VRDisplayInfoPtr display_info, + mojom::XRRuntime::RequestSessionCallback deferred_callback, + ArCoreGlCreateSessionCallback callback); const scoped_refptr<base::SingleThreadTaskRunner>& GetGlThreadTaskRunner() { return gl_thread_task_runner_; } + // mojom::XRFrameDataProvider + void GetFrameData(GetFrameDataCallback callback) override; + + void GetEnvironmentIntegrationProvider( + mojom::XREnvironmentIntegrationProviderAssociatedRequest + environment_provider) override; + + // mojom::XREnvironmentIntegrationProvider + void UpdateSessionGeometry( + const gfx::Size& frame_size, + display::Display::Rotation display_rotation) override; + void RequestHitTest( mojom::XRRayPtr, - mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback); + mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback) override; + + // mojom::XRSessionController + void SetFrameDataRestricted(bool restricted) override; base::WeakPtr<ArCoreGl> GetWeakPtr(); private: + void Pause(); + void Resume(); + void ProcessFrame(mojom::XRFrameDataPtr frame_data, mojom::XRFrameDataProvider::GetFrameDataCallback callback); @@ -84,6 +110,7 @@ // Default dummy values to ensure consistent behaviour. gfx::Size transfer_size_ = gfx::Size(0, 0); display::Display::Rotation display_rotation_ = display::Display::ROTATE_0; + bool should_update_display_geometry_ = true; gfx::Transform uv_transform_; gfx::Transform projection_; @@ -93,10 +120,17 @@ bool is_initialized_ = false; + bool restrict_frame_data_ = false; + FPSMeter fps_meter_; std::vector<std::unique_ptr<ArCoreHitTestRequest>> hit_test_requests_; + mojo::Binding<mojom::XRFrameDataProvider> frame_data_binding_; + mojo::Binding<mojom::XRSessionController> session_controller_binding_; + mojo::AssociatedBinding<mojom::XREnvironmentIntegrationProvider> + environment_binding_; + // Must be last. base::WeakPtrFactory<ArCoreGl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ArCoreGl);
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 1abcdb45..20de66e 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2559,6 +2559,27 @@ return allow; } +bool ChromeContentBrowserClient::AllowWorkerCacheStorage( + const GURL& url, + content::ResourceContext* context, + const std::vector<content::GlobalFrameRoutingId>& render_frames) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); + content_settings::CookieSettings* cookie_settings = + io_data->GetCookieSettings(); + bool allow = cookie_settings->IsCookieAccessAllowed(url, url); + + // Record access to CacheStorage for potential display in UI. + for (const auto& it : render_frames) { + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&TabSpecificContentSettings::CacheStorageAccessed, + it.child_id, it.frame_routing_id, url, !allow)); + } + + return allow; +} + ChromeContentBrowserClient::AllowWebBluetoothResult ChromeContentBrowserClient::AllowWebBluetooth( content::BrowserContext* browser_context,
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 970609d..5ba3c8dc 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -255,6 +255,10 @@ const GURL& url, content::ResourceContext* context, const std::vector<content::GlobalFrameRoutingId>& render_frames) override; + bool AllowWorkerCacheStorage( + const GURL& url, + content::ResourceContext* context, + const std::vector<content::GlobalFrameRoutingId>& render_frames) override; AllowWebBluetoothResult AllowWebBluetooth( content::BrowserContext* browser_context, const url::Origin& requesting_origin,
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 37a79e2..5e6ce184 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1560,6 +1560,8 @@ "policy/device_status_collector.h", "policy/device_wallpaper_image_handler.cc", "policy/device_wallpaper_image_handler.h", + "policy/device_wifi_allowed_handler.cc", + "policy/device_wifi_allowed_handler.h", "policy/device_wilco_dtc_configuration_handler.cc", "policy/device_wilco_dtc_configuration_handler.h", "policy/display_resolution_handler.cc",
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc index 510ea1c..3843dda 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
@@ -271,7 +271,7 @@ GetPoliciesAndVerifyResult("{\"guid\":\"" + instance_guid() + "\"}"); } -TEST_F(ArcPolicyBridgeTest, ArcPolicyTest) { +TEST_F(ArcPolicyBridgeTest, DISABLED_ArcPolicyTest) { policy_map().Set( policy::key::kArcPolicy, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
diff --git a/chrome/browser/chromeos/child_accounts/screen_time_controller.cc b/chrome/browser/chromeos/child_accounts/screen_time_controller.cc index 3975957e..a2ad4a4 100644 --- a/chrome/browser/chromeos/child_accounts/screen_time_controller.cc +++ b/chrome/browser/chromeos/child_accounts/screen_time_controller.cc
@@ -198,10 +198,10 @@ notification_type = TimeLimitNotifier::LimitType::kBedTime; break; case usage_time_limit::ActivePolicies::kUsageLimit: + case usage_time_limit::ActivePolicies::kOverride: notification_type = TimeLimitNotifier::LimitType::kScreenTime; break; case usage_time_limit::ActivePolicies::kNoActivePolicy: - case usage_time_limit::ActivePolicies::kOverride: break; default: NOTREACHED();
diff --git a/chrome/browser/chromeos/child_accounts/time_limit_notifier.h b/chrome/browser/chromeos/child_accounts/time_limit_notifier.h index cde75c2d..550da29 100644 --- a/chrome/browser/chromeos/child_accounts/time_limit_notifier.h +++ b/chrome/browser/chromeos/child_accounts/time_limit_notifier.h
@@ -24,8 +24,9 @@ class TimeLimitNotifier { public: // The types of time limits to notify for. kScreenTime is used when the - // the screen time limit is about to be used up, and kBedTime is used when - // the bed time is approaching. + // the screen time limit is about to be used up or when the unlock override + // with duration is almost over, and kBedTime is used when the bed time is + // approaching. enum class LimitType { kScreenTime, kBedTime }; explicit TimeLimitNotifier(content::BrowserContext* context);
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc index a4eb63e..e6d307b3 100644 --- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc +++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -33,6 +33,7 @@ #include "chrome/browser/chromeos/policy/device_network_configuration_updater.h" #include "chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager.h" #include "chrome/browser/chromeos/policy/device_wallpaper_image_handler.h" +#include "chrome/browser/chromeos/policy/device_wifi_allowed_handler.h" #include "chrome/browser/chromeos/policy/device_wilco_dtc_configuration_handler.h" #include "chrome/browser/chromeos/policy/enrollment_config.h" #include "chrome/browser/chromeos/policy/hostname_handler.h" @@ -235,6 +236,8 @@ device_wilco_dtc_configuration_handler_ = std::make_unique<DeviceWilcoDtcConfigurationHandler>(GetPolicyService()); + device_wifi_allowed_handler_ = + std::make_unique<DeviceWiFiAllowedHandler>(chromeos::CrosSettings::Get()); } void BrowserPolicyConnectorChromeOS::PreShutdown() {
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h index 09d4ea1..665cabd 100644 --- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h +++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
@@ -44,6 +44,7 @@ class DeviceCloudPolicyInitializer; class DeviceLocalAccountPolicyService; class DeviceNetworkConfigurationUpdater; +class DeviceWiFiAllowedHandler; struct EnrollmentConfig; class HostnameHandler; class MinimumVersionPolicyHandler; @@ -231,6 +232,7 @@ std::unique_ptr<DeviceWallpaperImageHandler> device_wallpaper_image_handler_; std::unique_ptr<DeviceWilcoDtcConfigurationHandler> device_wilco_dtc_configuration_handler_; + std::unique_ptr<DeviceWiFiAllowedHandler> device_wifi_allowed_handler_; // This policy provider is used on Chrome OS to feed user policy into the // global PolicyService instance. This works by installing the cloud policy
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc index 955ccc03..7653065d 100644 --- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc +++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -1201,6 +1201,17 @@ nullptr); } } + + if (policy.has_device_wifi_allowed()) { + const em::DeviceWiFiAllowedProto& container(policy.device_wifi_allowed()); + if (container.has_device_wifi_allowed()) { + policies->Set( + key::kDeviceWiFiAllowed, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_CLOUD, + std::make_unique<base::Value>(container.device_wifi_allowed()), + nullptr); + } + } } } // namespace
diff --git a/chrome/browser/chromeos/policy/device_wifi_allowed_handler.cc b/chrome/browser/chromeos/policy/device_wifi_allowed_handler.cc new file mode 100644 index 0000000..411de33 --- /dev/null +++ b/chrome/browser/chromeos/policy/device_wifi_allowed_handler.cc
@@ -0,0 +1,53 @@ +// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/policy/device_wifi_allowed_handler.h" + +#include <vector> + +#include "base/bind.h" +#include "chromeos/network/network_handler.h" +#include "chromeos/network/prohibited_technologies_handler.h" +#include "chromeos/settings/cros_settings_names.h" +#include "chromeos/settings/cros_settings_provider.h" +#include "third_party/cros_system_api/dbus/shill/dbus-constants.h" + +namespace policy { + +DeviceWiFiAllowedHandler::DeviceWiFiAllowedHandler( + chromeos::CrosSettings* cros_settings) + : cros_settings_(cros_settings), weak_factory_(this) { + wifi_policy_subscription_ = cros_settings_->AddSettingsObserver( + chromeos::kDeviceWiFiAllowed, + base::BindRepeating(&DeviceWiFiAllowedHandler::OnWiFiPolicyChanged, + weak_factory_.GetWeakPtr())); + + // Fire it once so we're sure we get an invocation on startup. + OnWiFiPolicyChanged(); +} + +DeviceWiFiAllowedHandler::~DeviceWiFiAllowedHandler() = default; + +void DeviceWiFiAllowedHandler::OnWiFiPolicyChanged() { + chromeos::CrosSettingsProvider::TrustedStatus status = + cros_settings_->PrepareTrustedValues( + base::BindRepeating(&DeviceWiFiAllowedHandler::OnWiFiPolicyChanged, + weak_factory_.GetWeakPtr())); + if (status != chromeos::CrosSettingsProvider::TRUSTED) + return; + + bool wifi_allowed = true; + cros_settings_->GetBoolean(chromeos::kDeviceWiFiAllowed, &wifi_allowed); + if (!wifi_allowed) { + chromeos::NetworkHandler::Get() + ->prohibited_technologies_handler() + ->AddGloballyProhibitedTechnology(shill::kTypeWifi); + } else { + chromeos::NetworkHandler::Get() + ->prohibited_technologies_handler() + ->RemoveGloballyProhibitedTechnology(shill::kTypeWifi); + } +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/device_wifi_allowed_handler.h b/chrome/browser/chromeos/policy/device_wifi_allowed_handler.h new file mode 100644 index 0000000..350acb3 --- /dev/null +++ b/chrome/browser/chromeos/policy/device_wifi_allowed_handler.h
@@ -0,0 +1,37 @@ +// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_WIFI_ALLOWED_HANDLER_H_ +#define CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_WIFI_ALLOWED_HANDLER_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" + +namespace policy { + +// This class observes the device setting |DeviceWiFiAllowed|, and updates +// the list of shill ProhibitedTechnoligies based on this +// setting. +class DeviceWiFiAllowedHandler { + public: + explicit DeviceWiFiAllowedHandler(chromeos::CrosSettings* cros_settings); + ~DeviceWiFiAllowedHandler(); + + private: + void OnWiFiPolicyChanged(); + + chromeos::CrosSettings* cros_settings_; + std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> + wifi_policy_subscription_; + base::WeakPtrFactory<DeviceWiFiAllowedHandler> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(DeviceWiFiAllowedHandler); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_WIFI_ALLOWED_HANDLER_H_
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc index 6c411daab..50842e80 100644 --- a/chrome/browser/chromeos/settings/device_settings_provider.cc +++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -72,6 +72,7 @@ kDeviceAutoUpdateTimeRestrictions, kDeviceDisabled, kDeviceDisabledMessage, + kDeviceDisplayResolution, kDeviceHostnameTemplate, kDeviceLoginScreenAppInstallList, kDeviceLoginScreenInputMethods, @@ -82,10 +83,10 @@ kDeviceNativePrintersBlacklist, kDeviceNativePrintersWhitelist, kDeviceQuirksDownloadEnabled, - kDeviceUnaffiliatedCrostiniAllowed, - kDeviceWilcoDtcAllowed, - kDeviceDisplayResolution, kDeviceRebootOnUserSignout, + kDeviceUnaffiliatedCrostiniAllowed, + kDeviceWiFiAllowed, + kDeviceWilcoDtcAllowed, kDisplayRotationDefault, kExtensionCacheSize, kHeartbeatEnabled, @@ -624,6 +625,14 @@ new_values_cache->SetBoolean(kAllowBluetooth, true); } + if (policy.has_device_wifi_allowed() && + policy.device_wifi_allowed().has_device_wifi_allowed()) { + new_values_cache->SetBoolean( + kDeviceWiFiAllowed, policy.device_wifi_allowed().device_wifi_allowed()); + } else { + new_values_cache->SetBoolean(kDeviceWiFiAllowed, true); + } + if (policy.has_quirks_download_enabled() && policy.quirks_download_enabled().has_quirks_download_enabled()) { new_values_cache->SetBoolean(
diff --git a/chrome/browser/chromeos/settings/stub_cros_settings_provider.cc b/chrome/browser/chromeos/settings/stub_cros_settings_provider.cc index f5151bb..e70cb9f 100644 --- a/chrome/browser/chromeos/settings/stub_cros_settings_provider.cc +++ b/chrome/browser/chromeos/settings/stub_cros_settings_provider.cc
@@ -99,6 +99,7 @@ values_.SetBoolean(kAccountsPrefShowUserNamesOnSignIn, true); values_.SetValue(kAccountsPrefUsers, base::Value(base::Value::Type::LIST)); values_.SetBoolean(kAllowBluetooth, true); + values_.SetBoolean(kDeviceWiFiAllowed, true); values_.SetBoolean(kAttestationForContentProtectionEnabled, true); values_.SetBoolean(kStatsReportingPref, true); values_.SetValue(kAccountsPrefDeviceLocalAccounts,
diff --git a/chrome/browser/conflicts/installed_applications_win.cc b/chrome/browser/conflicts/installed_applications_win.cc index 0837a023..d698b09b 100644 --- a/chrome/browser/conflicts/installed_applications_win.cc +++ b/chrome/browser/conflicts/installed_applications_win.cc
@@ -128,7 +128,7 @@ L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; std::vector<std::pair<HKEY, REGSAM>> registry_key_combinations; - if (base::win::OSInfo::GetInstance()->architecture() == + if (base::win::OSInfo::GetArchitecture() == base::win::OSInfo::X86_ARCHITECTURE) { // On 32-bit Windows, there is only one view of the registry. registry_key_combinations.emplace_back(HKEY_CURRENT_USER, 0);
diff --git a/chrome/browser/conflicts/module_event_sink_impl_win.cc b/chrome/browser/conflicts/module_event_sink_impl_win.cc index e36d33d0..19370d64 100644 --- a/chrome/browser/conflicts/module_event_sink_impl_win.cc +++ b/chrome/browser/conflicts/module_event_sink_impl_win.cc
@@ -8,6 +8,7 @@ #include <psapi.h> +#include <memory> #include <utility> #include <vector> @@ -159,12 +160,15 @@ std::move(request)); } -void ModuleEventSinkImpl::OnModuleEvent(uint64_t load_address) { - // Handle the event on a background sequence. - base::PostTaskWithTraits( - FROM_HERE, - {base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN, base::MayBlock()}, - base::BindOnce(&HandleModuleEvent, module_database_, process_.Duplicate(), - process_type_, load_address)); +void ModuleEventSinkImpl::OnModuleEvents( + const std::vector<uint64_t>& module_load_addresses) { + for (uint64_t load_address : module_load_addresses) { + // Handle the event on a background sequence. + base::PostTaskWithTraits( + FROM_HERE, + {base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN, base::MayBlock()}, + base::BindOnce(&HandleModuleEvent, module_database_, + process_.Duplicate(), process_type_, load_address)); + } }
diff --git a/chrome/browser/conflicts/module_event_sink_impl_win.h b/chrome/browser/conflicts/module_event_sink_impl_win.h index d86a9c8..de588d6 100644 --- a/chrome/browser/conflicts/module_event_sink_impl_win.h +++ b/chrome/browser/conflicts/module_event_sink_impl_win.h
@@ -7,6 +7,8 @@ #include <stdint.h> +#include <vector> + #include "base/callback_forward.h" #include "base/process/process.h" #include "chrome/common/conflicts/module_event_sink_win.mojom.h" @@ -41,7 +43,8 @@ mojom::ModuleEventSinkRequest request); // mojom::ModuleEventSink implementation: - void OnModuleEvent(uint64_t load_address) override; + void OnModuleEvents( + const std::vector<uint64_t>& module_load_addresses) override; private: friend class ModuleEventSinkImplTest;
diff --git a/chrome/browser/conflicts/module_event_sink_impl_win_unittest.cc b/chrome/browser/conflicts/module_event_sink_impl_win_unittest.cc index 35706986..d0d65fd 100644 --- a/chrome/browser/conflicts/module_event_sink_impl_win_unittest.cc +++ b/chrome/browser/conflicts/module_event_sink_impl_win_unittest.cc
@@ -74,12 +74,25 @@ EXPECT_EQ(0u, modules().size()); // An invalid load event should not cause a module entry. - module_event_sink_impl_->OnModuleEvent(kInvalidLoadAddress); + module_event_sink_impl_->OnModuleEvents({kInvalidLoadAddress}); test_browser_thread_bundle_.RunUntilIdle(); EXPECT_EQ(0u, modules().size()); // A valid load event should cause a module entry. - module_event_sink_impl_->OnModuleEvent(kValidLoadAddress); + module_event_sink_impl_->OnModuleEvents({kValidLoadAddress}); test_browser_thread_bundle_.RunUntilIdle(); EXPECT_EQ(1u, modules().size()); } + +TEST_F(ModuleEventSinkImplTest, MultipleEvents) { + const uintptr_t kLoadAddress1 = reinterpret_cast<uintptr_t>(&__ImageBase); + const uintptr_t kLoadAddress2 = + reinterpret_cast<uintptr_t>(::GetModuleHandle(L"kernel32.dll")); + ASSERT_TRUE(CreateModuleSinkImpl()); + + EXPECT_EQ(0u, modules().size()); + + module_event_sink_impl_->OnModuleEvents({kLoadAddress1, kLoadAddress2}); + test_browser_thread_bundle_.RunUntilIdle(); + EXPECT_EQ(2u, modules().size()); +}
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc index d966732..feb1619 100644 --- a/chrome/browser/content_settings/content_settings_browsertest.cc +++ b/chrome/browser/content_settings/content_settings_browsertest.cc
@@ -326,6 +326,45 @@ ASSERT_FALSE(GetCookies(browser()->profile(), unblocked_url).empty()); } +IN_PROC_BROWSER_TEST_P(CookieSettingsTest, BlockCookiesAlsoBlocksCacheStorage) { + ui_test_utils::NavigateToURL(browser(), GetPageURL()); + content_settings::CookieSettings* settings = + CookieSettingsFactory::GetForProfile(browser()->profile()).get(); + settings->SetCookieSetting(GetPageURL(), CONTENT_SETTING_BLOCK); + + const char kBaseExpected[] = + "%s - SecurityError: An attempt was made to break through the security " + "policy of the user agent."; + + const char kBaseScript[] = + "(async function() {" + " const name = `%s`;" + " try {" + " await %s;" + " } catch(e) {" + " return `${name} - ${e.toString()}`;" + " }" + " return `${name} - success`;" + "}())"; + + const std::vector<std::string> kTestOps({ + "caches.open('foo')", + "caches.has('foo')", + "caches.keys()", + "caches.delete('foo')", + "caches.match('/')", + }); + + content::WebContents* tab = + browser()->tab_strip_model()->GetActiveWebContents(); + + for (auto& op : kTestOps) { + EXPECT_EQ( + base::StringPrintf(kBaseExpected, op.data()), + EvalJs(tab, base::StringPrintf(kBaseScript, op.data(), op.data()))); + } +} + INSTANTIATE_TEST_SUITE_P( /* no prefix */, CookieSettingsTest,
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc index 0e170f1..2c514bc 100644 --- a/chrome/browser/content_settings/tab_specific_content_settings.cc +++ b/chrome/browser/content_settings/tab_specific_content_settings.cc
@@ -208,6 +208,18 @@ } // static +void TabSpecificContentSettings::CacheStorageAccessed(int render_process_id, + int render_frame_id, + const GURL& url, + bool blocked_by_policy) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + TabSpecificContentSettings* settings = + GetForFrame(render_process_id, render_frame_id); + if (settings) + settings->OnCacheStorageAccessed(url, blocked_by_policy); +} + +// static void TabSpecificContentSettings::FileSystemAccessed(int render_process_id, int render_frame_id, const GURL& url, @@ -426,6 +438,22 @@ NotifySiteDataObservers(); } +void TabSpecificContentSettings::OnCacheStorageAccessed( + const GURL& url, + bool blocked_by_policy) { + if (blocked_by_policy) { + blocked_local_shared_objects_.cache_storages()->Add( + url::Origin::Create(url)); + OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES); + } else { + allowed_local_shared_objects_.cache_storages()->Add( + url::Origin::Create(url)); + OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES); + } + + NotifySiteDataObservers(); +} + void TabSpecificContentSettings::OnLocalStorageAccessed( const GURL& url, bool local,
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.h b/chrome/browser/content_settings/tab_specific_content_settings.h index f063802..a98488f 100644 --- a/chrome/browser/content_settings/tab_specific_content_settings.h +++ b/chrome/browser/content_settings/tab_specific_content_settings.h
@@ -147,6 +147,15 @@ const GURL& url, bool blocked_by_policy); + // Called when CacheStorage::Open() is called in the current page. + // If access was blocked due to the user's content settings, + // |blocked_by_policy| should be true, and this function should invoke + // OnContentBlocked. + static void CacheStorageAccessed(int render_process_id, + int render_frame_id, + const GURL& url, + bool blocked_by_policy); + // Called when a specific file system in the current page was accessed. // If access was blocked due to the user's content settings, // |blocked_by_policy| should be true, and this function should invoke @@ -320,6 +329,7 @@ void OnFileSystemAccessed(const GURL& url, bool blocked_by_policy); void OnIndexedDBAccessed(const GURL& url, bool blocked_by_policy); + void OnCacheStorageAccessed(const GURL& url, bool blocked_by_policy); void OnLocalStorageAccessed(const GURL& url, bool local, bool blocked_by_policy);
diff --git a/chrome/browser/extensions/api/processes/processes_apitest.cc b/chrome/browser/extensions/api/processes/processes_apitest.cc index c470ed4..b8febd5 100644 --- a/chrome/browser/extensions/api/processes/processes_apitest.cc +++ b/chrome/browser/extensions/api/processes/processes_apitest.cc
@@ -33,7 +33,7 @@ ASSERT_TRUE(RunExtensionTest("processes/api")) << message_; } -IN_PROC_BROWSER_TEST_F(ProcessesApiTest, ProcessesApiListeners) { +IN_PROC_BROWSER_TEST_F(ProcessesApiTest, DISABLED_ProcessesApiListeners) { EXPECT_EQ(0, GetListenersCount()); // Load extension that adds a listener in background page
diff --git a/chrome/browser/extensions/api/socket/udp_socket_unittest.cc b/chrome/browser/extensions/api/socket/udp_socket_unittest.cc index 826e89e5..1cc6649 100644 --- a/chrome/browser/extensions/api/socket/udp_socket_unittest.cc +++ b/chrome/browser/extensions/api/socket/udp_socket_unittest.cc
@@ -79,9 +79,9 @@ // Confirm that we can call two RecvFroms in quick succession without // triggering crbug.com/146606. socket->Connect(CreateAddressList("127.0.0.1", 40000), - base::BindRepeating(&OnConnected)); - socket->RecvFrom(4096, base::BindRepeating(&OnCompleted)); - socket->RecvFrom(4096, base::BindRepeating(&OnCompleted)); + base::BindOnce(&OnConnected)); + socket->RecvFrom(4096, base::BindOnce(&OnCompleted)); + socket->RecvFrom(4096, base::BindOnce(&OnCompleted)); } TEST_F(UDPSocketUnitTest, TestUDPMulticastJoinGroup) { @@ -123,7 +123,7 @@ EXPECT_NE(0, socket->SetMulticastTimeToLive(-1)); // Negative TTL shall fail. EXPECT_EQ(0, socket->SetMulticastTimeToLive(3)); socket->Connect(CreateAddressList(kGroup, 13333), - base::BindRepeating(&OnConnected)); + base::BindOnce(&OnConnected)); } TEST_F(UDPSocketUnitTest, TestUDPMulticastLoopbackMode) { @@ -132,7 +132,7 @@ EXPECT_EQ(0, socket->SetMulticastLoopbackMode(false)); socket->Connect(CreateAddressList(kGroup, 13333), - base::BindRepeating(&OnConnected)); + base::BindOnce(&OnConnected)); } // Send a test multicast packet every second. @@ -187,15 +187,15 @@ } base::RunLoop run_loop; // |dest| is used with Bind(), so use RecvFrom() instead of Read(). - dest->RecvFrom(1024, - base::BindRepeating(&OnMulticastReadCompleted, - run_loop.QuitClosure(), &packet_received)); + dest->RecvFrom( + 1024, base::BindOnce(&OnMulticastReadCompleted, run_loop.QuitClosure(), + &packet_received)); // Sender EXPECT_EQ(0, src->SetMulticastTimeToLive(0)); - src->Connect(CreateAddressList(kGroup, kPort), - base::BindRepeating(&SendMulticastPacket, run_loop.QuitClosure(), - src.get())); + src->Connect( + CreateAddressList(kGroup, kPort), + base::BindOnce(&SendMulticastPacket, run_loop.QuitClosure(), src.get())); // If not received within the test action timeout, quit the message loop. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index a3ec3601..78819f12 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1212,11 +1212,6 @@ "expiry_milestone": 76 }, { - "name": "enable-html-base-username-detector", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "enable-implicit-root-scroller", "owners": [ "bokan", "input-dev" ], "expiry_milestone": 75 @@ -2173,8 +2168,8 @@ }, { "name": "instant-tethering", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "khorimoto" ], + "expiry_milestone": 80 }, { "name": "interest-feed-content-suggestions",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 33e6602..e4c7bec 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1159,10 +1159,6 @@ const char kHostedAppShimCreationDescription[] = "Create app shims on Mac when creating a hosted app."; -const char kHtmlBasedUsernameDetectorName[] = "HTML-based username detector"; -const char kHtmlBasedUsernameDetectorDescription[] = - "Use HTML-based username detector for the password manager."; - const char kIconNtpName[] = "Large icons on the New Tab page"; const char kIconNtpDescription[] = "Enable the experimental New Tab page using large icons.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 5b6a8881..6efa6473 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -694,9 +694,6 @@ extern const char kHostedAppShimCreationName[]; extern const char kHostedAppShimCreationDescription[]; -extern const char kHtmlBasedUsernameDetectorName[]; -extern const char kHtmlBasedUsernameDetectorDescription[]; - extern const char kIconNtpName[]; extern const char kIconNtpDescription[];
diff --git a/chrome/browser/media/android/cdm/media_drm_origin_id_manager.cc b/chrome/browser/media/android/cdm/media_drm_origin_id_manager.cc index 6e4f4b15a..3e09f21 100644 --- a/chrome/browser/media/android/cdm/media_drm_origin_id_manager.cc +++ b/chrome/browser/media/android/cdm/media_drm_origin_id_manager.cc
@@ -48,8 +48,12 @@ const char kMediaDrmOriginIds[] = "media.media_drm_origin_ids"; const char kExpirableToken[] = "expirable_token"; const char kOriginIds[] = "origin_ids"; -// Only pre-provision up to 5 origin IDs. -constexpr int kMaxPreProvisionedOriginIds = 5; + +// The maximum number of origin IDs to pre-provision. Chosen to be small to +// minimize provisioning server load. +// TODO(jrummell): Adjust this value if needed after initial launch. +constexpr int kMaxPreProvisionedOriginIds = 2; + // "expirable_token" is only good for 24 hours. constexpr base::TimeDelta kExpirationDelta = base::TimeDelta::FromHours(24);
diff --git a/chrome/browser/media/android/cdm/media_drm_origin_id_manager_unittest.cc b/chrome/browser/media/android/cdm/media_drm_origin_id_manager_unittest.cc index faad038..c036368c 100644 --- a/chrome/browser/media/android/cdm/media_drm_origin_id_manager_unittest.cc +++ b/chrome/browser/media/android/cdm/media_drm_origin_id_manager_unittest.cc
@@ -39,7 +39,7 @@ const char kMediaDrmOriginIds[] = "media.media_drm_origin_ids"; const char kExpirableToken[] = "expirable_token"; const char kAvailableOriginIds[] = "origin_ids"; -constexpr size_t kExpectedPreferenceListSize = 5; +constexpr size_t kExpectedPreferenceListSize = 2; constexpr base::TimeDelta kExpirationDelta = base::TimeDelta::FromHours(24); constexpr size_t kConnectionAttempts = 5;
diff --git a/chrome/browser/notifications/notification_trigger_scheduler.cc b/chrome/browser/notifications/notification_trigger_scheduler.cc new file mode 100644 index 0000000..54b4d21d --- /dev/null +++ b/chrome/browser/notifications/notification_trigger_scheduler.cc
@@ -0,0 +1,95 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/notifications/notification_trigger_scheduler.h" + +#include <memory> + +#include "chrome/browser/browser_process.h" +#include "chrome/browser/notifications/platform_notification_service_impl.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/common/pref_names.h" +#include "components/prefs/pref_service.h" +#include "content/public/browser/platform_notification_context.h" +#include "content/public/browser/storage_partition.h" + +using content::BrowserContext; +using content::BrowserThread; + +namespace { + +void TriggerNotificationsForProfile(Profile* profile) { + auto* service = PlatformNotificationServiceImpl::GetInstance(); + base::Time next_trigger = service->ReadNextTriggerTimestamp(profile); + + // Skip this profile if there are no pending notifications. + if (next_trigger > base::Time::Now()) { + // Reschedule in case there are some in the future. + if (next_trigger < base::Time::Max()) + service->ScheduleTrigger(profile, next_trigger); + return; + } + + // Reset the next trigger time. It will be set again if there are more + // scheduled notifications for any storage partition of this profile. + profile->GetPrefs()->SetTime(prefs::kNotificationNextTriggerTime, + base::Time::Max()); + + // Unretained is safe here as PlatformNotificationServiceImpl is a singleton + // and owns its |trigger_scheduler_| until process exit. + BrowserContext::ForEachStoragePartition( + profile, + base::BindRepeating( + &NotificationTriggerScheduler:: + TriggerNotificationsForStoragePartition, + base::Unretained(service->GetNotificationTriggerScheduler()))); +} + +} // namespace + +// static +std::unique_ptr<NotificationTriggerScheduler> +NotificationTriggerScheduler::Create() { + return base::WrapUnique(new NotificationTriggerScheduler()); +} + +// static +void NotificationTriggerScheduler::TriggerNotifications() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + // Skip if the browser process is already in shutdown path. + if (!g_browser_process || g_browser_process->IsShuttingDown()) + return; + auto profiles = g_browser_process->profile_manager()->GetLoadedProfiles(); + for (Profile* profile : profiles) { + TriggerNotificationsForProfile(profile); + // Notifications are technically not supported in Incognito, but in case we + // ever change that lets handle these profiles too. + if (profile->HasOffTheRecordProfile()) + TriggerNotificationsForProfile(profile->GetOffTheRecordProfile()); + } +} + +NotificationTriggerScheduler::NotificationTriggerScheduler() + : weak_ptr_factory_(this) {} + +NotificationTriggerScheduler::~NotificationTriggerScheduler() = default; + +void NotificationTriggerScheduler::ScheduleTrigger(base::Time timestamp) { + base::TimeDelta delay = timestamp - base::Time::Now(); + if (delay.InMicroseconds() < 0) + delay = base::TimeDelta(); + + if (trigger_timer_.IsRunning() && trigger_timer_.GetCurrentDelay() <= delay) + return; + + trigger_timer_.Start( + FROM_HERE, delay, + base::BindOnce(&NotificationTriggerScheduler::TriggerNotifications)); +} + +void NotificationTriggerScheduler::TriggerNotificationsForStoragePartition( + content::StoragePartition* partition) { + partition->GetPlatformNotificationContext()->TriggerNotifications(); +}
diff --git a/chrome/browser/notifications/notification_trigger_scheduler.h b/chrome/browser/notifications/notification_trigger_scheduler.h new file mode 100644 index 0000000..c3f8882 --- /dev/null +++ b/chrome/browser/notifications/notification_trigger_scheduler.h
@@ -0,0 +1,49 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_TRIGGER_SCHEDULER_H_ +#define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_TRIGGER_SCHEDULER_H_ + +#include <memory> + +#include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "base/timer/timer.h" + +namespace content { +class StoragePartition; +} // namespace content + +class NotificationTriggerScheduler { + public: + static std::unique_ptr<NotificationTriggerScheduler> Create(); + + // Triggers pending notifications for all loaded profiles. + static void TriggerNotifications(); + + virtual ~NotificationTriggerScheduler(); + + // Schedules a trigger at |timestamp| that calls TriggerNotifications on each + // StoragePartition of profiles that have pending notifications at that time. + // If there is an existing earlier trigger set, this is a nop. Otherwise this + // overwrites the existing trigger so only the earliest is set at any time. + void ScheduleTrigger(base::Time timestamp); + + // Triggers pending notifications for |partition|. + // TODO(knollr): Mock the actual storage partitions to observe this call in + // tests and make this static in the implementation. + virtual void TriggerNotificationsForStoragePartition( + content::StoragePartition* partition); + + protected: + NotificationTriggerScheduler(); + + private: + base::OneShotTimer trigger_timer_; + base::WeakPtrFactory<NotificationTriggerScheduler> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(NotificationTriggerScheduler); +}; + +#endif // CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_TRIGGER_SCHEDULER_H_
diff --git a/chrome/browser/notifications/notification_trigger_scheduler_unittest.cc b/chrome/browser/notifications/notification_trigger_scheduler_unittest.cc new file mode 100644 index 0000000..95a5a19 --- /dev/null +++ b/chrome/browser/notifications/notification_trigger_scheduler_unittest.cc
@@ -0,0 +1,88 @@ +// 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 <memory> + +#include "chrome/browser/notifications/notification_trigger_scheduler.h" +#include "chrome/browser/notifications/platform_notification_service_impl.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "content/public/browser/browser_context.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; + +namespace { + +constexpr base::TimeDelta kTimeAdvance = base::TimeDelta::FromMilliseconds(1); + +std::unique_ptr<TestingProfileManager> CreateTestingProfileManager() { + std::unique_ptr<TestingProfileManager> profile_manager( + new TestingProfileManager(TestingBrowserProcess::GetGlobal())); + EXPECT_TRUE(profile_manager->SetUp()); + return profile_manager; +} + +PlatformNotificationServiceImpl* GetNotificationService() { + return PlatformNotificationServiceImpl::GetInstance(); +} + +class MockNotificationTriggerScheduler : public NotificationTriggerScheduler { + public: + ~MockNotificationTriggerScheduler() override = default; + MOCK_METHOD1(TriggerNotificationsForStoragePartition, + void(content::StoragePartition* partition)); +}; + +} // namespace + +class NotificationTriggerSchedulerTest : public testing::Test { + protected: + NotificationTriggerSchedulerTest() + : thread_bundle_( + base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME, + base::test::ScopedTaskEnvironment::NowSource:: + MAIN_THREAD_MOCK_TIME) {} + + void SetUp() override { + scheduler_ = new MockNotificationTriggerScheduler(); + GetNotificationService()->trigger_scheduler_ = base::WrapUnique(scheduler_); + + // Advance time a little bit so TimeTicks::Now().is_null() becomes false. + thread_bundle_.FastForwardBy(kTimeAdvance); + } + + MockNotificationTriggerScheduler* scheduler_; + content::TestBrowserThreadBundle thread_bundle_; +}; + +TEST_F(NotificationTriggerSchedulerTest, + TriggerNotificationsCallsAllStoragePartitions) { + EXPECT_CALL(*scheduler_, TriggerNotificationsForStoragePartition(_)).Times(0); + + std::unique_ptr<TestingProfileManager> profile_manager = + CreateTestingProfileManager(); + Profile* profile1 = profile_manager->CreateTestingProfile("profile1"); + Profile* profile2 = profile_manager->CreateTestingProfile("profile2"); + + auto* partition1 = content::BrowserContext::GetStoragePartitionForSite( + profile1, GURL("http://example.com")); + auto* partition2 = content::BrowserContext::GetStoragePartitionForSite( + profile2, GURL("http://example.com")); + + auto now = base::Time::Now(); + auto delta = base::TimeDelta::FromSeconds(3); + GetNotificationService()->ScheduleTrigger(profile1, now + delta); + GetNotificationService()->ScheduleTrigger(profile2, now + delta); + base::RunLoop().RunUntilIdle(); + + testing::Mock::VerifyAndClearExpectations(scheduler_); + EXPECT_CALL(*scheduler_, TriggerNotificationsForStoragePartition(partition1)); + EXPECT_CALL(*scheduler_, TriggerNotificationsForStoragePartition(partition2)); + + thread_bundle_.FastForwardBy(delta); + base::RunLoop().RunUntilIdle(); +}
diff --git a/chrome/browser/notifications/platform_notification_service_impl.cc b/chrome/browser/notifications/platform_notification_service_impl.cc index 2fb6444..06949640 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.cc +++ b/chrome/browser/notifications/platform_notification_service_impl.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/notifications/platform_notification_service_impl.h" +#include <memory> #include <set> #include <utility> #include <vector> @@ -112,9 +113,15 @@ // notification IDs may occur as they were previously stored in a different // data store. registry->RegisterIntegerPref(prefs::kNotificationNextPersistentId, 10000); + + // Store the next notification trigger time for each profile. If none is set, + // this will default to base::Time::Max. + registry->RegisterTimePref(prefs::kNotificationNextTriggerTime, + base::Time::Max()); } -PlatformNotificationServiceImpl::PlatformNotificationServiceImpl() = default; +PlatformNotificationServiceImpl::PlatformNotificationServiceImpl() + : trigger_scheduler_(NotificationTriggerScheduler::Create()) {} PlatformNotificationServiceImpl::~PlatformNotificationServiceImpl() = default; @@ -228,6 +235,27 @@ std::move(callback)); } +void PlatformNotificationServiceImpl::ScheduleTrigger( + BrowserContext* browser_context, + base::Time timestamp) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + PrefService* prefs = Profile::FromBrowserContext(browser_context)->GetPrefs(); + base::Time current_trigger = + prefs->GetTime(prefs::kNotificationNextTriggerTime); + + if (current_trigger > timestamp) + prefs->SetTime(prefs::kNotificationNextTriggerTime, timestamp); + + trigger_scheduler_->ScheduleTrigger(timestamp); +} + +base::Time PlatformNotificationServiceImpl::ReadNextTriggerTimestamp( + BrowserContext* browser_context) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + PrefService* prefs = Profile::FromBrowserContext(browser_context)->GetPrefs(); + return prefs->GetTime(prefs::kNotificationNextTriggerTime); +} + int64_t PlatformNotificationServiceImpl::ReadNextPersistentNotificationId( BrowserContext* browser_context) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -266,6 +294,11 @@ &task_tracker_); } +NotificationTriggerScheduler* +PlatformNotificationServiceImpl::GetNotificationTriggerScheduler() { + return trigger_scheduler_.get(); +} + void PlatformNotificationServiceImpl::OnUrlHistoryQueryComplete( const content::NotificationDatabaseData& data, bool found_url,
diff --git a/chrome/browser/notifications/platform_notification_service_impl.h b/chrome/browser/notifications/platform_notification_service_impl.h index 837a09c..a451cb1 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.h +++ b/chrome/browser/notifications/platform_notification_service_impl.h
@@ -7,6 +7,7 @@ #include <stdint.h> +#include <memory> #include <string> #include <unordered_set> @@ -16,6 +17,7 @@ #include "base/strings/string16.h" #include "base/task/cancelable_task_tracker.h" #include "chrome/browser/notifications/notification_common.h" +#include "chrome/browser/notifications/notification_trigger_scheduler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/buildflags.h" #include "components/history/core/browser/history_service.h" @@ -68,6 +70,11 @@ void GetDisplayedNotifications( content::BrowserContext* browser_context, DisplayedNotificationsCallback callback) override; + void ScheduleTrigger(content::BrowserContext* browser_context, + base::Time timestamp) override; + base::Time ReadNextTriggerTimestamp( + content::BrowserContext* browser_context) override; + int64_t ReadNextPersistentNotificationId( content::BrowserContext* browser_context) override; void RecordNotificationUkmEvent( @@ -79,8 +86,11 @@ history_query_complete_closure_for_testing_ = std::move(closure); } + NotificationTriggerScheduler* GetNotificationTriggerScheduler(); + private: friend struct base::DefaultSingletonTraits<PlatformNotificationServiceImpl>; + friend class NotificationTriggerSchedulerTest; friend class PersistentNotificationHandlerTest; friend class PlatformNotificationServiceBrowserTest; friend class PlatformNotificationServiceTest; @@ -123,6 +133,9 @@ // Task tracker used for querying URLs in the history service. base::CancelableTaskTracker task_tracker_; + // Scheduler for notifications with a trigger. + std::unique_ptr<NotificationTriggerScheduler> trigger_scheduler_; + // Testing-only closure to observe when querying the history service has been // completed, and the result of logging UKM can be observed. base::OnceClosure history_query_complete_closure_for_testing_;
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc index 7ffa614..f6c8a5c 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -20,7 +20,6 @@ #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" #include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/sync/profile_sync_test_util.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "components/autofill/content/common/autofill_agent.mojom.h" @@ -40,8 +39,8 @@ #include "components/prefs/pref_service.h" #include "components/prefs/testing_pref_service.h" #include "components/sessions/content/content_record_password_state.h" +#include "components/sync/driver/test_sync_service.h" #include "components/sync_preferences/testing_pref_service_syncable.h" -#include "components/version_info/version_info.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/web_contents.h" @@ -65,7 +64,6 @@ #endif using autofill::PasswordForm; -using browser_sync::ProfileSyncServiceMock; using content::BrowserContext; using content::WebContents; using password_manager::PasswordManagerClient; @@ -169,6 +167,11 @@ mojo::AssociatedBinding<autofill::mojom::PasswordAutofillAgent> binding_; }; +std::unique_ptr<KeyedService> CreateTestSyncService( + content::BrowserContext* context) { + return std::make_unique<syncer::TestSyncService>(); +} + } // namespace class ChromePasswordManagerClientTest : public ChromeRenderViewHostTestHarness { @@ -183,26 +186,18 @@ } // Caller does not own the returned pointer. - ProfileSyncServiceMock* SetupBasicMockSync() { - ProfileSyncServiceMock* mock_sync_service = - static_cast<ProfileSyncServiceMock*>( + syncer::TestSyncService* SetupBasicTestSync() { + syncer::TestSyncService* sync_service = + static_cast<syncer::TestSyncService*>( ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( - profile(), base::BindRepeating(&BuildMockProfileSyncService))); - - EXPECT_CALL(*mock_sync_service->GetUserSettingsMock(), - IsFirstSetupComplete()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*mock_sync_service, GetTransportState()) - .WillRepeatedly(Return(syncer::SyncService::TransportState::ACTIVE)); - return mock_sync_service; + profile(), base::BindRepeating(&CreateTestSyncService))); + return sync_service; } // Make a navigation entry that will accept an annotation. void SetupNavigationForAnnotation() { - ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync(); - EXPECT_CALL(*mock_sync_service->GetUserSettingsMock(), - IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); + syncer::TestSyncService* sync_service = SetupBasicTestSync(); + sync_service->SetIsUsingSecondaryPassphrase(false); metrics_enabled_ = true; NavigateAndCommit(GURL("about:blank")); } @@ -287,15 +282,10 @@ } TEST_F(ChromePasswordManagerClientTest, GetPasswordSyncState) { - ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync(); + syncer::TestSyncService* sync_service = SetupBasicTestSync(); - syncer::ModelTypeSet active_types; - active_types.Put(syncer::PASSWORDS); - EXPECT_CALL(*mock_sync_service, GetActiveDataTypes()) - .WillRepeatedly(Return(active_types)); - EXPECT_CALL(*mock_sync_service->GetUserSettingsMock(), - IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); + sync_service->SetActiveDataTypes(syncer::ModelTypeSet(syncer::PASSWORDS)); + sync_service->SetIsUsingSecondaryPassphrase(false); ChromePasswordManagerClient* client = GetClient(); @@ -304,25 +294,18 @@ client->GetPasswordSyncState()); // Again, using a custom passphrase. - EXPECT_CALL(*mock_sync_service->GetUserSettingsMock(), - IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(true)); + sync_service->SetIsUsingSecondaryPassphrase(true); EXPECT_EQ(password_manager::SYNCING_WITH_CUSTOM_PASSPHRASE, client->GetPasswordSyncState()); // Report correctly if we aren't syncing passwords. - active_types.Remove(syncer::PASSWORDS); - active_types.Put(syncer::BOOKMARKS); - EXPECT_CALL(*mock_sync_service, GetActiveDataTypes()) - .WillRepeatedly(Return(active_types)); + sync_service->SetActiveDataTypes(syncer::ModelTypeSet(syncer::BOOKMARKS)); EXPECT_EQ(password_manager::NOT_SYNCING, client->GetPasswordSyncState()); // Again, without a custom passphrase. - EXPECT_CALL(*mock_sync_service->GetUserSettingsMock(), - IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); + sync_service->SetIsUsingSecondaryPassphrase(false); EXPECT_EQ(password_manager::NOT_SYNCING, client->GetPasswordSyncState()); } @@ -524,10 +507,8 @@ // Metrics enabled, syncing with non-custom passphrase: Do not annotate. TEST_F(ChromePasswordManagerClientTest, AnnotateNavigationEntryWithMetricsNoCustom) { - ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync(); - EXPECT_CALL(*mock_sync_service->GetUserSettingsMock(), - IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); + syncer::TestSyncService* sync_service = SetupBasicTestSync(); + sync_service->SetIsUsingSecondaryPassphrase(false); metrics_enabled_ = true; NavigateAndCommit(GURL("about:blank")); @@ -541,10 +522,8 @@ // Metrics disabled, syncing with non-custom passphrase: Do not annotate. TEST_F(ChromePasswordManagerClientTest, AnnotateNavigationEntryNoMetricsNoCustom) { - ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync(); - EXPECT_CALL(*mock_sync_service->GetUserSettingsMock(), - IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(false)); + syncer::TestSyncService* sync_service = SetupBasicTestSync(); + sync_service->SetIsUsingSecondaryPassphrase(false); metrics_enabled_ = false; NavigateAndCommit(GURL("about:blank")); @@ -558,10 +537,8 @@ // Metrics enabled, syncing with custom passphrase: Do not annotate. TEST_F(ChromePasswordManagerClientTest, AnnotateNavigationEntryWithMetricsWithCustom) { - ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync(); - EXPECT_CALL(*mock_sync_service->GetUserSettingsMock(), - IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(true)); + syncer::TestSyncService* sync_service = SetupBasicTestSync(); + sync_service->SetIsUsingSecondaryPassphrase(true); metrics_enabled_ = true; NavigateAndCommit(GURL("about:blank")); @@ -575,10 +552,8 @@ // Metrics disabled, syncing with custom passphrase: Do not annotate. TEST_F(ChromePasswordManagerClientTest, AnnotateNavigationEntryNoMetricsWithCustom) { - ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync(); - EXPECT_CALL(*mock_sync_service->GetUserSettingsMock(), - IsUsingSecondaryPassphrase()) - .WillRepeatedly(Return(true)); + syncer::TestSyncService* sync_service = SetupBasicTestSync(); + sync_service->SetIsUsingSecondaryPassphrase(true); metrics_enabled_ = false; NavigateAndCommit(GURL("about:blank"));
diff --git a/chrome/browser/password_manager/password_generation_controller_impl.cc b/chrome/browser/password_manager/password_generation_controller_impl.cc index c5082ea3..f939f64 100644 --- a/chrome/browser/password_manager/password_generation_controller_impl.cc +++ b/chrome/browser/password_manager/password_generation_controller_impl.cc
@@ -15,7 +15,7 @@ #include "components/autofill/core/common/password_form.h" #include "components/autofill/core/common/password_generation_util.h" #include "components/autofill/core/common/signatures_util.h" -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/password_manager/core/browser/password_generation_frame_helper.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/password_manager/core/browser/password_manager_driver.h" @@ -106,7 +106,7 @@ dialog_view_ = create_dialog_factory_.Run(this); uint32_t spec_priority = 0; base::string16 password = - target_frame_driver_->GetPasswordGenerationManager()->GeneratePassword( + target_frame_driver_->GetPasswordGenerationHelper()->GeneratePassword( web_contents_->GetLastCommittedURL().GetOrigin(), generation_element_data_->form_signature, generation_element_data_->field_signature,
diff --git a/chrome/browser/password_manager/password_generation_controller_impl_unittest.cc b/chrome/browser/password_manager/password_generation_controller_impl_unittest.cc index 603a1b4..2cd5142 100644 --- a/chrome/browser/password_manager/password_generation_controller_impl_unittest.cc +++ b/chrome/browser/password_manager/password_generation_controller_impl_unittest.cc
@@ -14,7 +14,7 @@ #include "chrome/browser/autofill/mock_manual_filling_controller.h" #include "chrome/browser/password_manager/password_generation_dialog_view_interface.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/password_manager/core/browser/password_generation_frame_helper.h" #include "components/password_manager/core/browser/stub_password_manager_driver.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -37,19 +37,19 @@ public: MockPasswordManagerDriver() = default; - MOCK_METHOD0(GetPasswordGenerationManager, - password_manager::PasswordGenerationManager*()); + MOCK_METHOD0(GetPasswordGenerationHelper, + password_manager::PasswordGenerationFrameHelper*()); private: DISALLOW_COPY_AND_ASSIGN(MockPasswordManagerDriver); }; -class MockPasswordGenerationManager - : public password_manager::PasswordGenerationManager { +class MockPasswordGenerationHelper + : public password_manager::PasswordGenerationFrameHelper { public: - MockPasswordGenerationManager(password_manager::PasswordManagerClient* client, - password_manager::PasswordManagerDriver* driver) - : password_manager::PasswordGenerationManager(client, driver) {} + MockPasswordGenerationHelper(password_manager::PasswordManagerClient* client, + password_manager::PasswordManagerDriver* driver) + : password_manager::PasswordGenerationFrameHelper(client, driver) {} MOCK_METHOD5(GeneratePassword, base::string16(const GURL&, @@ -59,7 +59,7 @@ uint32_t*)); private: - DISALLOW_COPY_AND_ASSIGN(MockPasswordGenerationManager); + DISALLOW_COPY_AND_ASSIGN(MockPasswordGenerationHelper); }; // Mock modal dialog view used to bypass the need of a valid top level window. @@ -115,8 +115,8 @@ mock_password_manager_driver_ = std::make_unique<NiceMock<MockPasswordManagerDriver>>(); - mock_generation_manager_ = - std::make_unique<NiceMock<MockPasswordGenerationManager>>( + mock_generation_helper_ = + std::make_unique<NiceMock<MockPasswordGenerationHelper>>( nullptr, mock_password_manager_driver_.get()); mock_dialog_ = std::make_unique<NiceMock<MockPasswordGenerationDialogView>>(); @@ -141,8 +141,8 @@ std::unique_ptr<NiceMock<MockPasswordManagerDriver>> mock_password_manager_driver_; - std::unique_ptr<NiceMock<MockPasswordGenerationManager>> - mock_generation_manager_; + std::unique_ptr<NiceMock<MockPasswordGenerationHelper>> + mock_generation_helper_; std::unique_ptr<NiceMock<MockPasswordGenerationDialogView>> mock_dialog_; private: @@ -153,8 +153,8 @@ void PasswordGenerationControllerTest::InitializeGeneration( const base::string16& password) { - ON_CALL(*mock_password_manager_driver_, GetPasswordGenerationManager()) - .WillByDefault(Return(mock_generation_manager_.get())); + ON_CALL(*mock_password_manager_driver_, GetPasswordGenerationHelper()) + .WillByDefault(Return(mock_generation_helper_.get())); EXPECT_CALL(mock_manual_filling_controller_, OnAutomaticGenerationStatusChanged(true)); @@ -163,7 +163,7 @@ true, GetTestGenerationUIData1(), mock_password_manager_driver_->AsWeakPtr()); - ON_CALL(*mock_generation_manager_, GeneratePassword(_, _, _, _, _)) + ON_CALL(*mock_generation_helper_, GeneratePassword(_, _, _, _, _)) .WillByDefault(Return(password)); ON_CALL(mock_dialog_factory(), Run) @@ -220,9 +220,9 @@ base::string16 generated_password = ASCIIToUTF16("t3stp@ssw0rd"); EXPECT_CALL(mock_dialog_factory(), Run) .WillOnce(Return(ByMove(std::move(mock_dialog_)))); - EXPECT_CALL(*mock_password_manager_driver_, GetPasswordGenerationManager()) - .WillOnce(Return(mock_generation_manager_.get())); - EXPECT_CALL(*mock_generation_manager_, + EXPECT_CALL(*mock_password_manager_driver_, GetPasswordGenerationHelper()) + .WillOnce(Return(mock_generation_helper_.get())); + EXPECT_CALL(*mock_generation_helper_, GeneratePassword(_, form_signature, field_signature, uint32_t(new_ui_data.max_length), _)) .WillOnce(Return(generated_password));
diff --git a/chrome/browser/password_manager/password_generation_interactive_uitest.cc b/chrome/browser/password_manager/password_generation_interactive_uitest.cc index 0fae796..1c105893 100644 --- a/chrome/browser/password_manager/password_generation_interactive_uitest.cc +++ b/chrome/browser/password_manager/password_generation_interactive_uitest.cc
@@ -21,7 +21,7 @@ #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/common/autofill_features.h" #include "components/password_manager/core/browser/new_password_form_manager.h" -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/password_manager/core/browser/password_generation_frame_helper.h" #include "components/password_manager/core/browser/password_manager_util.h" #include "components/password_manager/core/browser/test_password_store.h" #include "content/public/browser/render_view_host.h" @@ -41,7 +41,7 @@ ~TestPopupObserver() = default; void OnPopupShown( - PasswordGenerationPopupController::GenerationState state) override { + PasswordGenerationPopupController::GenerationUIState state) override { popup_showing_ = true; state_ = state; MaybeQuitRunLoop(); @@ -53,7 +53,7 @@ } bool popup_showing() const { return popup_showing_; } - PasswordGenerationPopupController::GenerationState state() const { + PasswordGenerationPopupController::GenerationUIState state() const { return state_; } @@ -75,7 +75,7 @@ // The loop to be stopped after the popup state change. base::RunLoop* run_loop_ = nullptr; bool popup_showing_ = false; - PasswordGenerationPopupController::GenerationState state_ = + PasswordGenerationPopupController::GenerationUIState state_ = PasswordGenerationPopupController::kOfferGeneration; DISALLOW_COPY_AND_ASSIGN(TestPopupObserver);
diff --git a/chrome/browser/performance_manager/graph/frame_node_impl.h b/chrome/browser/performance_manager/graph/frame_node_impl.h index ee0e4a6..28c1add2 100644 --- a/chrome/browser/performance_manager/graph/frame_node_impl.h +++ b/chrome/browser/performance_manager/graph/frame_node_impl.h
@@ -25,7 +25,7 @@ resource_coordinator::mojom::FrameCoordinationUnit, resource_coordinator::mojom::FrameCoordinationUnitRequest> { public: - static resource_coordinator::CoordinationUnitType Type() { + static constexpr resource_coordinator::CoordinationUnitType Type() { return resource_coordinator::CoordinationUnitType::kFrame; }
diff --git a/chrome/browser/performance_manager/graph/graph.cc b/chrome/browser/performance_manager/graph/graph.cc index f50b9cc..3af6b38b 100644 --- a/chrome/browser/performance_manager/graph/graph.cc +++ b/chrome/browser/performance_manager/graph/graph.cc
@@ -125,6 +125,23 @@ return GetAllNodesOfType<PageNodeImpl>(); } +size_t Graph::GetNodeAttachedDataCountForTesting(NodeBase* node, + const void* key) const { + if (!node && !key) + return node_attached_data_map_.size(); + + size_t count = 0; + for (auto& node_data : node_attached_data_map_) { + if (node && node_data.first.first != node) + continue; + if (key && node_data.first.second != key) + continue; + ++count; + } + + return count; +} + NodeBase* Graph::AddNewNode(std::unique_ptr<NodeBase> new_cu) { auto it = coordination_units_.emplace(new_cu->id(), std::move(new_cu)); DCHECK(it.second); // Inserted successfully @@ -138,6 +155,13 @@ void Graph::DestroyNode(NodeBase* cu) { OnBeforeNodeDestroyed(cu); + // Remove any node attached data affiliated with this node. + auto lower = node_attached_data_map_.lower_bound(std::make_pair(cu, nullptr)); + auto upper = + node_attached_data_map_.lower_bound(std::make_pair(cu + 1, nullptr)); + node_attached_data_map_.erase(lower, upper); + + // Before removing the node itself. size_t erased = coordination_units_.erase(cu->id()); DCHECK_EQ(1u, erased); }
diff --git a/chrome/browser/performance_manager/graph/graph.h b/chrome/browser/performance_manager/graph/graph.h index c19591b..4cacb7d7 100644 --- a/chrome/browser/performance_manager/graph/graph.h +++ b/chrome/browser/performance_manager/graph/graph.h
@@ -7,12 +7,15 @@ #include <stdint.h> +#include <map> #include <memory> #include <unordered_map> +#include <utility> #include <vector> #include "base/macros.h" #include "base/process/process_handle.h" +#include "chrome/browser/performance_manager/graph/node_attached_data.h" #include "services/metrics/public/cpp/mojo_ukm_recorder.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "services/resource_coordinator/public/cpp/coordination_unit_id.h" @@ -74,6 +77,12 @@ return observers_; } + // A |key| of nullptr counts all instances associated with the |node|. A + // |node| of null counts all instances associated with the |key|. If both are + // null then the entire map size is provided. + size_t GetNodeAttachedDataCountForTesting(NodeBase* node, + const void* key) const; + private: using CUIDMap = std::unordered_map<resource_coordinator::CoordinationUnitID, std::unique_ptr<NodeBase>>; @@ -99,6 +108,13 @@ ukm::UkmRecorder* ukm_recorder_ = nullptr; std::unique_ptr<GraphNodeProviderImpl> provider_; + // User data storage for the graph. + friend class NodeAttachedData; + using NodeAttachedDataKey = std::pair<const NodeBase*, const void*>; + using NodeAttachedDataMap = + std::map<NodeAttachedDataKey, std::unique_ptr<NodeAttachedData>>; + NodeAttachedDataMap node_attached_data_map_; + static void Create(); DISALLOW_COPY_AND_ASSIGN(Graph);
diff --git a/chrome/browser/performance_manager/graph/node_attached_data.cc b/chrome/browser/performance_manager/graph/node_attached_data.cc new file mode 100644 index 0000000..9e8223d --- /dev/null +++ b/chrome/browser/performance_manager/graph/node_attached_data.cc
@@ -0,0 +1,62 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/performance_manager/graph/node_attached_data.h" + +#include <utility> + +#include "base/logging.h" +#include "chrome/browser/performance_manager/graph/graph.h" +#include "chrome/browser/performance_manager/graph/node_base.h" + +namespace performance_manager { + +NodeAttachedData::NodeAttachedData() = default; +NodeAttachedData::~NodeAttachedData() = default; + +bool NodeAttachedData::CanAttach(const NodeBase* node) const { + return CanAttach(node->id().type); +} + +// static +void NodeAttachedData::AttachInMap(const NodeBase* node, + std::unique_ptr<NodeAttachedData> data) { + CHECK(data->CanAttach(node->id().type)); + Graph::NodeAttachedDataKey data_key = std::make_pair(node, data->key()); + auto& map = node->graph()->node_attached_data_map_; + DCHECK(!base::ContainsKey(map, data_key)); + map[data_key] = std::move(data); +} + +// static +NodeAttachedData* NodeAttachedData::GetFromMap(const NodeBase* node, + const void* key) { + Graph::NodeAttachedDataKey data_key = std::make_pair(node, key); + auto& map = node->graph()->node_attached_data_map_; + auto it = map.find(data_key); + if (it == map.end()) + return nullptr; + DCHECK_EQ(key, it->second->key()); + return it->second.get(); +} + +// static +std::unique_ptr<NodeAttachedData> NodeAttachedData::DetachFromMap( + const NodeBase* node, + const void* key) { + Graph::NodeAttachedDataKey data_key = std::make_pair(node, key); + auto& map = node->graph()->node_attached_data_map_; + auto it = map.find(data_key); + + std::unique_ptr<NodeAttachedData> data; + if (it != map.end()) { + data = std::move(it->second); + map.erase(it); + DCHECK(data->CanAttach(node->id().type)); + } + + return data; +} + +} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/node_attached_data.h b/chrome/browser/performance_manager/graph/node_attached_data.h new file mode 100644 index 0000000..8cd5f41 --- /dev/null +++ b/chrome/browser/performance_manager/graph/node_attached_data.h
@@ -0,0 +1,109 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_NODE_ATTACHED_DATA_H_ +#define CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_NODE_ATTACHED_DATA_H_ + +#include <memory> + +#include "base/logging.h" +#include "base/macros.h" +#include "services/resource_coordinator/public/cpp/coordination_unit_types.h" + +namespace performance_manager { + +class NodeBase; + +// Abstract base class used for attaching user data to nodes in the graph. +// Implementations should derive from NodeAttachedDataImpl. See +// node_attached_data_impl.h for details. +class NodeAttachedData { + public: + NodeAttachedData(); + virtual ~NodeAttachedData(); + + // Returns the 'key' associated with this type of NodeAttachedData. This needs + // to be unique per data type or bad things happen. + virtual const void* key() const = 0; + + // Returns true if the implementation is able to be attached to a node of the + // given type. + virtual bool CanAttach( + resource_coordinator::CoordinationUnitType node_type) const = 0; + bool CanAttach(const NodeBase* node) const; + + protected: + friend class NodeAttachedDataTest; + + // For creating / retrieving / destroying data that is stored in a global map + // owned by the graph. These are not intended to be used directly, rather + // they are invoked by the typed helper functions provided via + // NodeAttachedDataImpl. + + // Attaches the provided |data| to the provided |node|. This should only be + // called if the data does not exist (GetFromMap returns nullptr), and will + // DCHECK otherwise. This should also only be called if |data| can be attached + // to the given node type (also enforced by a DCHECK). + static void AttachInMap(const NodeBase* node, + std::unique_ptr<NodeAttachedData> data); + + // Retrieves the data associated with the provided |node| and |key|. This + // returns nullptr if no data exists. + static NodeAttachedData* GetFromMap(const NodeBase* node, const void* key); + + // Detaches the data associated with the provided |node| and |key|. It is + // harmless to call this when no data exists. + static std::unique_ptr<NodeAttachedData> DetachFromMap(const NodeBase* node, + const void* key); +}; + +// Helper class for providing internal storage of a NodeAttachedData +// implementation directly in a node. The storage is provided as a raw buffer of +// bytes which is initialized externally by the NodeAttachedDataImpl via a +// placement new. In this way the node only needs to know about the +// NodeAttachedData base class, and the size of the required storage. +template <size_t DataSize> +class InternalNodeAttachedDataStorage { + public: + static constexpr size_t kDataSize = DataSize; + + InternalNodeAttachedDataStorage() {} + + ~InternalNodeAttachedDataStorage() { Reset(); } + + // Returns a pointer to the data object, if allocated. + NodeAttachedData* Get() { return data_; } + + void Reset() { + if (data_) + data_->~NodeAttachedData(); + data_ = nullptr; + } + + uint8_t* buffer() { return buffer_; } + + protected: + friend class InternalNodeAttachedDataStorageAccess; + + // Transitions this object to being allocated. + void Set(NodeAttachedData* data) { + DCHECK(!data_); + // Depending on the object layout, once it has been cast to a + // NodeAttachedData there's no guarantee that the pointer will be at the + // head of the object, only that the pointer will be somewhere inside of the + // full object extent. + DCHECK_LE(buffer_, reinterpret_cast<uint8_t*>(data)); + DCHECK_GT(buffer_ + kDataSize, reinterpret_cast<uint8_t*>(data)); + data_ = data; + } + + private: + NodeAttachedData* data_ = nullptr; + uint8_t buffer_[kDataSize]; + DISALLOW_COPY_AND_ASSIGN(InternalNodeAttachedDataStorage); +}; + +} // namespace performance_manager + +#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_NODE_ATTACHED_DATA_H_
diff --git a/chrome/browser/performance_manager/graph/node_attached_data_impl.h b/chrome/browser/performance_manager/graph/node_attached_data_impl.h new file mode 100644 index 0000000..0d6c0028 --- /dev/null +++ b/chrome/browser/performance_manager/graph/node_attached_data_impl.h
@@ -0,0 +1,432 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_NODE_ATTACHED_DATA_IMPL_H_ +#define CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_NODE_ATTACHED_DATA_IMPL_H_ + +#include <memory> +#include <type_traits> +#include <utility> + +#include "base/logging.h" +#include "chrome/browser/performance_manager/graph/node_attached_data.h" +#include "services/resource_coordinator/public/cpp/coordination_unit_types.h" + +namespace performance_manager { + +// Helper classes for defining a user data class that is associated with nodes +// in the graph. At most one instance of each type of data may exist per node +// in the graph. +// +// An instance of NodeAttachedData has to be specifically permitted to be +// associated with individual node types, with this being enforced at compile +// time via the type system. For each association, exactly one storage type is +// also specified. Storage may be one of the following: +// +// - In a singleton map owned by the graph (easiest, least efficient). This is +// provided by deriving the traits from NodeAttachedDataInMap<>. If the data +// is needed only for some instances of a node type, use this storage. +// - In a std::unique_ptr<NodeAttachedData> owned by the node itself +// (slightly harder, slightly more efficient). The node type need only be +// aware of the NodeAttachedData base class in this case. This is provided by +// deriving the traits from NodeAttachedDataOwnedByNodeType<>. If the data is +// needed for all instances of a node type, but only for a relatively small +// portion of the nodes lifetime, use this storage type. +// - In a raw buffer owned by the node implementation, initialized by the +// data type using a placement new (most difficult to use, but most memory +// efficient). The node type needs to be aware of NodeAttachedData base class +// and the size of the DataType in this case. This is provided by deriving +// the traits from NodeAttachedDataInternalOnNodeType<>. If the data is needed +// for all instances of a node type and for effectively the entire lifetime of +// the node, use this storage type. +// +// These traits are provided by a "Traits" subclass, which is decorated by +// deriving from the appropriate storage type helpers. Keeping the decorations +// on a subclass keeps the data implementation class hierarchy clean, meaning it +// has a predictable size across all platforms and compilers (a single vtable +// entry). +// +// This is intended to be used as follows: +// +// -- foo.h -- +// class Foo : public NodeAttachedDataImpl<Foo> { +// public: +// // This class communicates how the data type is allowed to be used in the +// // graph. +// struct Traits +// // Can be associated with page nodes, storage in the map. +// : public NodeAttachedDataInMap<PageNodeImpl>, +// // Can be associated with frame nodes, storage provided by a +// // std::unique_ptr<> member in the FrameNodeImpl. +// public NodeAttachedDataOwnedByNodeType<FrameNodeImpl>, +// // Can be associated with process nodes, storage provided inline +// // in the ProcessNodeImpl. +// public NodeAttachedDataInternalOnNodeType<ProcessNodeImpl> {}; +// +// ~Foo() override; +// +// private: +// // Make the impl our friend so it can access the constructor and any +// // storage providers. +// friend class ::performance_manager::NodeAttachedDataImpl<DataType>; +// +// // A default constructor must be provided. It should be protected or +// // private so that only the NodeAttachedDataImpl<Foo> can access it. +// Foo(); +// ... +// +// // Provides access to the std::unique_ptr storage in frame nodes. +// // See NodeAttachedDataOwnedByNodeType<>. +// static std::unique_ptr<NodeAttachedData>* GetUniquePtrStorage( +// FrameNodeImpl* frame_node); +// +// // Provides access to the inline storage in process nodes. The "4" must +// // match sizeof(Foo). See NodeAttachedDataInternalOnNodeType<>. +// static InternalNodeAttachedDataStorage<4>* GetInternalStorage( +// ProcessNodeImpl* process_node); +// +// }; +// -- foo.h -- +// +// Once defined, the class is used the same way, regardless of where the +// storage is implemented. For each bound node type the following functions are +// exposed: +// +// - static Foo* Foo::GetOrCreate(const NodeType* node) +// Creates a Foo associated with |node| if there isn't already one, and +// returns it. +// - static Foo* Foo::Get(const NodeType* node) +// Returns the Foo associated with |node|, which may be nullptr. +// - static bool Foo::Destroy(const NodeType* node) +// Destroys the Foo associated with |node|, if one exists. Returns true if one +// existed, false otherwise. +// +// For example: +// +// -- user_of_foo.cc -- +// Foo* foo = Foo::GetOrCreate(page_node); +// foo->DoSomething(); +// DHCECK_EQ(foo, Foo::Get(page_node)); +// DCHECK(Foo::Destroy(page_node)); +// -- user_of_foo.cc -- + +using NodeTypeEnum = resource_coordinator::CoordinationUnitType; + +// Implementation of NodeAttachedData intended to be used as the base class for +// derived types. Provides the basic plumbing for accessing the node attached +// data in a strongly typed manner, while enforcing node type bindings. +template <typename DataType> +class NodeAttachedDataImpl : public NodeAttachedData { + public: + /////////////////////////////////// + // Storage specification classes // + /////////////////////////////////// + + // The pointer to this object acts as a unique key that identifies the type + // at runtime. Note that the address of this should be taken only from a + // single library, as a different address will be returned from each library + // into which a given data type is linked. + static constexpr int kUserDataKey = 0; + + // A class whose presence in the inheritance hierarchy of the Traits class + // indicates that a NodeAttachedDataImpl is allowed to be attached to the + // given node type, by type or by enum. Used by the storage impl classes. + template <NodeTypeEnum kNodeType> + class NodeAttachedDataPermittedByNodeTypeEnum {}; + template <typename NodeType> + class NodeAttachedDataPermittedOnNodeType + : public NodeAttachedDataPermittedByNodeTypeEnum<NodeType::Type()> { + static_assert(std::is_base_of<NodeBase, NodeType>::value && + !std::is_same<NodeBase, NodeType>::value, + "NodeType must be descended from NodeBase"); + }; + + // The following 3 "mixin" classes are used to enable NodeAttachedData for a + // given node type, and also to provide the storage type for the data. See + // each class for details. + + // A "mixin" class that endows a NodeAttachedData implementation with strongly + // typed data accessors for a given node type. This allows a NodeAttachedData + // to be selectively bound only to certain node types. Use this with NodeBase + // if the data can be attached to any graph node type. + template <typename NodeType> + class NodeAttachedDataInMap + : public NodeAttachedDataPermittedOnNodeType<NodeType> { + public: + static DataType* GetOrCreate(const NodeType* node); + static DataType* Get(const NodeType* node); + static bool Destroy(const NodeType* node); + }; + + // A "mixin" class that endows a NodeAttachedData implementation with strongly + // typed accessors for a given node type, where the storage for the data is + // provided by a std::unique_ptr<NodeAttachedData> owned by the node. + template <typename NodeType> + class NodeAttachedDataOwnedByNodeType + : public NodeAttachedDataPermittedOnNodeType<NodeType> { + public: + static DataType* GetOrCreate(const NodeType* node); + static DataType* Get(const NodeType* node); + static bool Destroy(const NodeType* node); + }; + + // A "mixin" class that endows a NodeAttachedData implementation with strongly + // typed accessors for a given node type, where the storage for the data is + // provided by an InternalNodeAttachedDataStorage<> on the node. + template <typename NodeType> + class NodeAttachedDataInternalOnNodeType + : public NodeAttachedDataPermittedOnNodeType<NodeType> { + public: + static DataType* GetOrCreate(const NodeType* node); + static DataType* Get(const NodeType* node); + static bool Destroy(const NodeType* node); + }; + + static const void* UserDataKey() { return &DataType::kUserDataKey; } + + static bool CanAttachToNodeType( + resource_coordinator::CoordinationUnitType node_type); + + template <typename NodeType> + static bool CanAttachToNodeType() { + static_assert(std::is_base_of<NodeBase, NodeType>::value, + "NodeType must be descended from NodeBase"); + return CanAttachToNodeType(NodeType::Type()); + } + + // NodeAttachedData implementation: + const void* key() const override { return UserDataKey(); } + bool CanAttach( + resource_coordinator::CoordinationUnitType node_type) const override { + return CanAttachToNodeType(node_type); + } + + private: + // Uses implicit conversion of the traits to get the appropriate mixin class + // that implements storage for the node type. This is used to provide dispatch + // of GetOrCreate/Get/Destroy base on the storage type. + template <class NodeType> + static const NodeAttachedDataInMap<NodeType>& GetTraits( + NodeAttachedDataInMap<NodeType>& traits) { + return traits; + } + template <class NodeType> + static const NodeAttachedDataOwnedByNodeType<NodeType>& GetTraits( + NodeAttachedDataOwnedByNodeType<NodeType>& traits) { + return traits; + } + template <class NodeType> + static const NodeAttachedDataInternalOnNodeType<NodeType>& GetTraits( + NodeAttachedDataInternalOnNodeType<NodeType>& traits) { + return traits; + } + + public: + // Creates (if necessary) and retrieves the data associated with the provided + // node. + template <typename NodeType> + static DataType* GetOrCreate(const NodeType* node) { + typename DataType::Traits traits; + return GetTraits<NodeType>(traits).GetOrCreate(node); + } + + // Retrieves the data associated with the provided node if it exists. + template <typename NodeType> + static DataType* Get(const NodeType* node) { + typename DataType::Traits traits; + return GetTraits<NodeType>(traits).Get(node); + } + + // Destroys the data associated with the provided node. Returns true data was + // deleted, false otherwise. + template <typename NodeType> + static bool Destroy(const NodeType* node) { + typename DataType::Traits traits; + return GetTraits<NodeType>(traits).Destroy(node); + } +}; + +// static +template <typename DataType> +constexpr int NodeAttachedDataImpl<DataType>::kUserDataKey; + +/////////////////////////////////////////////////////////// +// Everything below this point is implementation detail! // +/////////////////////////////////////////////////////////// + +// Implementation of NodeAttachedDataImpl. + +// static +template <typename DataType> +bool NodeAttachedDataImpl<DataType>::CanAttachToNodeType( + resource_coordinator::CoordinationUnitType node_type) { + switch (node_type) { + case NodeTypeEnum::kInvalidType: { + return false; + } + case NodeTypeEnum::kFrame: { + return std::is_base_of< + NodeAttachedDataPermittedByNodeTypeEnum<NodeTypeEnum::kFrame>, + typename DataType::Traits>::value; + } + case NodeTypeEnum::kPage: { + return std::is_base_of< + NodeAttachedDataPermittedByNodeTypeEnum<NodeTypeEnum::kPage>, + typename DataType::Traits>::value; + } + case NodeTypeEnum::kProcess: { + return std::is_base_of< + NodeAttachedDataPermittedByNodeTypeEnum<NodeTypeEnum::kProcess>, + typename DataType::Traits>::value; + } + case NodeTypeEnum::kSystem: { + return std::is_base_of< + NodeAttachedDataPermittedByNodeTypeEnum<NodeTypeEnum::kSystem>, + typename DataType::Traits>::value; + } + } +} + +// Helper class allowing access to internals of +// InternalNodeAttachedDataStorage<>. +class InternalNodeAttachedDataStorageAccess { + public: + // InternalNodeAttachedDataStorage<> forwarding. + template <typename InlineStorageType> + static void Set(InlineStorageType* storage, NodeAttachedData* data) { + storage->Set(data); + } +}; + +// Implementation of storage type mixins. + +// Map storage impl. + +// static +template <typename DataType> +template <typename NodeType> +DataType* +NodeAttachedDataImpl<DataType>::NodeAttachedDataInMap<NodeType>::GetOrCreate( + const NodeType* node) { + NodeAttachedData* base_data = + NodeAttachedData::GetFromMap(node, DataType::UserDataKey()); + if (base_data) { + DCHECK_EQ(DataType::UserDataKey(), base_data->key()); + return static_cast<DataType*>(base_data); + } + std::unique_ptr<DataType> data = std::make_unique<DataType>(); + DataType* raw_data = data.get(); + NodeAttachedData::AttachInMap(node, std::move(data)); + return raw_data; +} + +// static +template <typename DataType> +template <typename NodeType> +DataType* NodeAttachedDataImpl<DataType>::NodeAttachedDataInMap<NodeType>::Get( + const NodeType* node) { + auto* data = NodeAttachedData::GetFromMap(node, DataType::UserDataKey()); + DCHECK(!data || DataType::UserDataKey() == data->key()); + return static_cast<DataType*>(data); +} + +// static +template <typename DataType> +template <typename NodeType> +bool NodeAttachedDataImpl<DataType>::NodeAttachedDataInMap<NodeType>::Destroy( + const NodeType* node) { + std::unique_ptr<NodeAttachedData> data = + NodeAttachedData::DetachFromMap(node, DataType::UserDataKey()); + return data.get(); +} + +// Node owned storage impl. + +// static +template <typename DataType> +template <typename NodeType> +DataType* NodeAttachedDataImpl<DataType>::NodeAttachedDataOwnedByNodeType< + NodeType>::GetOrCreate(const NodeType* node) { + std::unique_ptr<NodeAttachedData>* storage = + DataType::GetUniquePtrStorage(const_cast<NodeType*>(node)); + if (!storage->get()) + *storage = std::make_unique<DataType>(); + DCHECK_EQ(DataType::UserDataKey(), storage->get()->key()); + return static_cast<DataType*>(storage->get()); +} + +// static +template <typename DataType> +template <typename NodeType> +DataType* +NodeAttachedDataImpl<DataType>::NodeAttachedDataOwnedByNodeType<NodeType>::Get( + const NodeType* node) { + std::unique_ptr<NodeAttachedData>* storage = + DataType::GetUniquePtrStorage(const_cast<NodeType*>(node)); + if (storage->get()) + DCHECK_EQ(DataType::UserDataKey(), storage->get()->key()); + return static_cast<DataType*>(storage->get()); +} + +// static +template <typename DataType> +template <typename NodeType> +bool NodeAttachedDataImpl<DataType>::NodeAttachedDataOwnedByNodeType< + NodeType>::Destroy(const NodeType* node) { + std::unique_ptr<NodeAttachedData>* storage = + DataType::GetUniquePtrStorage(const_cast<NodeType*>(node)); + bool data_exists = storage->get(); + storage->reset(); + return data_exists; +} + +// Node internal storage impl. + +// static +template <typename DataType> +template <typename NodeType> +DataType* NodeAttachedDataImpl<DataType>::NodeAttachedDataInternalOnNodeType< + NodeType>::GetOrCreate(const NodeType* node) { + static_assert( + std::is_same<InternalNodeAttachedDataStorage<sizeof(DataType)>*, + typename std::result_of<decltype ( + &DataType::GetInternalStorage)(NodeType*)>::type>::value, + "NodeType provided internal storage doesn't match size of DataType"); + InternalNodeAttachedDataStorage<sizeof(DataType)>* storage = + DataType::GetInternalStorage(const_cast<NodeType*>(node)); + if (!storage->Get()) { + NodeAttachedData* data = new (storage->buffer()) DataType(); + InternalNodeAttachedDataStorageAccess::Set(storage, data); + } + DCHECK_EQ(DataType::UserDataKey(), storage->Get()->key()); + return static_cast<DataType*>(storage->Get()); +} + +// static +template <typename DataType> +template <typename NodeType> +DataType* NodeAttachedDataImpl<DataType>::NodeAttachedDataInternalOnNodeType< + NodeType>::Get(const NodeType* node) { + InternalNodeAttachedDataStorage<sizeof(DataType)>* storage = + DataType::GetInternalStorage(const_cast<NodeType*>(node)); + if (storage->Get()) + DCHECK_EQ(DataType::UserDataKey(), storage->Get()->key()); + return static_cast<DataType*>(storage->Get()); +} + +// static +template <typename DataType> +template <typename NodeType> +bool NodeAttachedDataImpl<DataType>::NodeAttachedDataInternalOnNodeType< + NodeType>::Destroy(const NodeType* node) { + InternalNodeAttachedDataStorage<sizeof(DataType)>* storage = + DataType::GetInternalStorage(const_cast<NodeType*>(node)); + bool data_exists = storage->Get(); + storage->Reset(); + return data_exists; +} + +} // namespace performance_manager + +#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_GRAPH_NODE_ATTACHED_DATA_IMPL_H_
diff --git a/chrome/browser/performance_manager/graph/node_attached_data_unittest.cc b/chrome/browser/performance_manager/graph/node_attached_data_unittest.cc new file mode 100644 index 0000000..6dcfbb3 --- /dev/null +++ b/chrome/browser/performance_manager/graph/node_attached_data_unittest.cc
@@ -0,0 +1,307 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/performance_manager/graph/node_attached_data.h" + +#include <utility> + +#include "base/test/gtest_util.h" +#include "chrome/browser/performance_manager/graph/frame_node_impl.h" +#include "chrome/browser/performance_manager/graph/graph.h" +#include "chrome/browser/performance_manager/graph/graph_test_harness.h" +#include "chrome/browser/performance_manager/graph/mock_graphs.h" +#include "chrome/browser/performance_manager/graph/node_attached_data_impl.h" +#include "chrome/browser/performance_manager/graph/page_node_impl.h" +#include "chrome/browser/performance_manager/graph/process_node_impl.h" +#include "chrome/browser/performance_manager/graph/system_node_impl.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace performance_manager { + +namespace { + +// Note that a FooData basically has pointer size, because its an empty class +// with a single vtable pointer. +constexpr size_t kFooDataSize = sizeof(uintptr_t); + +// A dummy node type so that we can exercise node attached storage code paths. +class DummyNode : public NodeBase { + public: + explicit DummyNode(Graph* graph) + : NodeBase(resource_coordinator::CoordinationUnitID( + resource_coordinator::CoordinationUnitType::kInvalidType, + resource_coordinator::CoordinationUnitID::RANDOM_ID), + graph) {} + + ~DummyNode() override = default; + + static constexpr resource_coordinator::CoordinationUnitType Type() { + return resource_coordinator::CoordinationUnitType::kInvalidType; + } + + // Internal storage for DummyData and FooData types. These would normally be + // protected and the data classes friended, but we also want to access these + // in the tests. + std::unique_ptr<NodeAttachedData> dummy_data_; + InternalNodeAttachedDataStorage<kFooDataSize> foo_data_; + + private: + DISALLOW_COPY_AND_ASSIGN(DummyNode); +}; + +// A NodeAttachedData class that can only be attached to page and process nodes +// using the map, and to DummyNodes using node owned storage. +class DummyData : public NodeAttachedDataImpl<DummyData> { + public: + struct Traits : public NodeAttachedDataInMap<PageNodeImpl>, + public NodeAttachedDataInMap<ProcessNodeImpl>, + public NodeAttachedDataOwnedByNodeType<DummyNode> {}; + + DummyData() = default; + ~DummyData() override = default; + + // Provides access to storage on DummyNodes. + static std::unique_ptr<NodeAttachedData>* GetUniquePtrStorage( + DummyNode* dummy_node) { + return &dummy_node->dummy_data_; + } + + private: + DISALLOW_COPY_AND_ASSIGN(DummyData); +}; + +// Another NodeAttachedData class that can only be attached to page nodes in the +// map, and to DummyNodes using node internal storage. +class FooData : public NodeAttachedDataImpl<FooData> { + public: + struct Traits : public NodeAttachedDataInMap<PageNodeImpl>, + public NodeAttachedDataInternalOnNodeType<DummyNode> {}; + + FooData() = default; + ~FooData() override = default; + + // Provides access to storage on DummyNodes. + static InternalNodeAttachedDataStorage<kFooDataSize>* GetInternalStorage( + DummyNode* dummy_node) { + return &dummy_node->foo_data_; + } + + private: + DISALLOW_COPY_AND_ASSIGN(FooData); +}; + +} // namespace + +class NodeAttachedDataTest : public GraphTestHarness { + public: + NodeAttachedDataTest() = default; + ~NodeAttachedDataTest() override = default; + + static void AttachInMap(const NodeBase* node, + std::unique_ptr<NodeAttachedData> data) { + return NodeAttachedData::AttachInMap(node, std::move(data)); + } + + // Retrieves the data associated with the provided |node| and |key|. This + // returns nullptr if no data exists. + static NodeAttachedData* GetFromMap(const NodeBase* node, const void* key) { + return NodeAttachedData::GetFromMap(node, key); + } + + // Detaches the data associated with the provided |node| and |key|. It is + // harmless to call this when no data exists. + static std::unique_ptr<NodeAttachedData> DetachFromMap(const NodeBase* node, + const void* key) { + return NodeAttachedData::DetachFromMap(node, key); + } +}; + +TEST_F(NodeAttachedDataTest, UserDataKey) { + std::unique_ptr<NodeAttachedData> data = std::make_unique<DummyData>(); + EXPECT_EQ(data->key(), DummyData::UserDataKey()); +} + +TEST_F(NodeAttachedDataTest, CanAttach) { + EXPECT_FALSE(DummyData::CanAttachToNodeType<FrameNodeImpl>()); + EXPECT_TRUE(DummyData::CanAttachToNodeType<PageNodeImpl>()); + EXPECT_TRUE(DummyData::CanAttachToNodeType<ProcessNodeImpl>()); + EXPECT_FALSE(DummyData::CanAttachToNodeType<SystemNodeImpl>()); + + EXPECT_FALSE(DummyData::CanAttachToNodeType( + resource_coordinator::CoordinationUnitType::kInvalidType)); + EXPECT_FALSE(DummyData::CanAttachToNodeType( + resource_coordinator::CoordinationUnitType::kFrame)); + EXPECT_TRUE(DummyData::CanAttachToNodeType( + resource_coordinator::CoordinationUnitType::kPage)); + EXPECT_TRUE(DummyData::CanAttachToNodeType( + resource_coordinator::CoordinationUnitType::kProcess)); + EXPECT_FALSE(DummyData::CanAttachToNodeType( + resource_coordinator::CoordinationUnitType::kSystem)); + + std::unique_ptr<NodeAttachedData> data = std::make_unique<DummyData>(); + EXPECT_FALSE(data->CanAttach( + resource_coordinator::CoordinationUnitType::kInvalidType)); + EXPECT_FALSE( + data->CanAttach(resource_coordinator::CoordinationUnitType::kFrame)); + EXPECT_TRUE( + data->CanAttach(resource_coordinator::CoordinationUnitType::kPage)); + EXPECT_TRUE( + data->CanAttach(resource_coordinator::CoordinationUnitType::kProcess)); + EXPECT_FALSE( + data->CanAttach(resource_coordinator::CoordinationUnitType::kSystem)); +} + +TEST_F(NodeAttachedDataTest, RawAttachDetach) { + MockSinglePageInSingleProcessGraph graph(coordination_unit_graph()); + auto* page_node = graph.page.get(); + + static constexpr NodeAttachedData* kNull = nullptr; + + std::unique_ptr<DummyData> data = std::make_unique<DummyData>(); + auto* raw_data = data.get(); + auto* raw_base = static_cast<NodeAttachedData*>(raw_data); + + // No data yet exists. + EXPECT_EQ(0u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + EXPECT_EQ(kNull, GetFromMap(page_node, raw_data->key())); + + // Attach the data and look it up again. + AttachInMap(page_node, std::move(data)); + EXPECT_EQ(1u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + EXPECT_EQ(raw_base, GetFromMap(page_node, raw_data->key())); + + // Detach the data. + std::unique_ptr<NodeAttachedData> base_data = + DetachFromMap(page_node, raw_data->key()); + EXPECT_EQ(0u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + EXPECT_EQ(raw_base, base_data.get()); + EXPECT_EQ(kNull, GetFromMap(page_node, raw_data->key())); +} + +TEST_F(NodeAttachedDataTest, RawAttachExplodesOnWrongNodeType) { + MockSinglePageInSingleProcessGraph graph(coordination_unit_graph()); + auto* frame_node = graph.frame.get(); + + // Trying to attach a DummyData to a FrameNode should explode with a CHECK. + std::unique_ptr<DummyData> data = std::make_unique<DummyData>(); + EXPECT_CHECK_DEATH(AttachInMap(frame_node, std::move(data))); +} + +TEST_F(NodeAttachedDataTest, TypedAttachDetach) { + MockSinglePageInSingleProcessGraph graph(coordination_unit_graph()); + auto* page_node = graph.page.get(); + + static constexpr DummyData* kNull = nullptr; + + // Lookup non-existent data. + EXPECT_EQ(0u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + EXPECT_EQ(kNull, DummyData::Get(page_node)); + + // Create the data and look it up again. + auto* data = DummyData::GetOrCreate(page_node); + EXPECT_EQ(1u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + EXPECT_NE(kNull, data); + EXPECT_EQ(data, DummyData::Get(page_node)); + + // Destroy the data and expect it to no longer exist. + EXPECT_TRUE(DummyData::Destroy(page_node)); + EXPECT_EQ(0u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + EXPECT_EQ(kNull, DummyData::Get(page_node)); +} + +TEST_F(NodeAttachedDataTest, NodeDeathDestroysData) { + MockSinglePageInSingleProcessGraph graph(coordination_unit_graph()); + auto* page_node = graph.page.get(); + auto* proc_node = graph.process.get(); + + EXPECT_EQ(0u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + EXPECT_EQ(0u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + page_node, DummyData::UserDataKey())); + EXPECT_EQ(0u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + proc_node, DummyData::UserDataKey())); + + // Add data to both the process and the page. + DummyData::GetOrCreate(page_node); + FooData::GetOrCreate(page_node); + auto* proc_data = DummyData::GetOrCreate(proc_node); + EXPECT_EQ(3u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + EXPECT_EQ(2u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + page_node, nullptr)); + EXPECT_EQ(1u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + proc_node, DummyData::UserDataKey())); + + // Release the page node and expect the node attached data to have been + // cleaned up. + graph.page.reset(); + EXPECT_EQ(1u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + EXPECT_EQ(0u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + page_node, nullptr)); + EXPECT_EQ(1u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + proc_node, DummyData::UserDataKey())); + + // The process data should still exist. + EXPECT_EQ(proc_data, DummyData::Get(proc_node)); +} + +TEST_F(NodeAttachedDataTest, NodeOwnedStorage) { + DummyNode dummy_node(coordination_unit_graph()); + + // The storage in the dummy node should not be initialized. + EXPECT_FALSE(dummy_node.dummy_data_.get()); + EXPECT_FALSE(DummyData::Get(&dummy_node)); + + // Creating a DummyData on the DummyNode should not create storage in the map. + EXPECT_EQ(0u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + DummyData* dummy_data = DummyData::GetOrCreate(&dummy_node); + NodeAttachedData* nad = static_cast<NodeAttachedData*>(dummy_data); + EXPECT_EQ(0u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + + // The storage in the dummy node should now be initialized. + EXPECT_EQ(nad, dummy_node.dummy_data_.get()); + EXPECT_EQ(dummy_data, DummyData::Get(&dummy_node)); + + // Destroying the data should free up the storage. + DummyData::Destroy(&dummy_node); + EXPECT_FALSE(dummy_node.dummy_data_.get()); + EXPECT_FALSE(DummyData::Get(&dummy_node)); +} + +TEST_F(NodeAttachedDataTest, NodeInternalStorage) { + DummyNode dummy_node(coordination_unit_graph()); + + // The storage in the dummy node should not be initialized. + EXPECT_FALSE(dummy_node.foo_data_.Get()); + EXPECT_FALSE(FooData::Get(&dummy_node)); + + // Creating a FooData on the DummyNode should not create storage in the map. + EXPECT_EQ(0u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + FooData* foo_data = FooData::GetOrCreate(&dummy_node); + NodeAttachedData* nad = static_cast<NodeAttachedData*>(foo_data); + EXPECT_EQ(0u, coordination_unit_graph()->GetNodeAttachedDataCountForTesting( + nullptr, nullptr)); + + // The storage in the dummy node should now be initialized. + EXPECT_EQ(nad, dummy_node.foo_data_.Get()); + EXPECT_EQ(foo_data, FooData::Get(&dummy_node)); + + // Destroying the data should free up the storage. + FooData::Destroy(&dummy_node); + EXPECT_FALSE(dummy_node.foo_data_.Get()); + EXPECT_FALSE(FooData::Get(&dummy_node)); +} + +} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/graph/page_node_impl.h b/chrome/browser/performance_manager/graph/page_node_impl.h index 1e8cb9f..7a3075a7 100644 --- a/chrome/browser/performance_manager/graph/page_node_impl.h +++ b/chrome/browser/performance_manager/graph/page_node_impl.h
@@ -25,7 +25,7 @@ public: struct PageAlmostIdleHelper; - static resource_coordinator::CoordinationUnitType Type() { + static constexpr resource_coordinator::CoordinationUnitType Type() { return resource_coordinator::CoordinationUnitType::kPage; }
diff --git a/chrome/browser/performance_manager/graph/process_node_impl.h b/chrome/browser/performance_manager/graph/process_node_impl.h index 3cdaef06..827aede 100644 --- a/chrome/browser/performance_manager/graph/process_node_impl.h +++ b/chrome/browser/performance_manager/graph/process_node_impl.h
@@ -33,7 +33,7 @@ resource_coordinator::mojom::ProcessCoordinationUnit, resource_coordinator::mojom::ProcessCoordinationUnitRequest> { public: - static resource_coordinator::CoordinationUnitType Type() { + static constexpr resource_coordinator::CoordinationUnitType Type() { return resource_coordinator::CoordinationUnitType::kProcess; }
diff --git a/chrome/browser/performance_manager/graph/system_node_impl.h b/chrome/browser/performance_manager/graph/system_node_impl.h index 65b3f86..0bee680 100644 --- a/chrome/browser/performance_manager/graph/system_node_impl.h +++ b/chrome/browser/performance_manager/graph/system_node_impl.h
@@ -17,7 +17,7 @@ resource_coordinator::mojom::SystemCoordinationUnit, resource_coordinator::mojom::SystemCoordinationUnitRequest> { public: - static resource_coordinator::CoordinationUnitType Type() { + static constexpr resource_coordinator::CoordinationUnitType Type() { return resource_coordinator::CoordinationUnitType::kSystem; }
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 1a67b58..eae4fee 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -551,9 +551,9 @@ RegisterUserProfilePrefs(pref_registry_.get()); SimpleDependencyManager::GetInstance()->RegisterProfilePrefsForServices( - key_.get(), pref_registry_.get()); + pref_registry_.get()); BrowserContextDependencyManager::GetInstance() - ->RegisterProfilePrefsForServices(this, pref_registry_.get()); + ->RegisterProfilePrefsForServices(pref_registry_.get()); SupervisedUserSettingsService* supervised_user_settings = nullptr; #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc index c57e844..15cdd8e 100644 --- a/chrome/browser/renderer_host/chrome_render_message_filter.cc +++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc
@@ -81,6 +81,8 @@ IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RequestFileSystemAccessAsync, OnRequestFileSystemAccessAsync) IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowIndexedDB, OnAllowIndexedDB) + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowCacheStorage, + OnAllowCacheStorage) #if BUILDFLAG(ENABLE_PLUGINS) IPC_MESSAGE_HANDLER(ChromeViewHostMsg_IsCrashReportingEnabled, OnIsCrashReportingEnabled) @@ -293,6 +295,19 @@ !*allowed)); } +void ChromeRenderMessageFilter::OnAllowCacheStorage(int render_frame_id, + const GURL& origin_url, + const GURL& top_origin_url, + bool* allowed) { + *allowed = + cookie_settings_->IsCookieAccessAllowed(origin_url, top_origin_url); + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&TabSpecificContentSettings::CacheStorageAccessed, + render_process_id_, render_frame_id, origin_url, + !*allowed)); +} + #if BUILDFLAG(ENABLE_PLUGINS) void ChromeRenderMessageFilter::OnIsCrashReportingEnabled(bool* enabled) { *enabled = ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled();
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.h b/chrome/browser/renderer_host/chrome_render_message_filter.h index 1b8b9c5..70c61e4 100644 --- a/chrome/browser/renderer_host/chrome_render_message_filter.h +++ b/chrome/browser/renderer_host/chrome_render_message_filter.h
@@ -93,6 +93,10 @@ const GURL& origin_url, const GURL& top_origin_url, bool* allowed); + void OnAllowCacheStorage(int render_frame_id, + const GURL& origin_url, + const GURL& top_origin_url, + bool* allowed); #if BUILDFLAG(ENABLE_PLUGINS) void OnIsCrashReportingEnabled(bool* enabled); #endif
diff --git a/chrome/browser/resources/policy/policy.css b/chrome/browser/resources/policy/policy.css index 025065d..aaaea1f7 100644 --- a/chrome/browser/resources/policy/policy.css +++ b/chrome/browser/resources/policy/policy.css
@@ -89,7 +89,7 @@ white-space: pre; } -<if expr="not android"> +<if expr="not is_android"> .messages.row .name, .conflict.row .name, .value.row .name { @@ -179,7 +179,7 @@ display: none; } -<if expr="android"> +<if expr="is_android"> body > main { padding: 0; }
diff --git a/chrome/browser/resources/policy/policy_base.js b/chrome/browser/resources/policy/policy_base.js index 06e59cc..f8ce952 100644 --- a/chrome/browser/resources/policy/policy_base.js +++ b/chrome/browser/resources/policy/policy_base.js
@@ -298,7 +298,6 @@ * @private */ toggleExpanded_: function() { - // <if expr="not android"> const row = this.parentElement.parentElement; const messageRowDisplay = row.querySelector('.messages.row'); const valueRowDisplay = row.querySelector('.value.row'); @@ -317,7 +316,6 @@ } row.querySelectorAll('.policy-conflict-data') .forEach(row => row.hidden = !row.hidden); - // </if> }, };
diff --git a/chrome/browser/resources/unpack_pak.py b/chrome/browser/resources/unpack_pak.py index 9199e49e..d73c71f 100755 --- a/chrome/browser/resources/unpack_pak.py +++ b/chrome/browser/resources/unpack_pak.py
@@ -4,6 +4,9 @@ # found in the LICENSE file. import argparse +import collections +import cStringIO +import gzip import os import re import sys @@ -20,9 +23,16 @@ sys.path.insert(1, os.path.join(_SRC_PATH, 'tools', 'grit')) from grit.format import data_pack +ResourceFile = collections.namedtuple('ResourceFile', + ['path', 'gzipped']) + +def UngzipString(data): + # Ungzipping using Python's built in gzip. + with gzip.GzipFile(fileobj=cStringIO.StringIO(data)) as gzip_file: + return gzip_file.read() def ParseLine(line): - return re.match(' {"([^"]+)", ([^},]+)', line) + return re.match(' {"([^"]+)", ([^},]+)(?:, ([^},]+))?', line) def Unpack(pak_path, out_path): @@ -43,23 +53,29 @@ assert resource_ids # Associate numerical string IDs to files. - resource_filenames = dict() + resource_files = dict() resources_map_path = os.path.join(pak_dir, 'grit', pak_id + '_map.cc') with open(resources_map_path) as resources_map: for line in resources_map: res = ParseLine(line) if res: - resource_filenames[res.group(2)] = res.group(1) - assert resource_filenames + resource_files[res.group(2)] = ResourceFile( + path=res.group(1), + gzipped=res.group(3) == 'true') + assert resource_files # Extract packed files, while preserving directory structure. for (resource_id, text) in data.resources.iteritems(): - filename = resource_filenames[resource_ids[resource_id]] - dirname = os.path.join(out_path, os.path.dirname(filename)) - if not os.path.exists(dirname): - os.makedirs(dirname) - with open(os.path.join(out_path, filename), 'w') as file: - file.write(text) + resource_file = resource_files[resource_ids[resource_id]] + file_path = resource_file.path + file_gzipped = resource_file.gzipped + file_dir = os.path.join(out_path, os.path.dirname(file_path)) + if not os.path.exists(file_dir): + os.makedirs(file_dir) + if file_gzipped: + text = UngzipString(text) + with open(os.path.join(out_path, file_path), 'w') as f: + f.write(text) def main():
diff --git a/chrome/browser/resources/unpack_pak_test.py b/chrome/browser/resources/unpack_pak_test.py index ca5b87a..cbec57a 100755 --- a/chrome/browser/resources/unpack_pak_test.py +++ b/chrome/browser/resources/unpack_pak_test.py
@@ -15,6 +15,13 @@ self.assertTrue(unpack_pak.ParseLine(' {"path.js", IDR_PATH, false}')) self.assertTrue(unpack_pak.ParseLine(' {"path.js", IDR_PATH, true}')) + def testUngzipString(self): + self.assertEqual( + unpack_pak.UngzipString( + '\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\xcbH\xcd\xc9\xc9W' + + '(\xcf/\xcaI\x01\x00\x85\x11J\r\x0b\x00\x00\x00'), + 'hello world') + if __name__ == '__main__': unittest.main()
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc index 5c9470e..defcbd10 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc
@@ -60,7 +60,7 @@ } GURL GetStableDownloadURL() { - const std::string url = base::win::OSInfo::GetInstance()->architecture() == + const std::string url = base::win::OSInfo::GetArchitecture() == base::win::OSInfo::X86_ARCHITECTURE ? kSRTX86StableDownloadURL : kSRTX64StableDownloadURL; @@ -74,7 +74,7 @@ if (download_group.empty()) return GetStableDownloadURL(); - std::string architecture = base::win::OSInfo::GetInstance()->architecture() == + std::string architecture = base::win::OSInfo::GetArchitecture() == base::win::OSInfo::X86_ARCHITECTURE ? "x86" : "x64";
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win_unittest.cc b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win_unittest.cc index e726903..3fbcb03a 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win_unittest.cc
@@ -36,7 +36,7 @@ TEST_F(SRTDownloadURLTest, Stable) { CreatePromptTrial("On"); std::string expected_path; - if (base::win::OSInfo::GetInstance()->architecture() == + if (base::win::OSInfo::GetArchitecture() == base::win::OSInfo::X86_ARCHITECTURE) { expected_path = "/dl/softwareremovaltool/win/x86/stable/chrome_cleanup_tool.exe"; @@ -50,7 +50,7 @@ TEST_F(SRTDownloadURLTest, Experiment) { CreateDownloadFeature("experiment"); std::string expected_path; - if (base::win::OSInfo::GetInstance()->architecture() == + if (base::win::OSInfo::GetArchitecture() == base::win::OSInfo::X86_ARCHITECTURE) { expected_path = "/dl/softwareremovaltool/win/x86/experiment/chrome_cleanup_tool.exe"; @@ -63,7 +63,7 @@ TEST_F(SRTDownloadURLTest, DefaultsToStable) { std::string expected_path; - if (base::win::OSInfo::GetInstance()->architecture() == + if (base::win::OSInfo::GetArchitecture() == base::win::OSInfo::X86_ARCHITECTURE) { expected_path = "/dl/softwareremovaltool/win/x86/stable/chrome_cleanup_tool.exe";
diff --git a/chrome/browser/security_events/BUILD.gn b/chrome/browser/security_events/BUILD.gn deleted file mode 100644 index 924a1db..0000000 --- a/chrome/browser/security_events/BUILD.gn +++ /dev/null
@@ -1,19 +0,0 @@ -# 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. - -static_library("security_events") { - sources = [ - "security_event_recorder.h", - "security_event_recorder_impl.cc", - "security_event_recorder_impl.h", - "security_event_sync_bridge.h", - "security_event_sync_bridge_impl.cc", - "security_event_sync_bridge_impl.h", - ] - - deps = [ - "//components/keyed_service/core", - "//components/sync", - ] -}
diff --git a/chrome/browser/security_events/security_event_recorder_factory.cc b/chrome/browser/security_events/security_event_recorder_factory.cc new file mode 100644 index 0000000..b24ade38 --- /dev/null +++ b/chrome/browser/security_events/security_event_recorder_factory.cc
@@ -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. + +#include "chrome/browser/security_events/security_event_recorder_factory.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/time/default_clock.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/security_events/security_event_recorder_impl.h" +#include "chrome/browser/security_events/security_event_sync_bridge.h" +#include "chrome/browser/security_events/security_event_sync_bridge_impl.h" +#include "chrome/browser/sync/model_type_store_service_factory.h" +#include "chrome/common/channel_info.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/sync/base/report_unrecoverable_error.h" +#include "components/sync/model/model_type_store_service.h" +#include "components/sync/model_impl/client_tag_based_model_type_processor.h" + +// static +SecurityEventRecorderFactory* SecurityEventRecorderFactory::GetInstance() { + return base::Singleton<SecurityEventRecorderFactory>::get(); +} + +// static +SecurityEventRecorder* SecurityEventRecorderFactory::GetForProfile( + Profile* profile) { + DCHECK(!profile->IsOffTheRecord()); + return static_cast<SecurityEventRecorder*>( + GetInstance()->GetServiceForBrowserContext(profile, true)); +} +SecurityEventRecorderFactory::SecurityEventRecorderFactory() + : BrowserContextKeyedServiceFactory( + "SecurityEventRecorder", + BrowserContextDependencyManager::GetInstance()) { + DependsOn(ModelTypeStoreServiceFactory::GetInstance()); +} + +SecurityEventRecorderFactory::~SecurityEventRecorderFactory() {} + +KeyedService* SecurityEventRecorderFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + Profile* profile = static_cast<Profile*>(context); + syncer::OnceModelTypeStoreFactory store_factory = + ModelTypeStoreServiceFactory::GetForProfile(profile)->GetStoreFactory(); + + auto change_processor = + std::make_unique<syncer::ClientTagBasedModelTypeProcessor>( + syncer::SECURITY_EVENTS, + base::BindRepeating(&syncer::ReportUnrecoverableError, + chrome::GetChannel())); + auto security_event_sync_bridge = + std::make_unique<SecurityEventSyncBridgeImpl>( + std::move(store_factory), std::move(change_processor)); + return new SecurityEventRecorderImpl(std::move(security_event_sync_bridge), + base::DefaultClock::GetInstance()); +}
diff --git a/chrome/browser/security_events/security_event_recorder_factory.h b/chrome/browser/security_events/security_event_recorder_factory.h new file mode 100644 index 0000000..7187342c --- /dev/null +++ b/chrome/browser/security_events/security_event_recorder_factory.h
@@ -0,0 +1,39 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SECURITY_EVENTS_SECURITY_EVENT_RECORDER_FACTORY_H_ +#define CHROME_BROWSER_SECURITY_EVENTS_SECURITY_EVENT_RECORDER_FACTORY_H_ + +#include "base/macros.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace base { +template <typename t> +struct DefaultSingletonTraits; +} + +class Profile; +class SecurityEventRecorder; + +class SecurityEventRecorderFactory : public BrowserContextKeyedServiceFactory { + public: + // Returns the singleton instance of SecurityEventRecorderFactory. + static SecurityEventRecorderFactory* GetInstance(); + + // Returns the SecurityEventRecorder associated with |profile|. + static SecurityEventRecorder* GetForProfile(Profile* profile); + + private: + friend struct base::DefaultSingletonTraits<SecurityEventRecorderFactory>; + + SecurityEventRecorderFactory(); + ~SecurityEventRecorderFactory() override; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + + DISALLOW_COPY_AND_ASSIGN(SecurityEventRecorderFactory); +}; +#endif // CHROME_BROWSER_SECURITY_EVENTS_SECURITY_EVENT_RECORDER_FACTORY_H_
diff --git a/chrome/browser/security_events/security_event_recorder_impl_unittest.cc b/chrome/browser/security_events/security_event_recorder_impl_unittest.cc new file mode 100644 index 0000000..02065420 --- /dev/null +++ b/chrome/browser/security_events/security_event_recorder_impl_unittest.cc
@@ -0,0 +1,68 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/security_events/security_event_recorder_impl.h" + +#include <memory> + +#include "base/time/default_clock.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class MockSecurityEventSyncBridge : public SecurityEventSyncBridge { + public: + MockSecurityEventSyncBridge() = default; + ~MockSecurityEventSyncBridge() override = default; + + MOCK_METHOD1(RecordSecurityEvent, void(sync_pb::SecurityEventSpecifics)); + MOCK_METHOD0(GetControllerDelegate, + base::WeakPtr<syncer::ModelTypeControllerDelegate>()); +}; + +MATCHER_P(HasTimestampAndContainsGaiaPasswordReuse, event, "") { + if (!arg.has_event_time_usec()) { + return false; + } + + if (arg.event_case() != + sync_pb::SecurityEventSpecifics::EventCase::kGaiaPasswordReuseEvent) { + return false; + } + + std::string actual_proto; + std::string expected_proto; + arg.gaia_password_reuse_event().SerializeToString(&actual_proto); + event.SerializeToString(&expected_proto); + return actual_proto == expected_proto; +} + +} // namespace + +class SecurityEventRecorderImplTest : public testing::Test {}; + +TEST_F(SecurityEventRecorderImplTest, RecordGaiaPasswordReuse) { + sync_pb::GaiaPasswordReuse expected_gaia_password_reuse_event; + expected_gaia_password_reuse_event.mutable_reuse_detected() + ->mutable_status() + ->set_enabled(false); + + auto mock_security_event_sync_bridge = + std::make_unique<MockSecurityEventSyncBridge>(); + EXPECT_CALL(*(mock_security_event_sync_bridge.get()), + RecordSecurityEvent(HasTimestampAndContainsGaiaPasswordReuse( + expected_gaia_password_reuse_event))); + + sync_pb::GaiaPasswordReuse gaia_password_reuse_event; + gaia_password_reuse_event.mutable_reuse_detected() + ->mutable_status() + ->set_enabled(false); + + auto security_event_recorder = std::make_unique<SecurityEventRecorderImpl>( + std::move(mock_security_event_sync_bridge), + base::DefaultClock::GetInstance()); + + security_event_recorder->RecordGaiaPasswordReuse(gaia_password_reuse_event); +}
diff --git a/chrome/browser/supervised_user/kids_management_url_checker_client.cc b/chrome/browser/supervised_user/kids_management_url_checker_client.cc new file mode 100644 index 0000000..184649e4 --- /dev/null +++ b/chrome/browser/supervised_user/kids_management_url_checker_client.cc
@@ -0,0 +1,328 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/supervised_user/kids_management_url_checker_client.h" + +#include <utility> + +#include "base/callback.h" +#include "base/feature_list.h" +#include "base/json/json_reader.h" +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "base/optional.h" +#include "base/stl_util.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/time/time.h" +#include "base/values.h" +#include "chrome/browser/supervised_user/supervised_user_constants.h" +#include "components/google/core/common/google_util.h" +#include "google_apis/google_api_keys.h" +#include "net/base/escape.h" +#include "net/base/load_flags.h" +#include "net/http/http_status_code.h" +#include "net/url_request/url_request_status.h" +#include "services/identity/public/cpp/primary_account_access_token_fetcher.h" +#include "services/identity/public/cpp/scope_set.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "url/url_constants.h" + +enum class KidsManagementClassification { kAllowed, kRestricted, kUnknown }; + +enum class KidsManagementResponseStatus { + kSuccess = 0, + kNetworkError = 1, + kUnexpectedClassificationValue = 2, + kParsingError = 3, + kTokenError = 4, + kHttpError = 5, + kMaxValue = kHttpError, +}; + +struct KidsManagementURLCheckerResponse { + public: + KidsManagementClassification classification; + KidsManagementResponseStatus status; + + static KidsManagementURLCheckerResponse ForSuccess( + KidsManagementClassification classification) { + return KidsManagementURLCheckerResponse( + KidsManagementResponseStatus::kSuccess, classification); + } + + static KidsManagementURLCheckerResponse ForFailure( + KidsManagementResponseStatus status) { + return KidsManagementURLCheckerResponse( + status, KidsManagementClassification::kUnknown); + } + + private: + KidsManagementURLCheckerResponse( + const KidsManagementResponseStatus& status, + const KidsManagementClassification& classification) + : classification(classification), status(status) {} +}; + +namespace { + +const char kClassifyUrlApiPath[] = + "https://kidsmanagement-pa.googleapis.com/kidsmanagement/v1/people/" + "me:classifyUrl"; + +const char kKidPermissionScope[] = + "https://www.googleapis.com/auth/kid.permission"; +const char kDataContentType[] = "application/x-www-form-urlencoded"; +const char kDataFormat[] = "url=%s®ion_code=%s"; +// Possible responses from KidsManagement ClassifyUrl RPC allowed and restricted +const char kAllowed[] = "allowed"; +const char kRestricted[] = "restricted"; + +// Builds the POST data for KidsManagement ClassifyURL requests. +std::string BuildRequestData(const GURL& url, const std::string& region_code) { + std::string query = net::EscapeQueryParamValue(url.spec(), true); + return base::StringPrintf(kDataFormat, query.c_str(), region_code.c_str()); +} + +// Parses a KidsManagement API |response| and returns the classification. +// On failure returns classification kUnknown and status with the reason for +// failure. +KidsManagementURLCheckerResponse ParseResponse(const std::string& response) { + base::Optional<base::Value> optional_value = base::JSONReader::Read(response); + const base::DictionaryValue* dict = nullptr; + if (!optional_value || !optional_value.value().GetAsDictionary(&dict)) { + DLOG(WARNING) << "ParseResponse failed to parse global dictionary"; + return KidsManagementURLCheckerResponse::ForFailure( + KidsManagementResponseStatus::kParsingError); + } + + const base::Value* classification_value = + dict->FindKey("displayClassification"); + if (!classification_value) { + DLOG(WARNING) << "ParseResponse failed to parse displayClassification"; + return KidsManagementURLCheckerResponse::ForFailure( + KidsManagementResponseStatus::kParsingError); + } + + const std::string classification_string = classification_value->GetString(); + if (classification_string == kAllowed) { + return KidsManagementURLCheckerResponse::ForSuccess( + KidsManagementClassification::kAllowed); + } else if (classification_string == kRestricted) { + return KidsManagementURLCheckerResponse::ForSuccess( + KidsManagementClassification::kRestricted); + } + DLOG(WARNING) << "ParseResponse expected a valid displayClassification"; + return KidsManagementURLCheckerResponse::ForFailure( + KidsManagementResponseStatus::kUnexpectedClassificationValue); +} + +safe_search_api::ClientClassification ToClientClassification( + const KidsManagementClassification& classification) { + switch (classification) { + case KidsManagementClassification::kAllowed: + return safe_search_api::ClientClassification::kAllowed; + case KidsManagementClassification::kRestricted: + return safe_search_api::ClientClassification::kRestricted; + case KidsManagementClassification::kUnknown: + return safe_search_api::ClientClassification::kUnknown; + } +} + +} // namespace + +struct KidsManagementURLCheckerClient::Check { + Check(const GURL& url, ClientCheckCallback callback); + ~Check(); + Check(Check&&) = default; + + GURL url; + std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher> + access_token_fetcher; + bool access_token_expired; + std::unique_ptr<network::SimpleURLLoader> simple_url_loader; + ClientCheckCallback callback; + base::TimeTicks start_time; +}; + +KidsManagementURLCheckerClient::Check::Check(const GURL& url, + ClientCheckCallback callback) + : url(url), + access_token_expired(false), + callback(std::move(callback)), + start_time(base::TimeTicks::Now()) {} + +KidsManagementURLCheckerClient::Check::~Check() { + DCHECK(!callback); +} + +KidsManagementURLCheckerClient::KidsManagementURLCheckerClient( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + const std::string& country, + identity::IdentityManager* identity_manager) + : url_loader_factory_(std::move(url_loader_factory)), + traffic_annotation_( + net::DefineNetworkTrafficAnnotation("kids_management_url_checker", R"( + semantics { + sender: "Supervised Users" + description: + "Checks whether a given URL (or set of URLs) is considered safe by " + "Google KidsManagement." + trigger: + "If the parent enabled this feature for the child account, this is " + "sent for every navigation." + data: "URL(s) to be checked." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: NO + setting: + "This feature is only used in child accounts and cannot be " + "disabled by settings. Parent accounts can disable it in the " + "family dashboard." + chrome_policy { + RestrictSigninToPattern { + policy_options {mode: MANDATORY} + RestrictSigninToPattern: "*@manageddomain.com" + } + } + })")), + country_(country), + identity_manager_(identity_manager) {} + +KidsManagementURLCheckerClient::~KidsManagementURLCheckerClient() = default; + +void KidsManagementURLCheckerClient::CheckURL(const GURL& url, + ClientCheckCallback callback) { + checks_in_progress_.push_front( + std::make_unique<Check>(url, std::move(callback))); + + StartFetching(checks_in_progress_.begin()); +} + +void KidsManagementURLCheckerClient::StartFetching(CheckList::iterator it) { + identity::ScopeSet scopes{kKidPermissionScope}; + // It is safe to use Unretained(this) here given that the callback + // will not be invoked if this object is deleted. Likewise, |it| + // only comes from |checks_in_progress_|, which are owned by this object + // too. + it->get()->access_token_fetcher = + std::make_unique<identity::PrimaryAccountAccessTokenFetcher>( + "kids_url_classifier", identity_manager_, scopes, + base::BindOnce( + &KidsManagementURLCheckerClient::OnAccessTokenFetchComplete, + base::Unretained(this), it), + identity::PrimaryAccountAccessTokenFetcher::Mode::kImmediate); +} + +void KidsManagementURLCheckerClient::OnAccessTokenFetchComplete( + CheckList::iterator it, + GoogleServiceAuthError error, + identity::AccessTokenInfo token_info) { + if (error.state() != GoogleServiceAuthError::NONE) { + DLOG(WARNING) << "Token error: " << error.ToString(); + + DispatchResult(it, KidsManagementURLCheckerResponse::ForFailure( + KidsManagementResponseStatus::kTokenError)); + return; + } + Check* check = it->get(); + + DVLOG(1) << "Checking URL " << check->url; + auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->url = GURL(kClassifyUrlApiPath); + resource_request->method = "POST"; + resource_request->load_flags = + net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES; + resource_request->headers.SetHeader( + net::HttpRequestHeaders::kAuthorization, + base::StringPrintf(supervised_users::kAuthorizationHeaderFormat, + token_info.token.c_str())); + check->simple_url_loader = network::SimpleURLLoader::Create( + std::move(resource_request), traffic_annotation_); + check->simple_url_loader->AttachStringForUpload( + BuildRequestData(check->url, country_), kDataContentType); + + check->simple_url_loader->DownloadToString( + url_loader_factory_.get(), + base::BindOnce(&KidsManagementURLCheckerClient::OnSimpleLoaderComplete, + base::Unretained(this), it, token_info), + /*max_body_size*/ 128); +} + +void KidsManagementURLCheckerClient::OnSimpleLoaderComplete( + CheckList::iterator it, + identity::AccessTokenInfo token_info, + std::unique_ptr<std::string> response_body) { + Check* check = it->get(); + std::unique_ptr<network::SimpleURLLoader> simple_url_loader = + std::move(check->simple_url_loader); + int response_code = -1; + if (simple_url_loader->ResponseInfo() && + simple_url_loader->ResponseInfo()->headers) { + response_code = simple_url_loader->ResponseInfo()->headers->response_code(); + } + + // Handle first HTTP_UNAUTHORIZED response by removing access token and + // restarting the request from the beginning (fetching access token). + if (response_code == net::HTTP_UNAUTHORIZED && !check->access_token_expired) { + DLOG(WARNING) << "Access token expired:\n" << token_info.token; + check->access_token_expired = true; + identity::ScopeSet scopes{kKidPermissionScope}; + identity_manager_->RemoveAccessTokenFromCache( + identity_manager_->GetPrimaryAccountId(), scopes, token_info.token); + StartFetching(it); + return; + } + + int net_error = simple_url_loader->NetError(); + if (net_error != net::OK) { + DLOG(WARNING) << "Network error " << net_error; + DispatchResult(it, KidsManagementURLCheckerResponse::ForFailure( + KidsManagementResponseStatus::kNetworkError)); + return; + } + + if (response_code != net::HTTP_OK) { + DLOG(WARNING) << "HTTP error " << response_code; + DLOG(WARNING) << "Response: " << response_body.get(); + DispatchResult(it, KidsManagementURLCheckerResponse::ForFailure( + KidsManagementResponseStatus::kHttpError)); + return; + } + + // |response_body| is nullptr only in case of failure + if (!response_body) { + DLOG(WARNING) << "URL request failed! Letting through..."; + DispatchResult(it, KidsManagementURLCheckerResponse::ForFailure( + KidsManagementResponseStatus::kNetworkError)); + return; + } + + DispatchResult(it, ParseResponse(*response_body)); +} + +void KidsManagementURLCheckerClient::DispatchResult( + CheckList::iterator it, + KidsManagementURLCheckerResponse response) { + if (response.status == KidsManagementResponseStatus::kSuccess) { + UMA_HISTOGRAM_TIMES("ManagedUsers.KidsManagementClassifyUrlSuccessDelay", + base::TimeTicks::Now() - it->get()->start_time); + } else { + UMA_HISTOGRAM_TIMES("ManagedUsers.KidsManagementClassifyUrlFailureDelay", + base::TimeTicks::Now() - it->get()->start_time); + } + + UMA_HISTOGRAM_ENUMERATION( + "ManagedUsers.KidsManagementUrlCheckerResponseStatus", response.status); + + safe_search_api::ClientClassification api_classification = + ToClientClassification(response.classification); + std::move(it->get()->callback).Run(it->get()->url, api_classification); + + checks_in_progress_.erase(it); +}
diff --git a/chrome/browser/supervised_user/kids_management_url_checker_client.h b/chrome/browser/supervised_user/kids_management_url_checker_client.h new file mode 100644 index 0000000..3c7bb1a --- /dev/null +++ b/chrome/browser/supervised_user/kids_management_url_checker_client.h
@@ -0,0 +1,80 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SUPERVISED_USER_KIDS_MANAGEMENT_URL_CHECKER_CLIENT_H_ +#define CHROME_BROWSER_SUPERVISED_USER_KIDS_MANAGEMENT_URL_CHECKER_CLIENT_H_ + +#include <list> +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "components/safe_search_api/url_checker_client.h" +#include "google_apis/gaia/google_service_auth_error.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "url/gurl.h" + +namespace network { +class SharedURLLoaderFactory; +} // namespace network + +namespace identity { +class IdentityManager; +struct AccessTokenInfo; +} // namespace identity + +struct KidsManagementURLCheckerResponse; + +// This class uses the KidsManagement ClassifyUrl to check the classification +// of the content on a given URL and returns the result asynchronously +// via a callback. +class KidsManagementURLCheckerClient + : public safe_search_api::URLCheckerClient { + public: + // |country| should be a two-letter country code (ISO 3166-1 alpha-2), e.g., + // "us". + KidsManagementURLCheckerClient( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + const std::string& country, + identity::IdentityManager* identity_manager); + ~KidsManagementURLCheckerClient() override; + + // Checks whether an |url| is restricted according to KidsManagement + // ClassifyUrl RPC. + // + // On failure, the |callback| function is called with |url| as the first + // parameter, and UNKNOWN as the second. + void CheckURL(const GURL& url, ClientCheckCallback callback) override; + + private: + struct Check; + + // Must be list so that iterators stay valid until they are erased. + using CheckList = std::list<std::unique_ptr<Check>>; + + void StartFetching(CheckList::iterator it); + + void OnAccessTokenFetchComplete(CheckList::iterator it, + GoogleServiceAuthError error, + identity::AccessTokenInfo token_info); + + void OnSimpleLoaderComplete(CheckList::iterator it, + identity::AccessTokenInfo token_info, + std::unique_ptr<std::string> response_body); + + void DispatchResult(CheckList::iterator it, + KidsManagementURLCheckerResponse response); + + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; + const net::NetworkTrafficAnnotationTag traffic_annotation_; + const std::string country_; + identity::IdentityManager* identity_manager_; + + CheckList checks_in_progress_; + + DISALLOW_COPY_AND_ASSIGN(KidsManagementURLCheckerClient); +}; + +#endif // CHROME_BROWSER_SUPERVISED_USER_KIDS_MANAGEMENT_URL_CHECKER_CLIENT_H_
diff --git a/chrome/browser/supervised_user/kids_management_url_checker_client_unittest.cc b/chrome/browser/supervised_user/kids_management_url_checker_client_unittest.cc new file mode 100644 index 0000000..c6c658b --- /dev/null +++ b/chrome/browser/supervised_user/kids_management_url_checker_client_unittest.cc
@@ -0,0 +1,164 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/supervised_user/kids_management_url_checker_client.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/json/json_writer.h" +#include "base/message_loop/message_loop.h" +#include "base/test/scoped_feature_list.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/values.h" +#include "net/http/http_status_code.h" +#include "services/identity/public/cpp/identity_test_environment.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +const char kClassifyUrlApiPath[] = + "https://kidsmanagement-pa.googleapis.com/kidsmanagement/v1/people/" + "me:classifyUrl"; + +const char kEmail[] = "account@gmail.com"; + +std::string ClassificationToString( + safe_search_api::ClientClassification classification) { + switch (classification) { + case safe_search_api::ClientClassification::kAllowed: + return "allowed"; + case safe_search_api::ClientClassification::kRestricted: + return "restricted"; + case safe_search_api::ClientClassification::kUnknown: + return std::string(); + } +} + +// Build fake JSON string with a response according to |classification|. +std::string BuildResponse( + safe_search_api::ClientClassification classification) { + base::DictionaryValue dict; + dict.SetKey("displayClassification", + base::Value(ClassificationToString(classification))); + std::string result; + base::JSONWriter::Write(dict, &result); + return result; +} + +} // namespace + +class KidsManagementURLCheckerClientTest : public testing::Test { + public: + KidsManagementURLCheckerClientTest() + : test_shared_loader_factory_( + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_)) { + AccountInfo account_info = + identity_test_env_.MakePrimaryAccountAvailable(kEmail); + account_id_ = account_info.account_id; + url_classifier_ = std::make_unique<KidsManagementURLCheckerClient>( + test_shared_loader_factory_, std::string(), + identity_test_env_.identity_manager()); + } + + protected: + void IssueAccessTokens() { + identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( + account_id_, "access_token", + /*expiration_time*/ base::Time::Now() + base::TimeDelta::FromHours(1)); + } + + void IssueAccessTokenErrors() { + identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithError( + account_id_, GoogleServiceAuthError::FromServiceError("Error!")); + } + + void SetupResponse(net::HttpStatusCode status, const std::string& response) { + test_url_loader_factory_.AddResponse(kClassifyUrlApiPath, response, status); + } + + void CheckURL(const GURL& url) { + url_classifier_->CheckURL( + url, base::BindOnce(&KidsManagementURLCheckerClientTest::OnCheckDone, + base::Unretained(this))); + } + + void CheckURLWithResponse( + const GURL& url, + const safe_search_api::ClientClassification classification) { + CheckURL(url); + SetupResponse(net::HTTP_OK, BuildResponse(classification)); + + IssueAccessTokens(); + WaitForResponse(); + } + + // Only use this if setting response manually. CheckURLWithResponse already + // uses this. + void WaitForResponse() { base::RunLoop().RunUntilIdle(); } + + MOCK_METHOD2(OnCheckDone, + void(const GURL& url, + safe_search_api::ClientClassification classification)); + + base::MessageLoop message_loop_; + std::string account_id_; + identity::IdentityTestEnvironment identity_test_env_; + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; + std::unique_ptr<KidsManagementURLCheckerClient> url_classifier_; +}; + +TEST_F(KidsManagementURLCheckerClientTest, Simple) { + { + GURL url("http://randomurl1.com"); + + safe_search_api::ClientClassification classification = + safe_search_api::ClientClassification::kAllowed; + + EXPECT_CALL(*this, OnCheckDone(url, classification)); + + CheckURLWithResponse(url, classification); + } + { + GURL url("http://randomurl2.com"); + + safe_search_api::ClientClassification classification = + safe_search_api::ClientClassification::kRestricted; + + EXPECT_CALL(*this, OnCheckDone(url, classification)); + + CheckURLWithResponse(url, classification); + } +} + +TEST_F(KidsManagementURLCheckerClientTest, AccessTokenError) { + GURL url("http://randomurl.com"); + + // Our callback should get called immediately on an error. + EXPECT_CALL( + *this, OnCheckDone(url, safe_search_api::ClientClassification::kUnknown)); + CheckURL(url); + IssueAccessTokenErrors(); +} + +TEST_F(KidsManagementURLCheckerClientTest, NetworkError) { + GURL url("http://randomurl.com"); + CheckURL(url); + + IssueAccessTokens(); + + // Our callback should get called on an error. + EXPECT_CALL( + *this, OnCheckDone(url, safe_search_api::ClientClassification::kUnknown)); + + SetupResponse(net::HTTP_FORBIDDEN, std::string()); + WaitForResponse(); +}
diff --git a/chrome/browser/sync/sync_error_notifier_ash_unittest.cc b/chrome/browser/sync/sync_error_notifier_ash_unittest.cc index 191e078..68359ab 100644 --- a/chrome/browser/sync/sync_error_notifier_ash_unittest.cc +++ b/chrome/browser/sync/sync_error_notifier_ash_unittest.cc
@@ -4,30 +4,20 @@ #include "chrome/browser/sync/sync_error_notifier_ash.h" -#include <stddef.h> - #include <memory> #include "base/bind.h" -#include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/login/users/mock_user_manager.h" #include "chrome/browser/notifications/notification_display_service_tester.h" -#include "chrome/browser/sync/profile_sync_test_util.h" #include "chrome/browser/sync/sync_ui_util.h" -#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/test/base/browser_with_test_window_test.h" -#include "components/browser_sync/profile_sync_service_mock.h" +#include "components/sync/driver/test_sync_service.h" #include "components/user_manager/scoped_user_manager.h" -#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/message_center/public/cpp/notification.h" -using ::testing::NiceMock; -using ::testing::Return; -using ::testing::_; - namespace { // Notification ID corresponding to kProfileSyncNotificationId + the test @@ -37,25 +27,18 @@ class FakeLoginUIService: public LoginUIService { public: FakeLoginUIService() : LoginUIService(nullptr) {} - ~FakeLoginUIService() override {} + ~FakeLoginUIService() override = default; }; class FakeLoginUI : public LoginUIService::LoginUI { public: - FakeLoginUI() : focus_ui_call_count_(0) {} + FakeLoginUI() = default; + ~FakeLoginUI() override = default; - ~FakeLoginUI() override {} - - int focus_ui_call_count() const { return focus_ui_call_count_; } - - private: - // LoginUIService::LoginUI: - void FocusUI() override { ++focus_ui_call_count_; } - - int focus_ui_call_count_; + void FocusUI() override {} }; -std::unique_ptr<KeyedService> BuildMockLoginUIService( +std::unique_ptr<KeyedService> BuildFakeLoginUIService( content::BrowserContext* profile) { return std::make_unique<FakeLoginUIService>(); } @@ -68,16 +51,12 @@ void SetUp() override { BrowserWithTestWindowTest::SetUp(); - service_ = std::make_unique<NiceMock<browser_sync::ProfileSyncServiceMock>>( - CreateProfileSyncServiceParamsForTest(profile())); - FakeLoginUIService* login_ui_service = static_cast<FakeLoginUIService*>( LoginUIServiceFactory::GetInstance()->SetTestingFactoryAndUse( - profile(), base::BindRepeating(&BuildMockLoginUIService))); + profile(), base::BindRepeating(&BuildFakeLoginUIService))); login_ui_service->SetLoginUI(&login_ui_); - error_notifier_ = - std::make_unique<SyncErrorNotifier>(service_.get(), profile()); + error_notifier_ = std::make_unique<SyncErrorNotifier>(&service_, profile()); display_service_ = std::make_unique<NotificationDisplayServiceTester>(profile()); @@ -85,7 +64,6 @@ void TearDown() override { error_notifier_->Shutdown(); - service_.reset(); BrowserWithTestWindowTest::TearDown(); } @@ -97,15 +75,11 @@ bool is_signed_in, bool is_error, bool expected_notification) { - ON_CALL(*service_->GetUserSettingsMock(), IsFirstSetupComplete()) - .WillByDefault(Return(is_signed_in)); + service_.SetFirstSetupComplete(is_signed_in); + service_.SetAuthError(GoogleServiceAuthError(error_state)); + ASSERT_EQ(is_error, sync_ui_util::ShouldShowPassphraseError(&service_)); - ON_CALL(*service_, GetAuthError()) - .WillByDefault(Return(GoogleServiceAuthError(error_state))); - ASSERT_EQ(is_error, - sync_ui_util::ShouldShowPassphraseError(service_.get())); - - error_notifier_->OnStateChanged(service_.get()); + error_notifier_->OnStateChanged(&service_); base::Optional<message_center::Notification> notification = display_service_->GetNotification(kNotificationId); @@ -119,7 +93,7 @@ } std::unique_ptr<SyncErrorNotifier> error_notifier_; - std::unique_ptr<browser_sync::ProfileSyncServiceMock> service_; + syncer::TestSyncService service_; FakeLoginUI login_ui_; std::unique_ptr<NotificationDisplayServiceTester> display_service_; @@ -134,12 +108,8 @@ std::make_unique<chromeos::MockUserManager>()); ASSERT_FALSE(display_service_->GetNotification(kNotificationId)); - ON_CALL(*service_, QueryDetailedSyncStatus(_)).WillByDefault(Return(false)); - - ON_CALL(*service_->GetUserSettingsMock(), IsPassphraseRequired()) - .WillByDefault(Return(true)); - ON_CALL(*service_->GetUserSettingsMock(), IsPassphraseRequiredForDecryption()) - .WillByDefault(Return(true)); + service_.SetPassphraseRequired(true); + service_.SetPassphraseRequiredForDecryption(true); { SCOPED_TRACE("Expected a notification for passphrase error"); VerifySyncErrorNotifierResult(GoogleServiceAuthError::NONE, @@ -158,10 +128,8 @@ } // Check that no notification is shown if there is no error. - ON_CALL(*service_->GetUserSettingsMock(), IsPassphraseRequired()) - .WillByDefault(Return(false)); - ON_CALL(*service_->GetUserSettingsMock(), IsPassphraseRequiredForDecryption()) - .WillByDefault(Return(false)); + service_.SetPassphraseRequired(false); + service_.SetPassphraseRequiredForDecryption(false); { SCOPED_TRACE("Not expecting notification since no error exists"); VerifySyncErrorNotifierResult(GoogleServiceAuthError::NONE, @@ -170,10 +138,8 @@ } // Check that no notification is shown if sync setup is not completed. - ON_CALL(*service_->GetUserSettingsMock(), IsPassphraseRequired()) - .WillByDefault(Return(true)); - ON_CALL(*service_->GetUserSettingsMock(), IsPassphraseRequiredForDecryption()) - .WillByDefault(Return(true)); + service_.SetPassphraseRequired(true); + service_.SetPassphraseRequiredForDecryption(true); { SCOPED_TRACE("Not expecting notification since sync setup is incomplete"); VerifySyncErrorNotifierResult(
diff --git a/chrome/browser/sync/sync_startup_tracker_unittest.cc b/chrome/browser/sync/sync_startup_tracker_unittest.cc index 81e44d0..e7206bb 100644 --- a/chrome/browser/sync/sync_startup_tracker_unittest.cc +++ b/chrome/browser/sync/sync_startup_tracker_unittest.cc
@@ -4,20 +4,12 @@ #include "chrome/browser/sync/sync_startup_tracker.h" -#include <memory> - -#include "base/bind.h" -#include "chrome/browser/sync/profile_sync_test_util.h" -#include "chrome/test/base/testing_profile.h" -#include "components/browser_sync/profile_sync_service_mock.h" -#include "content/public/test/test_browser_thread_bundle.h" +#include "components/sync/driver/test_sync_service.h" #include "google_apis/gaia/google_service_auth_error.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using ::testing::Mock; -using ::testing::NiceMock; -using ::testing::Return; namespace { @@ -31,70 +23,44 @@ public: SyncStartupTrackerTest() {} - void SetUp() override { - profile_ = std::make_unique<TestingProfile>(); - mock_pss_ = - std::make_unique<NiceMock<browser_sync::ProfileSyncServiceMock>>( - CreateProfileSyncServiceParamsForTest(profile_.get())); - - ON_CALL(*mock_pss_, GetRegisteredDataTypes()) - .WillByDefault(Return(syncer::ModelTypeSet())); - mock_pss_->Initialize(); - } - - void TearDown() override { - mock_pss_->Shutdown(); - mock_pss_.reset(); - profile_.reset(); - } - void SetupNonInitializedPSS() { - ON_CALL(*mock_pss_, GetDisableReasons()) - .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE)); - ON_CALL(*mock_pss_, GetTransportState()) - .WillByDefault( - Return(syncer::SyncService::TransportState::INITIALIZING)); + sync_service_.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE); + sync_service_.SetTransportState( + syncer::SyncService::TransportState::INITIALIZING); } - content::TestBrowserThreadBundle thread_bundle_; - std::unique_ptr<TestingProfile> profile_; - // TODO(crbug.com/910518): Rewrite these tests in terms of TestSyncService. - std::unique_ptr<browser_sync::ProfileSyncServiceMock> mock_pss_; + syncer::TestSyncService sync_service_; MockObserver observer_; }; TEST_F(SyncStartupTrackerTest, SyncAlreadyInitialized) { - ON_CALL(*mock_pss_, GetDisableReasons()) - .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE)); - ON_CALL(*mock_pss_, GetTransportState()) - .WillByDefault(Return(syncer::SyncService::TransportState::ACTIVE)); + sync_service_.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE); + sync_service_.SetTransportState(syncer::SyncService::TransportState::ACTIVE); EXPECT_CALL(observer_, SyncStartupCompleted()); - SyncStartupTracker tracker(mock_pss_.get(), &observer_); + SyncStartupTracker tracker(&sync_service_, &observer_); } TEST_F(SyncStartupTrackerTest, SyncNotSignedIn) { // Make sure that we get a SyncStartupFailed() callback if sync is not logged // in. - ON_CALL(*mock_pss_, GetDisableReasons()) - .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN)); - ON_CALL(*mock_pss_, GetTransportState()) - .WillByDefault(Return(syncer::SyncService::TransportState::DISABLED)); + sync_service_.SetDisableReasons( + syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN); + sync_service_.SetTransportState( + syncer::SyncService::TransportState::DISABLED); EXPECT_CALL(observer_, SyncStartupFailed()); - SyncStartupTracker tracker(mock_pss_.get(), &observer_); + SyncStartupTracker tracker(&sync_service_, &observer_); } TEST_F(SyncStartupTrackerTest, SyncAuthError) { // Make sure that we get a SyncStartupFailed() callback if sync gets an auth // error. - ON_CALL(*mock_pss_, GetDisableReasons()) - .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE)); - ON_CALL(*mock_pss_, GetTransportState()) - .WillByDefault(Return(syncer::SyncService::TransportState::INITIALIZING)); - ON_CALL(*mock_pss_, GetAuthError()) - .WillByDefault(Return(GoogleServiceAuthError( - GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS))); + sync_service_.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE); + sync_service_.SetTransportState( + syncer::SyncService::TransportState::INITIALIZING); + sync_service_.SetAuthError( + GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); EXPECT_CALL(observer_, SyncStartupFailed()); - SyncStartupTracker tracker(mock_pss_.get(), &observer_); + SyncStartupTracker tracker(&sync_service_, &observer_); } TEST_F(SyncStartupTrackerTest, SyncDelayedInitialization) { @@ -102,13 +68,12 @@ SetupNonInitializedPSS(); EXPECT_CALL(observer_, SyncStartupCompleted()).Times(0); EXPECT_CALL(observer_, SyncStartupFailed()).Times(0); - SyncStartupTracker tracker(mock_pss_.get(), &observer_); + SyncStartupTracker tracker(&sync_service_, &observer_); Mock::VerifyAndClearExpectations(&observer_); // Now, mark the PSS as initialized. - ON_CALL(*mock_pss_, GetTransportState()) - .WillByDefault(Return(syncer::SyncService::TransportState::ACTIVE)); + sync_service_.SetTransportState(syncer::SyncService::TransportState::ACTIVE); EXPECT_CALL(observer_, SyncStartupCompleted()); - tracker.OnStateChanged(mock_pss_.get()); + tracker.OnStateChanged(&sync_service_); } TEST_F(SyncStartupTrackerTest, SyncDelayedAuthError) { @@ -116,20 +81,18 @@ SetupNonInitializedPSS(); EXPECT_CALL(observer_, SyncStartupCompleted()).Times(0); EXPECT_CALL(observer_, SyncStartupFailed()).Times(0); - SyncStartupTracker tracker(mock_pss_.get(), &observer_); + SyncStartupTracker tracker(&sync_service_, &observer_); Mock::VerifyAndClearExpectations(&observer_); - Mock::VerifyAndClearExpectations(mock_pss_.get()); + Mock::VerifyAndClearExpectations(&sync_service_); // Now, mark the PSS as having an auth error. - ON_CALL(*mock_pss_, GetDisableReasons()) - .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE)); - ON_CALL(*mock_pss_, GetTransportState()) - .WillByDefault(Return(syncer::SyncService::TransportState::INITIALIZING)); - ON_CALL(*mock_pss_, GetAuthError()) - .WillByDefault(Return(GoogleServiceAuthError( - GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS))); + sync_service_.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE); + sync_service_.SetTransportState( + syncer::SyncService::TransportState::INITIALIZING); + sync_service_.SetAuthError( + GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); EXPECT_CALL(observer_, SyncStartupFailed()); - tracker.OnStateChanged(mock_pss_.get()); + tracker.OnStateChanged(&sync_service_); } TEST_F(SyncStartupTrackerTest, SyncDelayedUnrecoverableError) { @@ -137,18 +100,17 @@ SetupNonInitializedPSS(); EXPECT_CALL(observer_, SyncStartupCompleted()).Times(0); EXPECT_CALL(observer_, SyncStartupFailed()).Times(0); - SyncStartupTracker tracker(mock_pss_.get(), &observer_); + SyncStartupTracker tracker(&sync_service_, &observer_); Mock::VerifyAndClearExpectations(&observer_); - Mock::VerifyAndClearExpectations(mock_pss_.get()); + Mock::VerifyAndClearExpectations(&sync_service_); // Now, mark the PSS as having an unrecoverable error. - ON_CALL(*mock_pss_, GetDisableReasons()) - .WillByDefault( - Return(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR)); - ON_CALL(*mock_pss_, GetTransportState()) - .WillByDefault(Return(syncer::SyncService::TransportState::DISABLED)); + sync_service_.SetDisableReasons( + syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR); + sync_service_.SetTransportState( + syncer::SyncService::TransportState::DISABLED); EXPECT_CALL(observer_, SyncStartupFailed()); - tracker.OnStateChanged(mock_pss_.get()); + tracker.OnStateChanged(&sync_service_); } } // namespace
diff --git a/chrome/browser/sync/sync_ui_util.cc b/chrome/browser/sync/sync_ui_util.cc index da03c3d..a4e82d3 100644 --- a/chrome/browser/sync/sync_ui_util.cc +++ b/chrome/browser/sync/sync_ui_util.cc
@@ -261,6 +261,10 @@ DCHECK(profile); syncer::SyncService* service = ProfileSyncServiceFactory::GetForProfile(profile); + if (!service) { + // This can happen if Sync is disabled via the command line. + return PRE_SYNCED; + } const bool is_user_signout_allowed = signin_util::IsUserSignoutAllowedForProfile(profile); GoogleServiceAuthError auth_error =
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 6608f22a..7f1ee9d 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -454,8 +454,8 @@ password_manager::ContentPasswordManagerDriver::GetForRenderFrameHost( rfh); if (driver) { - driver->GetPasswordGenerationManager()->ProcessPasswordRequirements(forms); - driver->GetPasswordGenerationManager()->DetectFormsEligibleForGeneration( + driver->GetPasswordGenerationHelper()->ProcessPasswordRequirements(forms); + driver->GetPasswordGenerationHelper()->DetectFormsEligibleForGeneration( forms); driver->GetPasswordManager()->ProcessAutofillPredictions(driver, forms); }
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc index 8a4ebd8..5d9921dc3 100644 --- a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc +++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
@@ -17,10 +17,8 @@ #include "base/test/simple_test_clock.h" #include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/sync/profile_sync_test_util.h" #include "chrome/browser/ui/passwords/passwords_model_delegate_mock.h" #include "chrome/test/base/testing_profile.h" -#include "components/browser_sync/profile_sync_service_mock.h" #include "components/password_manager/core/browser/mock_password_store.h" #include "components/password_manager/core/browser/password_form_metrics_recorder.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" @@ -31,6 +29,7 @@ #include "components/password_manager/core/common/password_manager_ui.h" #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_info.h" +#include "components/sync/driver/test_sync_service.h" #include "components/ukm/test_ukm_recorder.h" #include "content/public/browser/web_contents.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -41,9 +40,6 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -using ::testing::AnyNumber; -using ::testing::Contains; -using ::testing::Not; using ::testing::Return; using ::testing::ReturnRef; using ::testing::_; @@ -73,48 +69,11 @@ constexpr char kUIDismissalReasonUpdateMetric[] = "PasswordManager.UpdateUIDismissalReason"; -class TestSyncService : public browser_sync::ProfileSyncServiceMock { - public: - enum class SyncedTypes { ALL, NONE }; - - explicit TestSyncService(Profile* profile) - : browser_sync::ProfileSyncServiceMock( - CreateProfileSyncServiceParamsForTest(profile)), - synced_types_(SyncedTypes::NONE) {} - ~TestSyncService() override {} - - // FakeSyncService: - int GetDisableReasons() const override { return DISABLE_REASON_NONE; } - TransportState GetTransportState() const override { - return TransportState::ACTIVE; - } - syncer::ModelTypeSet GetActiveDataTypes() const override { - switch (synced_types_) { - case SyncedTypes::ALL: - return syncer::ModelTypeSet::All(); - case SyncedTypes::NONE: - return syncer::ModelTypeSet(); - } - NOTREACHED(); - return syncer::ModelTypeSet(); - } - syncer::ModelTypeSet GetPreferredDataTypes() const override { - return GetActiveDataTypes(); - } - - void set_synced_types(SyncedTypes synced_types) { - synced_types_ = synced_types; - } - - private: - SyncedTypes synced_types_; - - DISALLOW_COPY_AND_ASSIGN(TestSyncService); -}; +enum class SyncedTypes { ALL, NONE }; std::unique_ptr<KeyedService> TestingSyncFactoryFunction( content::BrowserContext* context) { - return std::make_unique<TestSyncService>(static_cast<Profile*>(context)); + return std::make_unique<syncer::TestSyncService>(); } MATCHER_P(AccountEq, expected, "") { @@ -545,13 +504,18 @@ class ManagePasswordsBubbleModelManageLinkTest : public ManagePasswordsBubbleModelTest, - public ::testing::WithParamInterface<TestSyncService::SyncedTypes> {}; + public ::testing::WithParamInterface<SyncedTypes> {}; TEST_P(ManagePasswordsBubbleModelManageLinkTest, OnManageClicked) { - TestSyncService* sync_service = static_cast<TestSyncService*>( + syncer::TestSyncService* sync_service = static_cast<syncer::TestSyncService*>( ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( profile(), base::BindRepeating(&TestingSyncFactoryFunction))); - sync_service->set_synced_types(GetParam()); + syncer::ModelTypeSet types; + if (GetParam() == SyncedTypes::ALL) { + types = syncer::ModelTypeSet::All(); + } + sync_service->SetPreferredDataTypes(types); + sync_service->SetActiveDataTypes(types); PretendManagingPasswords(); @@ -566,8 +530,8 @@ INSTANTIATE_TEST_SUITE_P(Default, ManagePasswordsBubbleModelManageLinkTest, - ::testing::Values(TestSyncService::SyncedTypes::ALL, - TestSyncService::SyncedTypes::NONE)); + ::testing::Values(SyncedTypes::ALL, + SyncedTypes::NONE)); // Verify that URL keyed metrics are properly recorded. TEST_F(ManagePasswordsBubbleModelTest, RecordUKMs) {
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller.h b/chrome/browser/ui/passwords/password_generation_popup_controller.h index 1716633..d03a80606 100644 --- a/chrome/browser/ui/passwords/password_generation_popup_controller.h +++ b/chrome/browser/ui/passwords/password_generation_popup_controller.h
@@ -11,7 +11,7 @@ class PasswordGenerationPopupController : public autofill::AutofillPopupViewDelegate { public: - enum GenerationState { + enum GenerationUIState { // Generated password is offered in the popup but not filled yet. kOfferGeneration, // The generated password was accepted. @@ -22,7 +22,7 @@ virtual void PasswordAccepted() = 0; // Accessors - virtual GenerationState state() const = 0; + virtual GenerationUIState state() const = 0; virtual bool password_selected() const = 0; virtual const base::string16& password() const = 0;
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc index 2ff4740..16f6f21 100644 --- a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc +++ b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc
@@ -28,7 +28,7 @@ #include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/browser/suggestion.h" #include "components/password_manager/core/browser/password_bubble_experiment.h" -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/password_manager/core/browser/password_generation_frame_helper.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "components/strings/grit/components_strings.h" @@ -152,13 +152,13 @@ Hide(); } -void PasswordGenerationPopupControllerImpl::Show(GenerationState state) { +void PasswordGenerationPopupControllerImpl::Show(GenerationUIState state) { // When switching from editing to generation state, regenerate the password. if (state == kOfferGeneration && (state_ != state || current_password_.empty())) { uint32_t spec_priority = 0; current_password_ = - driver_->GetPasswordGenerationManager()->GeneratePassword( + driver_->GetPasswordGenerationHelper()->GeneratePassword( web_contents_->GetLastCommittedURL().GetOrigin(), form_signature_, field_signature_, max_length_, &spec_priority); if (driver_ && driver_->GetPasswordManager()) { @@ -281,7 +281,7 @@ } #endif -PasswordGenerationPopupController::GenerationState +PasswordGenerationPopupController::GenerationUIState PasswordGenerationPopupControllerImpl::state() const { return state_; }
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h index d94b750..c7c6c3e 100644 --- a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h +++ b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h
@@ -69,7 +69,7 @@ ~PasswordGenerationPopupControllerImpl() override; // Create a PasswordGenerationPopupView if one doesn't already exist. - void Show(GenerationState state); + void Show(GenerationUIState state); // Update the password to be displayed in the UI. void UpdatePassword(base::string16 new_password); @@ -111,7 +111,7 @@ int GetElidedLabelWidthForRow(int row) override; #endif - GenerationState state() const override; + GenerationUIState state() const override; bool password_selected() const override; const base::string16& password() const override; base::string16 SuggestedText() override; @@ -156,7 +156,7 @@ bool password_selected_; // The state of the generation popup. - GenerationState state_; + GenerationUIState state_; autofill::PopupViewCommon view_common_;
diff --git a/chrome/browser/ui/passwords/password_generation_popup_observer.h b/chrome/browser/ui/passwords/password_generation_popup_observer.h index 9309d74..435e25a 100644 --- a/chrome/browser/ui/passwords/password_generation_popup_observer.h +++ b/chrome/browser/ui/passwords/password_generation_popup_observer.h
@@ -11,7 +11,7 @@ class PasswordGenerationPopupObserver { public: virtual void OnPopupShown( - PasswordGenerationPopupController::GenerationState state) = 0; + PasswordGenerationPopupController::GenerationUIState state) = 0; virtual void OnPopupHidden() = 0; };
diff --git a/chrome/browser/ui/task_manager/task_manager_table_model.cc b/chrome/browser/ui/task_manager/task_manager_table_model.cc index 1025020..6ca269c 100644 --- a/chrome/browser/ui/task_manager/task_manager_table_model.cc +++ b/chrome/browser/ui/task_manager/task_manager_table_model.cc
@@ -80,6 +80,18 @@ return value1 < value2 ? -1 : 1; } +// This forces NaN values to the bottom of the table. +template <> +int ValueCompare(double value1, double value2) { + if (std::isnan(value1)) + return std::isnan(value2) ? 0 : -1; + if (std::isnan(value2)) + return 1; + if (value1 == value2) + return 0; + return value1 < value2 ? -1 : 1; +} + // This is used to sort process priority. We want the backgrounded process (with // a true value) to come first. int BooleanCompare(bool value1, bool value2) {
diff --git a/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc b/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc index e5f3d2f..0c05ae41 100644 --- a/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc +++ b/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc
@@ -44,7 +44,7 @@ // of it. |generating_state| means that the generated password is offered. void Init(const base::string16& password, const base::string16& suggestion, - PasswordGenerationPopupController::GenerationState state) { + PasswordGenerationPopupController::GenerationUIState state) { views::GridLayout* layout = SetLayoutManager(std::make_unique<views::GridLayout>(this)); BuildColumnSet(layout);
diff --git a/chrome/browser/ui/webui/nacl_ui.cc b/chrome/browser/ui/webui/nacl_ui.cc index 78babd6..6fc7196 100644 --- a/chrome/browser/ui/webui/nacl_ui.cc +++ b/chrome/browser/ui/webui/nacl_ui.cc
@@ -197,7 +197,7 @@ os_label += " SP" + base::NumberToString(os->service_pack().major); if (os->service_pack().minor > 0) os_label += "." + base::NumberToString(os->service_pack().minor); - if (os->architecture() == base::win::OSInfo::X64_ARCHITECTURE) + if (os->GetArchitecture() == base::win::OSInfo::X64_ARCHITECTURE) os_label += " 64 bit"; #endif AddPair(list, l10n_util::GetStringUTF16(IDS_VERSION_UI_OS),
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc index 79535bb..8d4e51f 100644 --- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc +++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
@@ -35,7 +35,6 @@ #include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/signin/core/browser/signin_pref_names.h" -#include "components/sync/base/sync_prefs.h" #include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_user_settings.h" #include "components/unified_consent/feature.h" @@ -281,11 +280,6 @@ } void DiceTurnSyncOnHelper::TurnSyncOnWithProfileMode(ProfileMode profile_mode) { - // Make sure the syncing is requested, otherwise the IdentityManager - // will not be able to complete successfully. - syncer::SyncPrefs sync_prefs(profile_->GetPrefs()); - sync_prefs.SetSyncRequested(true); - switch (profile_mode) { case ProfileMode::CURRENT_PROFILE: { // If this is a new signin (no account authenticated yet) try loading @@ -443,6 +437,7 @@ // progress. // TODO(https://crbug.com/811211): Remove this handle. sync_blocker_ = sync_service->GetSetupInProgressHandle(); + sync_service->GetUserSettings()->SetSyncRequested(true); bool is_enterprise_user = !policy::BrowserPolicyConnector::IsNonEnterpriseUser( account_info_.email);
diff --git a/chrome/chrome_cleaner/http/http_agent_impl.cc b/chrome/chrome_cleaner/http/http_agent_impl.cc index d468065..9154c0c 100644 --- a/chrome/chrome_cleaner/http/http_agent_impl.cc +++ b/chrome/chrome_cleaner/http/http_agent_impl.cc
@@ -518,7 +518,7 @@ user_agent->set_architecture(UserAgent::WOW64); } else { base::win::OSInfo::WindowsArchitecture windows_architecture = - os_info->architecture(); + os_info->GetArchitecture(); if (windows_architecture == base::win::OSInfo::X64_ARCHITECTURE) user_agent->set_architecture(UserAgent::X64); else if (windows_architecture == base::win::OSInfo::IA64_ARCHITECTURE)
diff --git a/chrome/chrome_cleaner/os/disk_util.cc b/chrome/chrome_cleaner/os/disk_util.cc index d29e6c9..4430814 100644 --- a/chrome/chrome_cleaner/os/disk_util.cc +++ b/chrome/chrome_cleaner/os/disk_util.cc
@@ -243,7 +243,7 @@ base::FilePath GetX64ProgramFilesPath(const base::FilePath& input_path) { // On X86 system, there is no X64 program files folder, returns empty path. - if (base::win::OSInfo::GetInstance()->architecture() == + if (base::win::OSInfo::GetArchitecture() == base::win::OSInfo::X86_ARCHITECTURE) { return base::FilePath(); }
diff --git a/chrome/chrome_cleaner/os/disk_util_unittest.cc b/chrome/chrome_cleaner/os/disk_util_unittest.cc index edec82e..a1cb7d09 100644 --- a/chrome/chrome_cleaner/os/disk_util_unittest.cc +++ b/chrome/chrome_cleaner/os/disk_util_unittest.cc
@@ -197,7 +197,7 @@ TEST(DiskUtilTests, GetX64ProgramFilePath) { base::FilePath x64_program_files = GetX64ProgramFilesPath(base::FilePath(kProgramFilesBaseName)); - if (base::win::OSInfo::GetInstance()->architecture() == + if (base::win::OSInfo::GetArchitecture() == base::win::OSInfo::X86_ARCHITECTURE) { EXPECT_TRUE(x64_program_files.empty()); return;
diff --git a/chrome/chrome_cleaner/os/system_util.cc b/chrome/chrome_cleaner/os/system_util.cc index 4c0c6a28..d3b919d0 100644 --- a/chrome/chrome_cleaner/os/system_util.cc +++ b/chrome/chrome_cleaner/os/system_util.cc
@@ -122,7 +122,7 @@ } bool IsX64Architecture() { - return base::win::OSInfo::GetInstance()->architecture() == + return base::win::OSInfo::GetArchitecture() == base::win::OSInfo::X64_ARCHITECTURE; }
diff --git a/chrome/chrome_cleaner/os/system_util_cleaner_unittest.cc b/chrome/chrome_cleaner/os/system_util_cleaner_unittest.cc index 7db3b8d..f3d2f76 100644 --- a/chrome/chrome_cleaner/os/system_util_cleaner_unittest.cc +++ b/chrome/chrome_cleaner/os/system_util_cleaner_unittest.cc
@@ -85,8 +85,7 @@ EXPECT_FALSE(DoesServiceExist(service_handle.service_name())); } -// Flaky. https://crbug.com/871784 -TEST_F(ServiceUtilCleanerTest, DISABLED_StopAndDeleteRunningService) { +TEST_F(ServiceUtilCleanerTest, StopAndDeleteRunningService) { // Install and launch the service. TestScopedServiceHandle service_handle; ASSERT_TRUE(service_handle.InstallService()); @@ -109,8 +108,7 @@ EXPECT_FALSE(IsProcessRunning(kTestServiceExecutableName)); } -// Flaky. https://crbug.com/871784 -TEST_F(ServiceUtilCleanerTest, DISABLED_DeleteRunningService) { +TEST_F(ServiceUtilCleanerTest, DeleteRunningService) { // Install and launch the service. TestScopedServiceHandle service_handle; ASSERT_TRUE(service_handle.InstallService());
diff --git a/chrome/chrome_cleaner/test/BUILD.gn b/chrome/chrome_cleaner/test/BUILD.gn index 244cd1c..c62ce65 100644 --- a/chrome/chrome_cleaner/test/BUILD.gn +++ b/chrome/chrome_cleaner/test/BUILD.gn
@@ -129,6 +129,7 @@ "//base", "//chrome/chrome_cleaner/os:cleaner_os", "//chrome/chrome_cleaner/os:common_os", + "//testing/gtest", ] }
diff --git a/chrome/chrome_cleaner/test/test_scoped_service_handle.cc b/chrome/chrome_cleaner/test/test_scoped_service_handle.cc index 77a71c3..d85ed59 100644 --- a/chrome/chrome_cleaner/test/test_scoped_service_handle.cc +++ b/chrome/chrome_cleaner/test/test_scoped_service_handle.cc
@@ -6,6 +6,7 @@ #include <windows.h> +#include <utility> #include <vector> #include "base/base_paths.h" @@ -25,6 +26,10 @@ namespace { +using ::testing::AssertionFailure; +using ::testing::AssertionResult; +using ::testing::AssertionSuccess; + // The sleep time in ms between each poll attempt to get information about a // service. constexpr unsigned int kServiceQueryWaitTimeMs = 250; @@ -32,18 +37,22 @@ // The number of attempts to contact a service. constexpr int kServiceQueryRetry = 5; +std::string LastErrorString() { + return logging::SystemErrorCodeToString(logging::GetLastSystemErrorCode()); +} + } // namespace TestScopedServiceHandle::~TestScopedServiceHandle() { StopAndDelete(); } -bool TestScopedServiceHandle::InstallService() { +AssertionResult TestScopedServiceHandle::InstallService() { // Construct the full-path of the test service. base::FilePath module_path; if (!base::PathService::Get(base::DIR_EXE, &module_path)) { - PLOG(ERROR) << "Cannot retrieve module name."; - return false; + return AssertionFailure() + << "Cannot retrieve module name:" << LastErrorString(); } module_path = module_path.Append(kTestServiceExecutableName); @@ -58,8 +67,8 @@ service_manager_.Set( ::OpenSCManager(nullptr, nullptr, SC_MANAGER_ALL_ACCESS)); if (!service_manager_.IsValid()) { - PLOG(ERROR) << "Cannot open service manager."; - return false; + return AssertionFailure() + << "Cannot open service manager:" << LastErrorString(); } const base::string16 service_desc = @@ -72,35 +81,52 @@ nullptr, nullptr, nullptr)); if (!service_.IsValid()) { // Unable to create the service. - PLOG(ERROR) << "Cannot create service '" << service_name << "'."; - return false; + return AssertionFailure() << "Cannot create service '" << service_name + << "':" << LastErrorString(); } LOG(INFO) << "Created test service '" << service_name << "'."; service_name_ = service_name; - return true; + return AssertionSuccess(); } -bool TestScopedServiceHandle::StartService() { - if (!::StartService(service_.Get(), 0, nullptr)) - return false; +AssertionResult TestScopedServiceHandle::StartService() { + if (!::StartService(service_.Get(), 0, nullptr)) { + return AssertionFailure() + << "Failed to start " << service_name_ << ":" << LastErrorString(); + } SERVICE_STATUS service_status = {}; for (int iteration = 0; iteration < kServiceQueryRetry; ++iteration) { - if (!::QueryServiceStatus(service_.Get(), &service_status)) - return false; + if (!::QueryServiceStatus(service_.Get(), &service_status)) { + return AssertionFailure() + << "Failed to query service status:" << LastErrorString(); + } if (service_status.dwCurrentState == SERVICE_RUNNING) - return true; + return AssertionSuccess(); ::Sleep(kServiceQueryWaitTimeMs); } - return false; + return AssertionFailure() << "Service was not running after polling " + << kServiceQueryRetry << " times"; } -bool TestScopedServiceHandle::StopAndDelete() { +AssertionResult TestScopedServiceHandle::StopAndDelete() { Close(); - if (service_name_.empty()) - return false; - bool result = StopAndDeleteService(service_name_.c_str()); - service_name_.clear(); - return result; + base::string16 service_name; + std::swap(service_name, service_name_); + if (service_name.empty()) { + return AssertionFailure() << "Attempt to stop service with no name"; + } + + if (!StopService(service_name.c_str())) { + return AssertionFailure() << "Failed to stop service " << service_name; + } + if (!DeleteService(service_name.c_str())) { + return AssertionFailure() << "Failed to delete service " << service_name; + } + if (!WaitForServiceDeleted(service_name.c_str())) { + return AssertionFailure() + << "Failed while waiting for deletion of service " << service_name; + } + return AssertionSuccess(); } void TestScopedServiceHandle::Close() { @@ -108,13 +134,6 @@ service_manager_.Close(); } -bool TestScopedServiceHandle::StopAndDeleteService( - const base::string16& service_name) { - return StopService(service_name.c_str()) && - DeleteService(service_name.c_str()) && - WaitForServiceDeleted(service_name.c_str()); -} - base::string16 RandomUnusedServiceNameForTesting() { base::string16 service_name; do { @@ -124,13 +143,13 @@ return service_name; } -bool EnsureNoTestServicesRunning() { +AssertionResult EnsureNoTestServicesRunning() { // Get the pid's of all processes running the test service executable. base::ProcessIterator::ProcessEntries processes = base::NamedProcessIterator(kTestServiceExecutableName, nullptr) .Snapshot(); if (processes.empty()) - return true; + return AssertionSuccess(); std::vector<base::ProcessId> process_ids; process_ids.reserve(processes.size()); @@ -146,17 +165,15 @@ std::vector<ServiceStatus> services; if (!EnumerateServices(service_manager, SERVICE_WIN32_OWN_PROCESS, SERVICE_STATE_ALL, &services)) { - return false; + return AssertionFailure() << "Failed to enumerate services"; } std::vector<base::string16> stopped_service_names; for (const ServiceStatus& service : services) { base::string16 service_name = service.service_name; base::ProcessId pid = service.service_status_process.dwProcessId; if (base::ContainsValue(process_ids, pid)) { - if (!StopService(service_name.c_str())) { - LOG(ERROR) << "Could not stop service " << service_name; - return false; - } + if (!StopService(service_name.c_str())) + return AssertionFailure() << "Could not stop service " << service_name; stopped_service_names.push_back(service_name); } } @@ -164,25 +181,22 @@ // Now all services running the test executable should be stopping, and can be // deleted. if (!WaitForProcessesStopped(kTestServiceExecutableName)) { - LOG(ERROR) << "Not all " << kTestServiceExecutableName - << " processes stopped"; - return false; + return AssertionFailure() + << "Not all " << kTestServiceExecutableName << " processes stopped"; } // Issue an async DeleteService request for each service in parallel, then // wait for all of them to finish deleting. for (const base::string16& service_name : stopped_service_names) { - if (!DeleteService(service_name.c_str())) { - LOG(ERROR) << "Could not delete service " << service_name; - return false; - } + if (!DeleteService(service_name.c_str())) + return AssertionFailure() << "Could not delete service " << service_name; } for (const base::string16& service_name : stopped_service_names) { if (!WaitForServiceDeleted(service_name.c_str())) { - LOG(ERROR) << "Did not finish deleting service " << service_name; - return false; + return AssertionFailure() + << "Did not finish deleting service " << service_name; } } - return true; + return AssertionSuccess(); } } // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/test/test_scoped_service_handle.h b/chrome/chrome_cleaner/test/test_scoped_service_handle.h index d63babd6..785dbb4 100644 --- a/chrome/chrome_cleaner/test/test_scoped_service_handle.h +++ b/chrome/chrome_cleaner/test/test_scoped_service_handle.h
@@ -10,6 +10,7 @@ #include "base/files/file_path.h" #include "base/strings/string16.h" #include "chrome/chrome_cleaner/os/scoped_service_handle.h" +#include "testing/gtest/include/gtest/gtest.h" namespace chrome_cleaner { @@ -20,16 +21,14 @@ public: ~TestScopedServiceHandle(); - bool InstallService(); - bool StartService(); - bool StopAndDelete(); + ::testing::AssertionResult InstallService(); + ::testing::AssertionResult StartService(); + ::testing::AssertionResult StopAndDelete(); void Close(); const base::char16* service_name() const { return service_name_.c_str(); } private: - static bool StopAndDeleteService(const base::string16& service_name); - base::string16 service_name_; }; @@ -40,7 +39,7 @@ // Tries to stop any copies of the test service executable that are running. // Returns false if an executable remains running. -bool EnsureNoTestServicesRunning(); +::testing::AssertionResult EnsureNoTestServicesRunning(); } // namespace chrome_cleaner
diff --git a/chrome/common/conflicts/module_event_sink_win.mojom b/chrome/common/conflicts/module_event_sink_win.mojom index ec29a822..556ffbc 100644 --- a/chrome/common/conflicts/module_event_sink_win.mojom +++ b/chrome/common/conflicts/module_event_sink_win.mojom
@@ -6,8 +6,8 @@ // Interface for a remote consumer of module events. interface ModuleEventSink { - // Notifies the module database of a module event in a remote process. The - // module is identified only by its load address, which is sufficient for - // any process to safely look up the module. - OnModuleEvent(uint64 load_address); + // Notifies the module database of multiple module events in a remote process. + // The modules are identified only by their load addresses, which are + // sufficient for any process to safely look up the modules. + OnModuleEvents(array<uint64> module_load_addresses); };
diff --git a/chrome/common/conflicts/remote_module_watcher_win.cc b/chrome/common/conflicts/remote_module_watcher_win.cc index 66e0d9a..50cb691 100644 --- a/chrome/common/conflicts/remote_module_watcher_win.cc +++ b/chrome/common/conflicts/remote_module_watcher_win.cc
@@ -23,6 +23,9 @@ } // namespace +// static +constexpr base::TimeDelta RemoteModuleWatcher::kIdleDelay; + RemoteModuleWatcher::~RemoteModuleWatcher() = default; // static @@ -46,7 +49,12 @@ RemoteModuleWatcher::RemoteModuleWatcher( scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : task_runner_(task_runner), weak_ptr_factory_(this) {} + : task_runner_(task_runner), + delay_timer_(FROM_HERE, + kIdleDelay, + this, + &RemoteModuleWatcher::OnTimerFired), + weak_ptr_factory_(this) {} void RemoteModuleWatcher::InitializeOnTaskRunner( std::unique_ptr<service_manager::Connector> connector) { @@ -65,6 +73,17 @@ const ModuleWatcher::ModuleEvent& event) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); - module_event_sink_->OnModuleEvent( + // Accumulate events. They will be sent when the |delay_timer_| fires. + module_load_addresses_.push_back( reinterpret_cast<uintptr_t>(event.module_load_address)); + + // Ensure the timer is running. + delay_timer_.Reset(); +} + +void RemoteModuleWatcher::OnTimerFired() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + + module_event_sink_->OnModuleEvents(module_load_addresses_); + module_load_addresses_.clear(); }
diff --git a/chrome/common/conflicts/remote_module_watcher_win.h b/chrome/common/conflicts/remote_module_watcher_win.h index c0e716a..0621231 100644 --- a/chrome/common/conflicts/remote_module_watcher_win.h +++ b/chrome/common/conflicts/remote_module_watcher_win.h
@@ -6,10 +6,13 @@ #define CHROME_COMMON_CONFLICTS_REMOTE_MODULE_WATCHER_WIN_H_ #include <memory> +#include <vector> #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "base/timer/timer.h" #include "chrome/common/conflicts/module_event_sink_win.mojom.h" #include "chrome/common/conflicts/module_watcher_win.h" #include "mojo/public/cpp/bindings/interface_ptr.h" @@ -32,6 +35,10 @@ using UniquePtr = std::unique_ptr<RemoteModuleWatcher, base::OnTaskRunnerDeleter>; + // The amount of time this class waits before sending all the received module + // events in one batch to the browser process. + static constexpr base::TimeDelta kIdleDelay = base::TimeDelta::FromSeconds(5); + ~RemoteModuleWatcher(); // Creates a RemoteModuleWatcher instance and initializes it on |task_runner|. @@ -54,6 +61,10 @@ // the |module_event_sink_|. void HandleModuleEvent(const ModuleWatcher::ModuleEvent& event); + // Sends all accumulated module events in |module_load_addresses_| to the + // |module_event_sink_| in one batch. + void OnTimerFired(); + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; // Module events from |module_watcher_| are forwarded to the browser process @@ -63,6 +74,14 @@ // Observes module load events. std::unique_ptr<ModuleWatcher> module_watcher_; + // Accumulates module events. They will be sent to the browser process when + // |delay_timer_| fires. + std::vector<uint64_t> module_load_addresses_; + + // This timer is used to delay the sending of module events until none have + // been received for |kIdleDelay| amount of time. + base::DelayTimer delay_timer_; + base::WeakPtrFactory<RemoteModuleWatcher> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(RemoteModuleWatcher);
diff --git a/chrome/common/conflicts/remote_module_watcher_win_unittest.cc b/chrome/common/conflicts/remote_module_watcher_win_unittest.cc index 41b6db18..7096c6e 100644 --- a/chrome/common/conflicts/remote_module_watcher_win_unittest.cc +++ b/chrome/common/conflicts/remote_module_watcher_win_unittest.cc
@@ -9,10 +9,11 @@ #include <memory> #include <string> #include <utility> +#include <vector> #include "base/memory/scoped_refptr.h" -#include "base/task/post_task.h" #include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" #include "chrome/common/conflicts/module_event_sink_win.mojom.h" #include "content/public/common/service_names.mojom.h" #include "services/service_manager/public/cpp/binder_registry.h" @@ -28,7 +29,11 @@ public mojom::ModuleEventSink { public: RemoteModuleWatcherTest() - : service_binding_(this, + : scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME, + base::test::ScopedTaskEnvironment::NowSource:: + MAIN_THREAD_MOCK_TIME), + service_binding_(this, test_connector_factory_.RegisterInstance( content::mojom::kBrowserServiceName)), binding_(this) {} @@ -48,9 +53,13 @@ } // mojom::ModuleEventSink: - void OnModuleEvent(uint64_t load_address) override { module_event_count_++; } + void OnModuleEvents( + const std::vector<uint64_t>& module_load_addresses) override { + module_event_count_ += module_load_addresses.size(); + } - // Returns a connector that may be used to connect to a ModuleEventSink implementation. + // Returns a connector that may be used to connect to a ModuleEventSink + // implementation. service_manager::Connector* GetConnector() { return test_connector_factory_.GetDefaultConnector(); } @@ -78,6 +87,9 @@ // Runs the task scheduler until no tasks are running. void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); } + void FastForwardByIdleDelay() { + scoped_task_environment_.FastForwardBy(RemoteModuleWatcher::kIdleDelay); + } HMODULE module_handle() { return module_handle_; } @@ -112,19 +124,21 @@ } // namespace TEST_F(RemoteModuleWatcherTest, ModuleEvents) { - auto task_runner = base::CreateSingleThreadTaskRunnerWithTraits({}); + auto remote_module_watcher = RemoteModuleWatcher::Create( + base::ThreadTaskRunnerHandle::Get(), GetConnector()); - auto remote_module_watcher = - RemoteModuleWatcher::Create(task_runner, GetConnector()); - - // Wait until the watcher is initialized and a few module events are received. + // Wait until the watcher is initialized and events for already loaded modules + // are received. RunUntilIdle(); + // Now wait for the timer used to batch events to expire. + FastForwardByIdleDelay(); + EXPECT_GT(module_event_count(), 0); // Dynamically load a module and ensure a notification is received for it. int previous_module_event_count = module_event_count(); LoadModule(); - RunUntilIdle(); + FastForwardByIdleDelay(); EXPECT_GT(module_event_count(), previous_module_event_count); UnloadModule(); @@ -136,7 +150,7 @@ // Load the module and ensure no notification is received this time. previous_module_event_count = module_event_count(); LoadModule(); - RunUntilIdle(); + FastForwardByIdleDelay(); EXPECT_EQ(module_event_count(), previous_module_event_count);
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 091967c..e499334a8f 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -2583,6 +2583,10 @@ // used. const char kNotificationNextPersistentId[] = "persistent_notifications.next_id"; +// Time that holds the value of the next notification trigger timestamp. +const char kNotificationNextTriggerTime[] = + "persistent_notifications.next_trigger"; + // Preference for controlling whether tab lifecycles // (throttling/freezing/discarding) are enabled. const char kTabLifecyclesEnabled[] = "tab_lifecycles_enabled";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index fa23f8ef..6456f191 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -912,6 +912,7 @@ #endif extern const char kNotificationNextPersistentId[]; +extern const char kNotificationNextTriggerTime[]; extern const char kTabLifecyclesEnabled[];
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index d829113..c371f1a 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h
@@ -116,6 +116,14 @@ GURL /* top origin url */, bool /* allowed */) +// Sent by the renderer process to check whether access to CacheStorage is +// granted by content settings. +IPC_SYNC_MESSAGE_CONTROL3_1(ChromeViewHostMsg_AllowCacheStorage, + int /* render_frame_id */, + GURL /* origin_url */, + GURL /* top origin url */, + bool /* allowed */) + #if BUILDFLAG(ENABLE_PLUGINS) // Sent by the renderer to check if crash reporting is enabled. IPC_SYNC_MESSAGE_CONTROL0_1(ChromeViewHostMsg_IsCrashReportingEnabled,
diff --git a/chrome/credential_provider/gaiacp/dllmain.cc b/chrome/credential_provider/gaiacp/dllmain.cc index b4551f5..f265a7a 100644 --- a/chrome/credential_provider/gaiacp/dllmain.cc +++ b/chrome/credential_provider/gaiacp/dllmain.cc
@@ -23,6 +23,7 @@ #include "base/values.h" #include "base/win/current_module.h" #include "base/win/registry.h" +#include "base/win/scoped_com_initializer.h" #include "chrome/common/chrome_version.h" #include "chrome/credential_provider/common/gcp_strings.h" #include "chrome/credential_provider/gaiacp/gaia_credential.h" @@ -184,13 +185,22 @@ if (FAILED(hr)) LOGFN(ERROR) << "SaveAccountInfoW hr=" << putHR(hr); - // Try to enroll the machine to MDM here. MDM requires a user to be signed on - // to an interactive session to succeed and when we call this function the - // user should have been successfully signed on at that point and able to - // finish the enrollment. - hr = credential_provider::EnrollToGoogleMdmIfNeeded(*dict); - if (FAILED(hr)) - LOGFN(ERROR) << "EnrollToGoogleMdmIfNeeded hr=" << putHR(hr); + // Make sure COM is initialized in this thread. This thread must be + // initialized as an MTA or the call to enroll with MDM causes a crash in COM. + base::win::ScopedCOMInitializer com_initializer( + base::win::ScopedCOMInitializer::kMTA); + if (!com_initializer.Succeeded()) { + HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); + LOGFN(ERROR) << "ScopedCOMInitializer failed hr=" << putHR(hr); + } else { + // Try to enroll the machine to MDM here. MDM requires a user to be signed + // on to an interactive session to succeed and when we call this function + // the user should have been successfully signed on at that point and able + // to finish the enrollment. + HRESULT hr = credential_provider::EnrollToGoogleMdmIfNeeded(*dict); + if (FAILED(hr)) + LOGFN(ERROR) << "EnrollToGoogleMdmIfNeeded hr=" << putHR(hr); + } LOGFN(INFO) << "Done"; }
diff --git a/chrome/credential_provider/gaiacp/mdm_utils.cc b/chrome/credential_provider/gaiacp/mdm_utils.cc index f84a589..dadea63 100644 --- a/chrome/credential_provider/gaiacp/mdm_utils.cc +++ b/chrome/credential_provider/gaiacp/mdm_utils.cc
@@ -176,9 +176,14 @@ << " token=" << base::string16(token.c_str(), 10); // Build the json data needed by the server. - base::string16 serial_number = base::win::WmiComputerSystemInfo::Get().serial_number(); + + if (serial_number.empty()) { + LOGFN(ERROR) << "Failed to get serial number."; + return -1; + } + base::DictionaryValue registration_data; registration_data.SetString("serial_number", serial_number); registration_data.SetString("id_token", token);
diff --git a/chrome/install_static/product_install_details_unittest.cc b/chrome/install_static/product_install_details_unittest.cc index 3025dac..889f38b 100644 --- a/chrome/install_static/product_install_details_unittest.cc +++ b/chrome/install_static/product_install_details_unittest.cc
@@ -71,7 +71,7 @@ // 32-bit on 32-bit: only check C:\Program Files. // 32-bit and 64-bit on 64-bit: check both. - const bool is_x64 = base::win::OSInfo::GetInstance()->architecture() != + const bool is_x64 = base::win::OSInfo::GetArchitecture() != base::win::OSInfo::X86_ARCHITECTURE; std::vector<int> program_files_keys; program_files_keys.push_back(base::DIR_PROGRAM_FILESX86);
diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc index e2dc19f4..1d59daa 100644 --- a/chrome/renderer/content_settings_observer.cc +++ b/chrome/renderer/content_settings_observer.cc
@@ -317,6 +317,19 @@ return result; } +bool ContentSettingsObserver::AllowCacheStorage( + const blink::WebSecurityOrigin& origin) { + WebFrame* frame = render_frame()->GetWebFrame(); + if (IsUniqueFrame(frame)) + return false; + + bool result = false; + Send(new ChromeViewHostMsg_AllowCacheStorage( + routing_id(), url::Origin(frame->GetSecurityOrigin()).GetURL(), + url::Origin(frame->Top()->GetSecurityOrigin()).GetURL(), &result)); + return result; +} + bool ContentSettingsObserver::AllowScript(bool enabled_per_settings) { if (!enabled_per_settings) return false;
diff --git a/chrome/renderer/content_settings_observer.h b/chrome/renderer/content_settings_observer.h index ba15221..5939455c 100644 --- a/chrome/renderer/content_settings_observer.h +++ b/chrome/renderer/content_settings_observer.h
@@ -82,6 +82,7 @@ bool AllowImage(bool enabled_per_settings, const blink::WebURL& image_url) override; bool AllowIndexedDB(const blink::WebSecurityOrigin& origin) override; + bool AllowCacheStorage(const blink::WebSecurityOrigin& origin) override; bool AllowScript(bool enabled_per_settings) override; bool AllowScriptFromSource(bool enabled_per_settings, const blink::WebURL& script_url) override;
diff --git a/chrome/renderer/worker_content_settings_client.cc b/chrome/renderer/worker_content_settings_client.cc index 9d5cd2c..7d40793 100644 --- a/chrome/renderer/worker_content_settings_client.cc +++ b/chrome/renderer/worker_content_settings_client.cc
@@ -71,6 +71,17 @@ return result; } +bool WorkerContentSettingsClient::AllowCacheStorage( + const blink::WebSecurityOrigin&) { + if (is_unique_origin_) + return false; + + bool result = false; + sync_message_filter_->Send(new ChromeViewHostMsg_AllowCacheStorage( + routing_id_, document_origin_url_, top_frame_origin_url_, &result)); + return result; +} + bool WorkerContentSettingsClient::AllowRunningInsecureContent( bool allowed_per_settings, const blink::WebSecurityOrigin& context,
diff --git a/chrome/renderer/worker_content_settings_client.h b/chrome/renderer/worker_content_settings_client.h index b7d0791..d4566f18 100644 --- a/chrome/renderer/worker_content_settings_client.h +++ b/chrome/renderer/worker_content_settings_client.h
@@ -35,6 +35,7 @@ std::unique_ptr<blink::WebContentSettingsClient> Clone() override; bool RequestFileSystemAccessSync() override; bool AllowIndexedDB(const blink::WebSecurityOrigin&) override; + bool AllowCacheStorage(const blink::WebSecurityOrigin&) override; bool AllowRunningInsecureContent(bool allowed_per_settings, const blink::WebSecurityOrigin& context, const blink::WebURL& url) override;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index f8cbe2c..7478f0d 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2518,6 +2518,7 @@ "../browser/android/history_report/usage_reports_buffer_backend_unittest.cc", "../browser/android/locale/locale_template_url_loader_unittest.cc", "../browser/android/tab_web_contents_delegate_android_unittest.cc", + "../browser/security_events/security_event_recorder_impl_unittest.cc", "../browser/ui/webui/version_handler_win_unittest.cc", # TODO(newt): move this to test_support_unit? @@ -2708,6 +2709,7 @@ "../browser/notifications/notification_permission_context_unittest.cc", "../browser/notifications/notification_platform_bridge_chromeos_unittest.cc", "../browser/notifications/notification_platform_bridge_mac_unittest.mm", + "../browser/notifications/notification_trigger_scheduler_unittest.cc", "../browser/notifications/persistent_notification_handler_unittest.cc", "../browser/notifications/platform_notification_service_unittest.cc", "../browser/notifications/stub_alert_dispatcher_mac.h", @@ -2765,6 +2767,7 @@ "../browser/performance_manager/graph/graph_unittest.cc", "../browser/performance_manager/graph/mock_graphs.cc", "../browser/performance_manager/graph/mock_graphs.h", + "../browser/performance_manager/graph/node_attached_data_unittest.cc", "../browser/performance_manager/graph/node_base_unittest.cc", "../browser/performance_manager/graph/page_node_impl_unittest.cc", "../browser/performance_manager/graph/process_node_impl_unittest.cc", @@ -4646,6 +4649,7 @@ "../browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc", "../browser/supervised_user/child_accounts/permission_request_creator_apiary_unittest.cc", "../browser/supervised_user/experimental/safe_search_url_reporter_unittest.cc", + "../browser/supervised_user/kids_management_url_checker_client_unittest.cc", "../browser/supervised_user/supervised_user_pref_store_unittest.cc", "../browser/supervised_user/supervised_user_service_unittest.cc", "../browser/supervised_user/supervised_user_settings_service_unittest.cc",
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 8d222546..b67246a 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc
@@ -487,10 +487,9 @@ user_prefs::PrefRegistrySyncable* pref_registry = static_cast<user_prefs::PrefRegistrySyncable*>( prefs_->DeprecatedGetPrefRegistry()); - simple_dependency_manager_->RegisterProfilePrefsForServices(key, - pref_registry); - browser_context_dependency_manager_-> - RegisterProfilePrefsForServices(this, pref_registry); + simple_dependency_manager_->RegisterProfilePrefsForServices(pref_registry); + browser_context_dependency_manager_->RegisterProfilePrefsForServices( + pref_registry); } simple_dependency_manager_->CreateServicesForTest(key);
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index e404653..b1b5c54 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -3789,6 +3789,14 @@ "DeviceAllowBluetooth": { }, + "DeviceWiFiAllowed": { + "os": ["chromeos"], + "test_policy": { "DeviceWiFiAllowed": false}, + "pref_mappings": [ + { "pref": "cros.device.device_wifi_allowed" } + ] + }, + "DeviceQuirksDownloadEnabled": { "os": ["chromeos"], "can_be_recommended": false,
diff --git a/chrome/test/nacl/nacl_browsertest.cc b/chrome/test/nacl/nacl_browsertest.cc index ce153b5..0f3bde3 100644 --- a/chrome/test/nacl/nacl_browsertest.cc +++ b/chrome/test/nacl/nacl_browsertest.cc
@@ -285,9 +285,9 @@ // (see note in chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc) #if defined(OS_WIN) if (base::win::OSInfo::GetInstance()->wow64_status() == - base::win::OSInfo::WOW64_DISABLED && - base::win::OSInfo::GetInstance()->architecture() == - base::win::OSInfo::X86_ARCHITECTURE) { + base::win::OSInfo::WOW64_DISABLED && + base::win::OSInfo::GetArchitecture() == + base::win::OSInfo::X86_ARCHITECTURE) { return true; } #endif
diff --git a/chrome_elf/BUILD.gn b/chrome_elf/BUILD.gn index 61efc526..7643f279 100644 --- a/chrome_elf/BUILD.gn +++ b/chrome_elf/BUILD.gn
@@ -372,6 +372,7 @@ # Disable sanitizer instrumentation in the test DLLs to avoid unwanted # exports. + no_default_deps = true configs -= [ "//build/config/sanitizers:default_sanitizer_flags", "//build/config:shared_library_config", @@ -387,6 +388,7 @@ # Disable sanitizer instrumentation in the test DLLs to avoid unwanted # exports. + no_default_deps = true configs -= [ "//build/config/sanitizers:default_sanitizer_flags", "//build/config:shared_library_config",
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index 75ce77a..4ffe6a7 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -239,6 +239,15 @@ "//components/crash/content/app", "//components/crash/content/browser", ] + + # TODO(crbug.com/933142): Fuchsia needs its own methods to bridge with heap + # profiling service + deps += [ + "//components/heap_profiling", + "//components/services/heap_profiling", + "//components/services/heap_profiling/public/cpp", + "//components/services/heap_profiling/public/mojom", + ] } if (use_ozone) {
diff --git a/chromecast/browser/DEPS b/chromecast/browser/DEPS index ea72b8b..5431ac4e 100644 --- a/chromecast/browser/DEPS +++ b/chromecast/browser/DEPS
@@ -12,12 +12,16 @@ "+components/cdm/browser", "+components/crash", "+components/download/public/common", + "+components/heap_profiling", "+components/keyed_service", "+components/network_hints/browser", "+components/network_session_configurator/common", "+components/prefs", "+components/pref_registry", "+components/proxy_config", + "+components/services/heap_profiling/heap_profiling_service.h", + "+components/services/heap_profiling/public/mojom", + "+components/services/heap_profiling/public/cpp/settings.h", "+components/storage_monitor", "+components/user_prefs", "+components/version_info",
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index 4b6e811f..27b2d52 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -8,6 +8,7 @@ #include <string.h> #include <string> +#include <utility> #include <vector> #include "base/bind.h" @@ -121,6 +122,12 @@ #include "device/bluetooth/cast/bluetooth_adapter_cast.h" #endif // !defined(OS_ANDROID) && !defined(OS_FUCHSIA) +#if !defined(OS_FUCHSIA) +#include "base/bind_helpers.h" +#include "components/heap_profiling/client_connection_manager.h" +#include "components/heap_profiling/supervisor.h" +#endif // !defined(OS_FUCHSIA) + namespace { #if !defined(OS_ANDROID) && !defined(OS_FUCHSIA) @@ -218,6 +225,18 @@ #endif // !defined(OS_ANDROID) && !defined(OS_FUCHSIA) +#if !defined(OS_FUCHSIA) + +std::unique_ptr<heap_profiling::ClientConnectionManager> +CreateClientConnectionManager( + base::WeakPtr<heap_profiling::Controller> controller_weak_ptr, + heap_profiling::Mode mode) { + return std::make_unique<heap_profiling::ClientConnectionManager>( + std::move(controller_weak_ptr), mode); +} + +#endif + } // namespace namespace chromecast { @@ -670,5 +689,16 @@ #endif // !defined(OS_ANDROID) } +void CastBrowserMainParts::ServiceManagerConnectionStarted( + content::ServiceManagerConnection* connection) { +#if !defined(OS_FUCHSIA) + heap_profiling::Supervisor* supervisor = + heap_profiling::Supervisor::GetInstance(); + supervisor->SetClientConnectionManagerConstructor( + &CreateClientConnectionManager); + supervisor->Start(connection, base::NullCallback()); +#endif // !defined(OS_FUCHSIA) +} + } // namespace shell } // namespace chromecast
diff --git a/chromecast/browser/cast_browser_main_parts.h b/chromecast/browser/cast_browser_main_parts.h index 662b5d4..4577385 100644 --- a/chromecast/browser/cast_browser_main_parts.h +++ b/chromecast/browser/cast_browser_main_parts.h
@@ -82,6 +82,8 @@ bool MainMessageLoopRun(int* result_code) override; void PostMainMessageLoopRun() override; void PostDestroyThreads() override; + void ServiceManagerConnectionStarted( + content::ServiceManagerConnection* connection) override; private: std::unique_ptr<CastBrowserProcess> cast_browser_process_;
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index 894d7f1..44f283e 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -136,6 +136,12 @@ #include "chromecast/external_mojo/broker_service/broker_service.h" #endif +#if !defined(OS_FUCHSIA) +#include "components/services/heap_profiling/heap_profiling_service.h" // nogncheck +#include "components/services/heap_profiling/public/cpp/settings.h" // nogncheck +#include "components/services/heap_profiling/public/mojom/constants.mojom.h" // nogncheck +#endif // !defined(OS_FUCHSIA) + namespace chromecast { namespace shell { @@ -1013,5 +1019,27 @@ return chromecast::shell::GetUserAgent(); } +void CastContentBrowserClient::RegisterOutOfProcessServices( + OutOfProcessServiceMap* services) { +#if !defined(OS_FUCHSIA) + if (!heap_profiling::IsInProcessModeEnabled()) { + services->emplace( + heap_profiling::mojom::kServiceName, + base::BindRepeating(&base::ASCIIToUTF16, "Profiling Service")); + } +#endif // !defined(OS_FUCHSIA) +} + +void CastContentBrowserClient::RegisterIOThreadServiceHandlers( + content::ServiceManagerConnection* connection) { +#if !defined(OS_FUCHSIA) + if (heap_profiling::IsInProcessModeEnabled()) { + connection->AddServiceRequestHandler( + heap_profiling::mojom::kServiceName, + heap_profiling::HeapProfilingService::GetServiceFactory()); + } +#endif // !defined(OS_FUCHSIA) +} + } // namespace shell } // namespace chromecast
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index 41da499..0cd57a5 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h
@@ -217,6 +217,9 @@ bool in_memory, const base::FilePath& relative_partition_path) override; std::string GetUserAgent() const override; + void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override; + void RegisterIOThreadServiceHandlers( + content::ServiceManagerConnection* connection) override; CastFeatureListCreator* GetCastFeatureListCreator() { return cast_feature_list_creator_; }
diff --git a/chromecast/browser/cast_overlay_manifests.cc b/chromecast/browser/cast_overlay_manifests.cc index 3ab7d82..aa050547 100644 --- a/chromecast/browser/cast_overlay_manifests.cc +++ b/chromecast/browser/cast_overlay_manifests.cc
@@ -25,12 +25,24 @@ #include "chromecast/internal/shell/browser/cast_content_renderer_internal_manifest_overlay.h" #endif +#if !defined(OS_FUCHSIA) +#include "components/services/heap_profiling/public/mojom/heap_profiling_client.mojom.h" // nogncheck +#endif // !defined(OS_FUCHSIA) + namespace chromecast { namespace shell { const service_manager::Manifest& GetCastContentBrowserOverlayManifest() { static base::NoDestructor<service_manager::Manifest> manifest { service_manager::ManifestBuilder() +#if !defined(OS_FUCHSIA) + .RequireCapability("heap_profiling", "heap_profiler") + .RequireCapability("heap_profiling", "profiling") + .RequireCapability("content_browser", "profiling_client") + .ExposeCapability("profiling_client", + service_manager::Manifest::InterfaceList< + heap_profiling::mojom::ProfilingClient>()) +#endif // !defined(OS_FUCHSIA) .ExposeCapability("renderer", service_manager::Manifest::InterfaceList< chromecast::media::mojom::MediaCaps, @@ -50,6 +62,11 @@ const service_manager::Manifest& GetCastContentRendererOverlayManifest() { static base::NoDestructor<service_manager::Manifest> manifest { service_manager::ManifestBuilder() +#if !defined(OS_FUCHSIA) + .ExposeCapability("browser", + service_manager::Manifest::InterfaceList< + heap_profiling::mojom::ProfilingClient>()) +#endif // !defined(OS_FUCHSIA) .ExposeInterfaceFilterCapability_Deprecated( "navigation:frame", "browser", service_manager::Manifest::InterfaceList<
diff --git a/chromecast/common/BUILD.gn b/chromecast/common/BUILD.gn index dac6096..925976d 100644 --- a/chromecast/common/BUILD.gn +++ b/chromecast/common/BUILD.gn
@@ -52,4 +52,8 @@ "//extensions/shell:resources_grit", ] } + + if (!is_fuchsia) { + deps += [ "//components/services/heap_profiling/public/cpp" ] + } }
diff --git a/chromecast/common/DEPS b/chromecast/common/DEPS index 288eeae..9dcc12d 100644 --- a/chromecast/common/DEPS +++ b/chromecast/common/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/services/heap_profiling/public/cpp", "+components/version_info", "+content/public/common", "+extensions/common", @@ -6,6 +7,7 @@ "+extensions/shell/common/api", "+extensions/shell/grit", "+mojo/public/cpp/bindings", + "+services/service_manager/public/cpp", "+ui/accessibility", "+ui/base", "+ui/gfx",
diff --git a/chromecast/common/cast_content_client.cc b/chromecast/common/cast_content_client.cc index 491e0842..b2807bd 100644 --- a/chromecast/common/cast_content_client.cc +++ b/chromecast/common/cast_content_client.cc
@@ -5,6 +5,8 @@ #include "chromecast/common/cast_content_client.h" #include <stdint.h> +#include <memory> +#include <utility> #include "base/strings/stringprintf.h" #include "base/system/sys_info.h" @@ -25,6 +27,14 @@ #include "chromecast/common/media/cast_media_drm_bridge_client.h" #endif +#if !defined(OS_FUCHSIA) +#include "base/no_destructor.h" +#include "components/services/heap_profiling/public/cpp/client.h" // nogncheck +#include "content/public/common/service_manager_connection.h" +#include "content/public/common/simple_connection_filter.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#endif + namespace chromecast { namespace shell { @@ -133,5 +143,20 @@ } #endif // OS_ANDROID +void CastContentClient::OnServiceManagerConnected( + content::ServiceManagerConnection* connection) { +#if !defined(OS_FUCHSIA) + static base::NoDestructor<heap_profiling::Client> profiling_client; + + std::unique_ptr<service_manager::BinderRegistry> registry( + std::make_unique<service_manager::BinderRegistry>()); + registry->AddInterface( + base::BindRepeating(&heap_profiling::Client::BindToInterface, + base::Unretained(profiling_client.get()))); + connection->AddConnectionFilter( + std::make_unique<content::SimpleConnectionFilter>(std::move(registry))); +#endif // !defined(OS_FUCHSIA) +} + } // namespace shell } // namespace chromecast
diff --git a/chromecast/common/cast_content_client.h b/chromecast/common/cast_content_client.h index b3cd2aec..f535ae7 100644 --- a/chromecast/common/cast_content_client.h +++ b/chromecast/common/cast_content_client.h
@@ -31,6 +31,8 @@ #if defined(OS_ANDROID) ::media::MediaDrmBridgeClient* GetMediaDrmBridgeClient() override; #endif // OS_ANDROID + void OnServiceManagerConnected( + content::ServiceManagerConnection* connection) override; private: GURL last_active_url_;
diff --git a/chromecast/utility/BUILD.gn b/chromecast/utility/BUILD.gn index a9e2938..421cd0e 100644 --- a/chromecast/utility/BUILD.gn +++ b/chromecast/utility/BUILD.gn
@@ -17,4 +17,15 @@ if (chromecast_branding == "public") { sources += [ "cast_content_utility_client_simple.cc" ] } + + if (!is_fuchsia) { + sources += [ "cast_content_utility_client.cc" ] + + deps += [ + "//chromecast:chromecast_buildflags", + "//components/services/heap_profiling", + "//components/services/heap_profiling/public/mojom", + "//services/service_manager/public/cpp", + ] + } }
diff --git a/chromecast/utility/DEPS b/chromecast/utility/DEPS index 8ad521e..6ab23ad 100644 --- a/chromecast/utility/DEPS +++ b/chromecast/utility/DEPS
@@ -1,3 +1,5 @@ include_rules = [ + "+components/services/heap_profiling", + "+components/services/heap_profiling/public/mojom", "+content/public/utility", ]
diff --git a/chromecast/utility/cast_content_utility_client.cc b/chromecast/utility/cast_content_utility_client.cc new file mode 100644 index 0000000..39d76f7e --- /dev/null +++ b/chromecast/utility/cast_content_utility_client.cc
@@ -0,0 +1,58 @@ +// 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 "chromecast/utility/cast_content_utility_client.h" + +#include <string> +#include <utility> + +#include "base/callback_forward.h" +#include "components/services/heap_profiling/heap_profiling_service.h" +#include "components/services/heap_profiling/public/mojom/constants.mojom.h" +#include "content/public/utility/utility_thread.h" + +namespace { + +std::unique_ptr<service_manager::Service> CreateHeapProfilingService( + service_manager::mojom::ServiceRequest request) { + return std::make_unique<heap_profiling::HeapProfilingService>( + std::move(request)); +} + +using ServiceFactory = + base::OnceCallback<std::unique_ptr<service_manager::Service>()>; +void RunServiceOnIOThread(ServiceFactory factory) { + base::OnceClosure terminate_process = base::BindOnce( + base::IgnoreResult(&base::SequencedTaskRunner::PostTask), + base::SequencedTaskRunnerHandle::Get(), FROM_HERE, + base::BindOnce([] { content::UtilityThread::Get()->ReleaseProcess(); })); + content::ChildThread::Get()->GetIOTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + [](ServiceFactory factory, base::OnceClosure terminate_process) { + service_manager::Service::RunAsyncUntilTermination( + std::move(factory).Run(), std::move(terminate_process)); + }, + std::move(factory), std::move(terminate_process))); +} + +} // namespace + +namespace chromecast { +namespace shell { + +bool CastContentUtilityClient::HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) { + if (service_name == heap_profiling::mojom::kServiceName) { + RunServiceOnIOThread( + base::BindOnce(&CreateHeapProfilingService, std::move(request))); + return true; + } + + return false; +} + +} // namespace shell +} // namespace chromecast
diff --git a/chromecast/utility/cast_content_utility_client.h b/chromecast/utility/cast_content_utility_client.h index 7f7528d..5f04c27 100644 --- a/chromecast/utility/cast_content_utility_client.h +++ b/chromecast/utility/cast_content_utility_client.h
@@ -6,8 +6,10 @@ #define CHROMECAST_UTILITY_CAST_CONTENT_UTILITY_CLIENT_H_ #include <memory> +#include <string> #include "base/macros.h" +#include "build/build_config.h" #include "content/public/utility/content_utility_client.h" namespace chromecast { @@ -19,6 +21,13 @@ CastContentUtilityClient() {} +#if !defined(OS_FUCHSIA) + // content::ContentUtilityClient implementation: + bool HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) override; +#endif // !defined(OS_FUCHSIA) + private: DISALLOW_COPY_AND_ASSIGN(CastContentUtilityClient); };
diff --git a/chromeos/network/prohibited_technologies_handler.cc b/chromeos/network/prohibited_technologies_handler.cc index 0db65090..1e22cbe5 100644 --- a/chromeos/network/prohibited_technologies_handler.cc +++ b/chromeos/network/prohibited_technologies_handler.cc
@@ -4,6 +4,9 @@ #include "chromeos/network/prohibited_technologies_handler.h" +#include <set> +#include <vector> + #include "chromeos/network/managed_network_configuration_handler.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_util.h" @@ -62,7 +65,7 @@ const base::ListValue* prohibited_list) { // Build up prohibited network type list and save it for furthur use when // enforced - prohibited_technologies_.clear(); + session_prohibited_technologies_.clear(); for (const auto& item : *prohibited_list) { std::string prohibited_technology; bool item_is_string = item.GetAsString(&prohibited_technology); @@ -70,44 +73,65 @@ std::string translated_tech = network_util::TranslateONCTypeToShill(prohibited_technology); if (!translated_tech.empty()) - prohibited_technologies_.push_back(translated_tech); + session_prohibited_technologies_.push_back(translated_tech); } EnforceProhibitedTechnologies(); } void ProhibitedTechnologiesHandler::EnforceProhibitedTechnologies() { - if (user_logged_in_ && user_policy_applied_) { - network_state_handler_->SetProhibitedTechnologies( - prohibited_technologies_, network_handler::ErrorCallback()); - if (std::find(prohibited_technologies_.begin(), - prohibited_technologies_.end(), - shill::kTypeEthernet) != prohibited_technologies_.end()) - return; - } else { - // This is done to make sure prohibited technologies are cleared - // before user policy is applied. - network_state_handler_->SetProhibitedTechnologies( - std::vector<std::string>(), network_handler::ErrorCallback()); - } - + auto prohibited_technologies_ = GetCurrentlyProhibitedTechnologies(); + network_state_handler_->SetProhibitedTechnologies( + prohibited_technologies_, network_handler::ErrorCallback()); // Enable ethernet back as user doesn't have a place to enable it back // if user shuts down directly in a user session. As shill will persist // ProhibitedTechnologies which may include ethernet, making users can // not find Ethernet at next boot or logging out unless user log out first // and then shutdown. + if (std::find(prohibited_technologies_.begin(), + prohibited_technologies_.end(), + shill::kTypeEthernet) != prohibited_technologies_.end()) { + return; + } if (network_state_handler_->IsTechnologyAvailable( NetworkTypePattern::Ethernet()) && !network_state_handler_->IsTechnologyEnabled( - NetworkTypePattern::Ethernet())) + NetworkTypePattern::Ethernet())) { network_state_handler_->SetTechnologyEnabled( NetworkTypePattern::Ethernet(), true, network_handler::ErrorCallback()); + } } std::vector<std::string> ProhibitedTechnologiesHandler::GetCurrentlyProhibitedTechnologies() { - if (user_logged_in_ && user_policy_applied_) - return prohibited_technologies_; - return std::vector<std::string>(); + if (!user_logged_in_ || !user_policy_applied_) + return globally_prohibited_technologies_; + std::set<std::string> prohibited_set; + prohibited_set.insert(session_prohibited_technologies_.begin(), + session_prohibited_technologies_.end()); + prohibited_set.insert(globally_prohibited_technologies_.begin(), + globally_prohibited_technologies_.end()); + std::vector<std::string> prohibited_list(prohibited_set.begin(), + prohibited_set.end()); + return prohibited_list; +} + +void ProhibitedTechnologiesHandler::AddGloballyProhibitedTechnology( + const std::string& technology) { + if (std::find(globally_prohibited_technologies_.begin(), + globally_prohibited_technologies_.end(), + technology) == globally_prohibited_technologies_.end()) { + globally_prohibited_technologies_.push_back(technology); + } + EnforceProhibitedTechnologies(); +} + +void ProhibitedTechnologiesHandler::RemoveGloballyProhibitedTechnology( + const std::string& technology) { + auto it = std::find(globally_prohibited_technologies_.begin(), + globally_prohibited_technologies_.end(), technology); + if (it != globally_prohibited_technologies_.end()) + globally_prohibited_technologies_.erase(it); + EnforceProhibitedTechnologies(); } } // namespace chromeos
diff --git a/chromeos/network/prohibited_technologies_handler.h b/chromeos/network/prohibited_technologies_handler.h index 426fbbb..3a10686 100644 --- a/chromeos/network/prohibited_technologies_handler.h +++ b/chromeos/network/prohibited_technologies_handler.h
@@ -6,6 +6,7 @@ #define CHROMEOS_NETWORK_PROHIBITED_TECHNOLOGIES_HANDLER_H_ #include <string> +#include <vector> #include "base/component_export.h" #include "base/macros.h" @@ -28,8 +29,15 @@ // NetworkPolicyObserver void PoliciesChanged(const std::string& userhash) override; void PoliciesApplied(const std::string& userhash) override; - + // Function for updating the list of technologies that are prohibited during + // user sessions void SetProhibitedTechnologies(const base::ListValue* prohibited_list); + // Functions for updating the list of technologies that are prohibited + // everywhere, including login screen + void AddGloballyProhibitedTechnology(const std::string& prohibited_list); + void RemoveGloballyProhibitedTechnology(const std::string& technology); + // Returns the currently active list of prohibited + // technologies(session-dependent and globally-prohibited ones) std::vector<std::string> GetCurrentlyProhibitedTechnologies(); private: @@ -44,7 +52,12 @@ void EnforceProhibitedTechnologies(); - std::vector<std::string> prohibited_technologies_; + // These only apply in user or kiosk sessions. + std::vector<std::string> session_prohibited_technologies_; + // Network technologies that are prohibited not only in user sessions, but at + // all time. + std::vector<std::string> globally_prohibited_technologies_; + ManagedNetworkConfigurationHandler* managed_network_configuration_handler_ = nullptr; NetworkStateHandler* network_state_handler_ = nullptr;
diff --git a/chromeos/network/prohibited_technologies_handler_unittest.cc b/chromeos/network/prohibited_technologies_handler_unittest.cc index 478a0bc..0d3c50c 100644 --- a/chromeos/network/prohibited_technologies_handler_unittest.cc +++ b/chromeos/network/prohibited_technologies_handler_unittest.cc
@@ -106,12 +106,13 @@ base::DictionaryValue global_config_disable_wifi; base::DictionaryValue global_config_disable_wifi_and_cell; + std::unique_ptr<ProhibitedTechnologiesHandler> + prohibited_technologies_handler_; private: base::test::ScopedTaskEnvironment scoped_task_environment_; NetworkStateTestHelper helper_{false /* use_default_devices_and_services */}; - std::unique_ptr<ProhibitedTechnologiesHandler> - prohibited_technologies_handler_; + std::unique_ptr<NetworkConfigurationHandler> network_config_handler_; std::unique_ptr<ManagedNetworkConfigurationHandlerImpl> managed_config_handler_; @@ -179,4 +180,66 @@ NetworkTypePattern::Cellular())); } +TEST_F(ProhibitedTechnologiesHandlerTest, + IsGloballyProhibitedTechnologyWorksAfterReenabling) { + LoginToRegularUser(); + SetupPolicy(base::DictionaryValue(), true); // wait for user policy + + EXPECT_TRUE( + network_state_handler()->IsTechnologyEnabled(NetworkTypePattern::WiFi())); + prohibited_technologies_handler_->AddGloballyProhibitedTechnology( + shill::kTypeWifi); + EXPECT_FALSE( + network_state_handler()->IsTechnologyEnabled(NetworkTypePattern::WiFi())); + + // Enabling it back + prohibited_technologies_handler_->RemoveGloballyProhibitedTechnology( + shill::kTypeWifi); + network_state_handler()->SetTechnologyEnabled( + NetworkTypePattern::WiFi(), true, network_handler::ErrorCallback()); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE( + network_state_handler()->IsTechnologyEnabled(NetworkTypePattern::WiFi())); +} + +TEST_F(ProhibitedTechnologiesHandlerTest, + InteractionBetweenGloballyAndSessionsProhibitedTechnologies) { + // Set session prohibiting of Cellular, should not prohibit on login screen + SetupPolicy(global_config_disable_wifi_and_cell, false); + EXPECT_TRUE(network_state_handler()->IsTechnologyEnabled( + NetworkTypePattern::Cellular())); + + LoginToRegularUser(); + SetupPolicy(base::DictionaryValue(), true); // receive user policy + // Cellular should be prohibited + EXPECT_FALSE(network_state_handler()->IsTechnologyEnabled( + NetworkTypePattern::Cellular())); + + // Should be prohibited after adding to globally prohibited list + prohibited_technologies_handler_->AddGloballyProhibitedTechnology( + shill::kTypeCellular); + network_state_handler()->SetTechnologyEnabled( + NetworkTypePattern::Cellular(), true, network_handler::ErrorCallback()); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(network_state_handler()->IsTechnologyEnabled( + NetworkTypePattern::Cellular())); + + // Should be prohibited after removing from globally prohibited list + prohibited_technologies_handler_->RemoveGloballyProhibitedTechnology( + shill::kTypeCellular); + network_state_handler()->SetTechnologyEnabled( + NetworkTypePattern::Cellular(), true, network_handler::ErrorCallback()); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(network_state_handler()->IsTechnologyEnabled( + NetworkTypePattern::Cellular())); + + // Should not be prohibited after updating session prohibited list. + SetupPolicy(global_config_disable_wifi, false); + network_state_handler()->SetTechnologyEnabled( + NetworkTypePattern::Cellular(), true, network_handler::ErrorCallback()); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(network_state_handler()->IsTechnologyEnabled( + NetworkTypePattern::Cellular())); +} + } // namespace chromeos
diff --git a/chromeos/settings/cros_settings_names.cc b/chromeos/settings/cros_settings_names.cc index eaccadd9a..8dff5c6 100644 --- a/chromeos/settings/cros_settings_names.cc +++ b/chromeos/settings/cros_settings_names.cc
@@ -253,6 +253,10 @@ // device. const char kAllowBluetooth[] = "cros.device.allow_bluetooth"; +// A boolean pref that indicates whether WiFi should be allowed on the +// device. +const char kDeviceWiFiAllowed[] = "cros.device.wifi_allowed"; + // A boolean pref to enable any pings or requests to the Quirks Server. const char kDeviceQuirksDownloadEnabled[] = "cros.device.quirks_download_enabled";
diff --git a/chromeos/settings/cros_settings_names.h b/chromeos/settings/cros_settings_names.h index 850acdb..9cc2c42 100644 --- a/chromeos/settings/cros_settings_names.h +++ b/chromeos/settings/cros_settings_names.h
@@ -155,6 +155,8 @@ COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kAllowBluetooth[]; +COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kDeviceWiFiAllowed[]; + COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kDeviceQuirksDownloadEnabled[];
diff --git a/cloud_print/virtual_driver/win/virtual_driver_helpers.cc b/cloud_print/virtual_driver/win/virtual_driver_helpers.cc index e7e7e9f..d26dc62 100644 --- a/cloud_print/virtual_driver/win/virtual_driver_helpers.cc +++ b/cloud_print/virtual_driver/win/virtual_driver_helpers.cc
@@ -47,7 +47,7 @@ bool IsSystem64Bit() { base::win::OSInfo::WindowsArchitecture arch = - base::win::OSInfo::GetInstance()->architecture(); + base::win::OSInfo::GetArchitecture(); return (arch == base::win::OSInfo::X64_ARCHITECTURE) || (arch == base::win::OSInfo::IA64_ARCHITECTURE); }
diff --git a/components/certificate_transparency/log_dns_client_unittest.cc b/components/certificate_transparency/log_dns_client_unittest.cc index 93da272..7922234 100644 --- a/components/certificate_transparency/log_dns_client_unittest.cc +++ b/components/certificate_transparency/log_dns_client_unittest.cc
@@ -1001,7 +1001,7 @@ rules.emplace_back( kLeafIndexQnames[0], net::dns_protocol::kTypeTXT, net::SecureDnsMode::SECURE, - net::MockDnsClientRule::CreateSecureResult(net::BuildTestDnsResponse( + net::MockDnsClientRule::CreateSecureResult(net::BuildTestDnsTextResponse( kLeafIndexQnames[0], std::vector<std::vector<std::string>>({{"123456"}}))), false /* delay */); @@ -1014,11 +1014,13 @@ rules.emplace_back( base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin), net::dns_protocol::kTypeTXT, net::SecureDnsMode::SECURE, - net::MockDnsClientRule::CreateSecureResult(net::BuildTestDnsResponse( - base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin), - {{std::accumulate(audit_proof.begin() + nodes_begin, - audit_proof.begin() + nodes_end, - std::string())}})), + net::MockDnsClientRule::CreateSecureResult( + net::BuildTestDnsTextResponse( + base::StringPrintf("%zu.123456.999999.tree.ct.test.", + nodes_begin), + {{std::accumulate(audit_proof.begin() + nodes_begin, + audit_proof.begin() + nodes_end, + std::string())}})), false /* delay */ ); } @@ -1047,12 +1049,12 @@ net::MockDnsClientRuleList rules; // Make leaf index queries for kLeafIndexQnames[0] successful only when // lookup_securely is false. - rules.emplace_back(kLeafIndexQnames[0], net::dns_protocol::kTypeTXT, - net::SecureDnsMode::OFF, - net::MockDnsClientRule::Result(net::BuildTestDnsResponse( - kLeafIndexQnames[0], - std::vector<std::vector<std::string>>({{"123456"}}))), - false /* delay */); + rules.emplace_back( + kLeafIndexQnames[0], net::dns_protocol::kTypeTXT, net::SecureDnsMode::OFF, + net::MockDnsClientRule::Result(net::BuildTestDnsTextResponse( + kLeafIndexQnames[0], + std::vector<std::vector<std::string>>({{"123456"}}))), + false /* delay */); // Add successful audit proof queries for lookup_securely false. for (size_t nodes_begin = 0; nodes_begin < audit_proof.size(); @@ -1062,7 +1064,7 @@ rules.emplace_back( base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin), net::dns_protocol::kTypeTXT, net::SecureDnsMode::OFF, - net::MockDnsClientRule::Result(net::BuildTestDnsResponse( + net::MockDnsClientRule::Result(net::BuildTestDnsTextResponse( base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin), {{std::accumulate(audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end,
diff --git a/components/cronet/native/url_request.cc b/components/cronet/native/url_request.cc index 3ebdc44..6dcec9a2 100644 --- a/components/cronet/native/url_request.cc +++ b/components/cronet/native/url_request.cc
@@ -587,7 +587,6 @@ DCHECK(url_request); } -// CronetURLRequest::NetworkTasks implementations: void Cronet_UrlRequestImpl::NetworkTasks::OnReceivedRedirect( const std::string& new_location, int http_status_code,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc index c34ddde5..ceaa57ba 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
@@ -411,6 +411,9 @@ request_options_->AddRequestHeader(&config->post_cache_headers, base::nullopt); + + config->assume_https_proxies_support_quic = true; + return config; }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc index 9ebaa95..3eb42af 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
@@ -408,4 +408,29 @@ EXPECT_TRUE(client.config->alternate_rules.Equals(expected_rules)); } +TEST_F(DataReductionProxyIODataTest, + TestCustomProxyConfigAssumesHttpsProxiesSupportQuic) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kDisableDataReductionProxyWarmupURLFetch); + DataReductionProxyIOData io_data( + Client::UNKNOWN, prefs(), + network::TestNetworkConnectionTracker::GetInstance(), + scoped_task_environment_.GetMainThreadTaskRunner(), + scoped_task_environment_.GetMainThreadTaskRunner(), false /* enabled */, + std::string() /* user_agent */, std::string() /* channel */); + NetworkPropertiesManager network_properties_manager( + base::DefaultClock::GetInstance(), prefs(), + scoped_task_environment_.GetMainThreadTaskRunner()); + io_data.config()->SetNetworkPropertiesManagerForTesting( + &network_properties_manager); + io_data.config()->UpdateConfigForTesting(true, true, true); + + network::mojom::CustomProxyConfigClientPtrInfo client_ptr_info; + TestCustomProxyConfigClient client(mojo::MakeRequest(&client_ptr_info)); + io_data.SetCustomProxyConfigClient(std::move(client_ptr_info)); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(client.config->assume_https_proxies_support_quic); +} + } // namespace data_reduction_proxy
diff --git a/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc b/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc index ef960e1..38b3467 100644 --- a/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc +++ b/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc
@@ -43,10 +43,6 @@ DCHECK(CalledOnValidThread()); DCHECK_EQ(NOT_RUNNING, state()); - if (DisableTypeIfNecessary()) { - return; - } - sync_service_->AddObserver(this); SyncableServiceBasedModelTypeController::LoadModels(configure_context, model_load_callback); @@ -66,27 +62,8 @@ void HistoryDeleteDirectivesModelTypeController::OnStateChanged( syncer::SyncService* sync) { DCHECK(CalledOnValidThread()); - DisableTypeIfNecessary(); -} - -bool HistoryDeleteDirectivesModelTypeController::DisableTypeIfNecessary() { - DCHECK(CalledOnValidThread()); - - if (!sync_service_->IsSyncFeatureActive()) { - return false; - } - - if (ReadyForStart()) { - return false; - } - - sync_service_->RemoveObserver(this); - - ReportModelError( - syncer::SyncError::DATATYPE_POLICY_ERROR, - syncer::ModelError(FROM_HERE, - "Delete directives not supported with encryption.")); - return true; + // Most of these calls will be no-ops but SyncService handles that just fine. + sync_service_->ReadyForStartChanged(type()); } } // namespace browser_sync
diff --git a/components/history/core/browser/sync/history_delete_directives_model_type_controller.h b/components/history/core/browser/sync/history_delete_directives_model_type_controller.h index 4c43cbb..93cb9d3 100644 --- a/components/history/core/browser/sync/history_delete_directives_model_type_controller.h +++ b/components/history/core/browser/sync/history_delete_directives_model_type_controller.h
@@ -44,10 +44,6 @@ void OnStateChanged(syncer::SyncService* sync) override; private: - // Triggers a SingleDataTypeUnrecoverable error and returns true if the - // type is no longer ready, else does nothing and returns false. - bool DisableTypeIfNecessary(); - syncer::SyncService* const sync_service_; DISALLOW_COPY_AND_ASSIGN(HistoryDeleteDirectivesModelTypeController);
diff --git a/components/keyed_service/content/browser_context_dependency_manager.cc b/components/keyed_service/content/browser_context_dependency_manager.cc index 3179ba48..e5a255e 100644 --- a/components/keyed_service/content/browser_context_dependency_manager.cc +++ b/components/keyed_service/content/browser_context_dependency_manager.cc
@@ -19,12 +19,11 @@ #endif // NDEBUG void BrowserContextDependencyManager::RegisterProfilePrefsForServices( - content::BrowserContext* context, user_prefs::PrefRegistrySyncable* pref_registry) { TRACE_EVENT0( "browser", "BrowserContextDependencyManager::RegisterProfilePrefsForServices"); - RegisterPrefsForServices(context, pref_registry); + RegisterPrefsForServices(pref_registry); } void BrowserContextDependencyManager::CreateBrowserContextServices(
diff --git a/components/keyed_service/content/browser_context_dependency_manager.h b/components/keyed_service/content/browser_context_dependency_manager.h index bf434adec..b32c804 100644 --- a/components/keyed_service/content/browser_context_dependency_manager.h +++ b/components/keyed_service/content/browser_context_dependency_manager.h
@@ -38,7 +38,6 @@ // a key to prevent multiple registrations on the same BrowserContext in // tests. void RegisterProfilePrefsForServices( - content::BrowserContext* context, user_prefs::PrefRegistrySyncable* registry); // Called by each BrowserContext to alert us of its creation. Several
diff --git a/components/keyed_service/core/dependency_manager.cc b/components/keyed_service/core/dependency_manager.cc index 9395b86..14b20f96 100644 --- a/components/keyed_service/core/dependency_manager.cc +++ b/components/keyed_service/core/dependency_manager.cc
@@ -35,7 +35,6 @@ } void DependencyManager::RegisterPrefsForServices( - void* context, user_prefs::PrefRegistrySyncable* pref_registry) { std::vector<DependencyNode*> construction_order; if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
diff --git a/components/keyed_service/core/dependency_manager.h b/components/keyed_service/core/dependency_manager.h index 0f881a9..14401d5 100644 --- a/components/keyed_service/core/dependency_manager.h +++ b/components/keyed_service/core/dependency_manager.h
@@ -38,11 +38,8 @@ void AddEdge(KeyedServiceBaseFactory* depended, KeyedServiceBaseFactory* dependee); - // Registers preferences for all services via |registry| associated with - // |context| (the association is managed by the embedder). The |context| - // is used as a key to prevent multiple registration during tests. - void RegisterPrefsForServices(void* context, - user_prefs::PrefRegistrySyncable* registry); + // Registers preferences for all services via |registry|. + void RegisterPrefsForServices(user_prefs::PrefRegistrySyncable* registry); // Called upon creation of |context| to create services that want to be // started at the creation of a context and register service-related
diff --git a/components/keyed_service/core/simple_dependency_manager.cc b/components/keyed_service/core/simple_dependency_manager.cc index 385ca3ac..3b8814e 100644 --- a/components/keyed_service/core/simple_dependency_manager.cc +++ b/components/keyed_service/core/simple_dependency_manager.cc
@@ -32,11 +32,10 @@ } void SimpleDependencyManager::RegisterProfilePrefsForServices( - SimpleFactoryKey* key, user_prefs::PrefRegistrySyncable* pref_registry) { TRACE_EVENT0("browser", "SimpleDependencyManager::RegisterProfilePrefsForServices"); - RegisterPrefsForServices(key, pref_registry); + RegisterPrefsForServices(pref_registry); } void SimpleDependencyManager::CreateServicesForTest(SimpleFactoryKey* key) {
diff --git a/components/keyed_service/core/simple_dependency_manager.h b/components/keyed_service/core/simple_dependency_manager.h index 817a5ed..005537d 100644 --- a/components/keyed_service/core/simple_dependency_manager.h +++ b/components/keyed_service/core/simple_dependency_manager.h
@@ -27,7 +27,6 @@ // |key| is used to prevent multiple registrations on the same BrowserContext // in tests. void RegisterProfilePrefsForServices( - SimpleFactoryKey* key, user_prefs::PrefRegistrySyncable* pref_registry); // Create services for test BrowserContexts - these contexts will not create
diff --git a/components/keyed_service/ios/browser_state_dependency_manager.cc b/components/keyed_service/ios/browser_state_dependency_manager.cc index d9c8577..3815ea9c 100644 --- a/components/keyed_service/ios/browser_state_dependency_manager.cc +++ b/components/keyed_service/ios/browser_state_dependency_manager.cc
@@ -14,9 +14,8 @@ } void BrowserStateDependencyManager::RegisterBrowserStatePrefsForServices( - web::BrowserState* context, user_prefs::PrefRegistrySyncable* pref_registry) { - RegisterPrefsForServices(context, pref_registry); + RegisterPrefsForServices(pref_registry); } void BrowserStateDependencyManager::CreateBrowserStateServices(
diff --git a/components/keyed_service/ios/browser_state_dependency_manager.h b/components/keyed_service/ios/browser_state_dependency_manager.h index 96c6743..2ad8cf8 100644 --- a/components/keyed_service/ios/browser_state_dependency_manager.h +++ b/components/keyed_service/ios/browser_state_dependency_manager.h
@@ -33,11 +33,7 @@ static BrowserStateDependencyManager* GetInstance(); // Registers context-specific preferences for all services via |registry|. - // |context| should be the BrowserState containing |registry| and is used as - // a key to prevent multiple registrations on the same BrowserState in - // tests. void RegisterBrowserStatePrefsForServices( - web::BrowserState* context, user_prefs::PrefRegistrySyncable* registry); // Called by each BrowserState to alert us of its creation. Service that
diff --git a/components/nacl/renderer/platform_info.cc b/components/nacl/renderer/platform_info.cc index 032af94..cb1ad6c 100644 --- a/components/nacl/renderer/platform_info.cc +++ b/components/nacl/renderer/platform_info.cc
@@ -23,7 +23,7 @@ #if defined(OS_WIN) // We have to check the host architecture on Windows. // See sandbox_isa.h for an explanation why. - if (base::win::OSInfo::GetInstance()->architecture() == + if (base::win::OSInfo::GetArchitecture() == base::win::OSInfo::X64_ARCHITECTURE) { return "x86-64"; }
diff --git a/components/password_manager/content/browser/content_password_manager_driver.cc b/components/password_manager/content/browser/content_password_manager_driver.cc index 2e1d54c..2df827d 100644 --- a/components/password_manager/content/browser/content_password_manager_driver.cc +++ b/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -34,7 +34,7 @@ autofill::AutofillClient* autofill_client) : render_frame_host_(render_frame_host), client_(client), - password_generation_manager_(client, this), + password_generation_helper_(client, this), password_autofill_manager_(this, autofill_client, client), is_main_frame_(render_frame_host->GetParent() == nullptr), weak_factory_(this) { @@ -74,7 +74,7 @@ void ContentPasswordManagerDriver::AllowPasswordGenerationForForm( const autofill::PasswordForm& form) { - if (GetPasswordGenerationManager()->IsGenerationEnabled( + if (GetPasswordGenerationHelper()->IsGenerationEnabled( /*log_debug_data=*/true)) { GetPasswordGenerationAgent()->FormNotBlacklisted(form); } @@ -87,7 +87,7 @@ void ContentPasswordManagerDriver::FormEligibleForGenerationFound( const autofill::NewPasswordFormGenerationData& form) { - if (GetPasswordGenerationManager()->IsGenerationEnabled( + if (GetPasswordGenerationHelper()->IsGenerationEnabled( /*log_debug_data=*/true)) { GetPasswordGenerationAgent()->FoundFormEligibleForGeneration(form); } @@ -135,9 +135,9 @@ GetAutofillAgent()->ClearPreviewedForm(); } -PasswordGenerationManager* -ContentPasswordManagerDriver::GetPasswordGenerationManager() { - return &password_generation_manager_; +PasswordGenerationFrameHelper* +ContentPasswordManagerDriver::GetPasswordGenerationHelper() { + return &password_generation_helper_; } PasswordManager* ContentPasswordManagerDriver::GetPasswordManager() {
diff --git a/components/password_manager/content/browser/content_password_manager_driver.h b/components/password_manager/content/browser/content_password_manager_driver.h index ff901b7..54d0acf0 100644 --- a/components/password_manager/content/browser/content_password_manager_driver.h +++ b/components/password_manager/content/browser/content_password_manager_driver.h
@@ -15,7 +15,7 @@ #include "components/autofill/core/common/password_form_field_prediction_map.h" #include "components/autofill/core/common/password_form_generation_data.h" #include "components/password_manager/core/browser/password_autofill_manager.h" -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/password_manager/core/browser/password_generation_frame_helper.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/password_manager/core/browser/password_manager_driver.h" #include "mojo/public/cpp/bindings/associated_binding.h" @@ -70,7 +70,7 @@ void ShowInitialPasswordAccountSuggestions( const autofill::PasswordFormFillData& form_data) override; void ClearPreviewedForm() override; - PasswordGenerationManager* GetPasswordGenerationManager() override; + PasswordGenerationFrameHelper* GetPasswordGenerationHelper() override; PasswordManager* GetPasswordManager() override; PasswordAutofillManager* GetPasswordAutofillManager() override; void SendLoggingAvailability() override; @@ -98,7 +98,7 @@ content::RenderFrameHost* render_frame_host_; PasswordManagerClient* client_; - PasswordGenerationManager password_generation_manager_; + PasswordGenerationFrameHelper password_generation_helper_; PasswordAutofillManager password_autofill_manager_; // It should be filled in the constructor, since later the frame might be
diff --git a/components/password_manager/content/browser/content_password_manager_driver_factory.h b/components/password_manager/content/browser/content_password_manager_driver_factory.h index 42bdb01..46d35215 100644 --- a/components/password_manager/content/browser/content_password_manager_driver_factory.h +++ b/components/password_manager/content/browser/content_password_manager_driver_factory.h
@@ -13,7 +13,7 @@ #include "base/supports_user_data.h" #include "components/autofill/content/common/autofill_driver.mojom.h" #include "components/password_manager/core/browser/password_autofill_manager.h" -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/password_manager/core/browser/password_generation_frame_helper.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/password_manager/core/browser/password_manager_driver.h" #include "content/public/browser/web_contents_observer.h"
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index c227c0a..0823251 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -109,8 +109,8 @@ "password_form_metrics_recorder.cc", "password_form_metrics_recorder.h", "password_form_user_action.h", - "password_generation_manager.cc", - "password_generation_manager.h", + "password_generation_frame_helper.cc", + "password_generation_frame_helper.h", "password_list_sorter.cc", "password_list_sorter.h", "password_manager.cc", @@ -426,7 +426,7 @@ "password_form_filling_unittest.cc", "password_form_manager_unittest.cc", "password_form_metrics_recorder_unittest.cc", - "password_generation_manager_unittest.cc", + "password_generation_frame_helper_unittest.cc", "password_hash_data_unittest.cc", "password_list_sorter_unittest.cc", "password_manager_metrics_recorder_unittest.cc",
diff --git a/components/password_manager/core/browser/password_generation_manager.cc b/components/password_manager/core/browser/password_generation_frame_helper.cc similarity index 91% rename from components/password_manager/core/browser/password_generation_manager.cc rename to components/password_manager/core/browser/password_generation_frame_helper.cc index 86ffe46..d3ce4259 100644 --- a/components/password_manager/core/browser/password_generation_manager.cc +++ b/components/password_manager/core/browser/password_generation_frame_helper.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/password_manager/core/browser/password_generation_frame_helper.h" #include "base/optional.h" #include "components/autofill/core/browser/autofill_field.h" @@ -30,16 +30,14 @@ using Logger = autofill::SavePasswordProgressLogger; } -PasswordGenerationManager::PasswordGenerationManager( +PasswordGenerationFrameHelper::PasswordGenerationFrameHelper( PasswordManagerClient* client, PasswordManagerDriver* driver) - : client_(client), driver_(driver) { -} + : client_(client), driver_(driver) {} -PasswordGenerationManager::~PasswordGenerationManager() { -} +PasswordGenerationFrameHelper::~PasswordGenerationFrameHelper() = default; -void PasswordGenerationManager::PrefetchSpec(const GURL& origin) { +void PasswordGenerationFrameHelper::PrefetchSpec(const GURL& origin) { // IsGenerationEnabled is called multiple times and it is sufficient to // log debug data once. if (!IsGenerationEnabled(/*log_debug_data=*/false)) @@ -56,7 +54,7 @@ password_requirements_service->PrefetchSpec(origin); } -void PasswordGenerationManager::ProcessPasswordRequirements( +void PasswordGenerationFrameHelper::ProcessPasswordRequirements( const std::vector<autofill::FormStructure*>& forms) { // IsGenerationEnabled is called multiple times and it is sufficient to // log debug data once. @@ -82,7 +80,7 @@ } } -void PasswordGenerationManager::DetectFormsEligibleForGeneration( +void PasswordGenerationFrameHelper::DetectFormsEligibleForGeneration( const std::vector<autofill::FormStructure*>& forms) { if (base::FeatureList::IsEnabled(features::kNewPasswordFormParsing)) { // NewPasswordFormManager sends this information to the renderer. @@ -123,7 +121,8 @@ // In order for password generation to be enabled, we need to make sure: // (1) Password sync is enabled, and // (2) Password saving is enabled. -bool PasswordGenerationManager::IsGenerationEnabled(bool log_debug_data) const { +bool PasswordGenerationFrameHelper::IsGenerationEnabled( + bool log_debug_data) const { std::unique_ptr<Logger> logger; if (log_debug_data && password_manager_util::IsLoggingActive(client_)) { logger.reset( @@ -144,7 +143,7 @@ return false; } -base::string16 PasswordGenerationManager::GeneratePassword( +base::string16 PasswordGenerationFrameHelper::GeneratePassword( const GURL& last_committed_url, autofill::FormSignature form_signature, autofill::FieldSignature field_signature,
diff --git a/components/password_manager/core/browser/password_generation_manager.h b/components/password_manager/core/browser/password_generation_frame_helper.h similarity index 81% rename from components/password_manager/core/browser/password_generation_manager.h rename to components/password_manager/core/browser/password_generation_frame_helper.h index dbe7becd..a53ec61 100644 --- a/components/password_manager/core/browser/password_generation_manager.h +++ b/components/password_manager/core/browser/password_generation_frame_helper.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_GENERATION_MANAGER_H_ -#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_GENERATION_MANAGER_H_ +#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_GENERATION_FRAME_HELPER_H_ +#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_GENERATION_FRAME_HELPER_H_ #include <vector> @@ -21,24 +21,19 @@ class PasswordManagerClient; class PasswordManagerDriver; -// Per-tab manager for password generation. Will enable this feature only if +// Per-frame helper for password generation. Will enable this feature only if // // - Password manager is enabled // - Password sync is enabled // -// NOTE: At the moment, the creation of the renderer PasswordGenerationManager -// is controlled by a switch (--enable-password-generation) so this feature will -// not be enabled regardless of the above criteria without the switch being -// present. -// // This class is used to determine what forms we should offer to generate // passwords for and manages the popup which is created if the user chooses to // generate a password. -class PasswordGenerationManager { +class PasswordGenerationFrameHelper { public: - PasswordGenerationManager(PasswordManagerClient* client, - PasswordManagerDriver* driver); - virtual ~PasswordGenerationManager(); + PasswordGenerationFrameHelper(PasswordManagerClient* client, + PasswordManagerDriver* driver); + virtual ~PasswordGenerationFrameHelper(); // Instructs the PasswordRequirementsService to fetch requirements for // |origin|. This needs to be called to enable domain-wide password @@ -81,7 +76,7 @@ uint32_t* spec_priority); private: - friend class PasswordGenerationManagerTest; + friend class PasswordGenerationFrameHelperTest; // The PasswordManagerClient instance associated with this instance. Must // outlive this instance. @@ -91,9 +86,9 @@ // outlive this instance. PasswordManagerDriver* driver_; - DISALLOW_COPY_AND_ASSIGN(PasswordGenerationManager); + DISALLOW_COPY_AND_ASSIGN(PasswordGenerationFrameHelper); }; } // namespace password_manager -#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_GENERATION_MANAGER_H_ +#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_GENERATION_FRAME_HELPER_H_
diff --git a/components/password_manager/core/browser/password_generation_manager_unittest.cc b/components/password_manager/core/browser/password_generation_frame_helper_unittest.cc similarity index 94% rename from components/password_manager/core/browser/password_generation_manager_unittest.cc rename to components/password_manager/core/browser/password_generation_frame_helper_unittest.cc index 2d6923a..29c0435 100644 --- a/components/password_manager/core/browser/password_generation_manager_unittest.cc +++ b/components/password_manager/core/browser/password_generation_frame_helper_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/password_manager/core/browser/password_generation_frame_helper.h" #include <memory> #include <utility> @@ -60,7 +60,7 @@ ~TestPasswordManagerDriver() override {} // PasswordManagerDriver implementation. - PasswordGenerationManager* GetPasswordGenerationManager() override { + PasswordGenerationFrameHelper* GetPasswordGenerationHelper() override { return &password_generation_manager_; } PasswordManager* GetPasswordManager() override { return &password_manager_; } @@ -83,7 +83,7 @@ private: PasswordManager password_manager_; - PasswordGenerationManager password_generation_manager_; + PasswordGenerationFrameHelper password_generation_manager_; PasswordAutofillManager password_autofill_manager_; std::vector<autofill::PasswordFormGenerationData> found_forms_eligible_for_generation_; @@ -162,7 +162,7 @@ } // anonymous namespace -class PasswordGenerationManagerTest : public testing::Test { +class PasswordGenerationFrameHelperTest : public testing::Test { protected: void SetUp() override { // Construct a PrefService and register all necessary prefs before handing @@ -177,26 +177,26 @@ void TearDown() override { client_.reset(); } - PasswordGenerationManager* GetGenerationManager() { - return client_->test_driver()->GetPasswordGenerationManager(); + PasswordGenerationFrameHelper* GetGenerationHelper() { + return client_->test_driver()->GetPasswordGenerationHelper(); } TestPasswordManagerDriver* GetTestDriver() { return client_->test_driver(); } bool IsGenerationEnabled() { - return GetGenerationManager()->IsGenerationEnabled(true); + return GetGenerationHelper()->IsGenerationEnabled(true); } void DetectFormsEligibleForGeneration( const std::vector<autofill::FormStructure*>& forms) { - GetGenerationManager()->DetectFormsEligibleForGeneration(forms); + GetGenerationHelper()->DetectFormsEligibleForGeneration(forms); } base::test::ScopedTaskEnvironment task_environment_; std::unique_ptr<MockPasswordManagerClient> client_; }; -TEST_F(PasswordGenerationManagerTest, IsGenerationEnabled) { +TEST_F(PasswordGenerationFrameHelperTest, IsGenerationEnabled) { // Enabling the PasswordManager and password sync should cause generation to // be enabled, unless the sync is with a custom passphrase. EXPECT_CALL(*client_, IsSavingAndFillingEnabled(_)) @@ -229,7 +229,7 @@ // Verify that password requirements received from the autofill server are // stored and that domain-wide password requirements are fetched as well. -TEST_F(PasswordGenerationManagerTest, ProcessPasswordRequirements) { +TEST_F(PasswordGenerationFrameHelperTest, ProcessPasswordRequirements) { // Setup so that IsGenerationEnabled() returns true. EXPECT_CALL(*client_, IsSavingAndFillingEnabled(_)) .WillRepeatedly(testing::Return(true)); @@ -318,12 +318,12 @@ autofill::FormStructure::ParseQueryResponse(response_string, forms, nullptr); - GetGenerationManager()->PrefetchSpec(origin.GetOrigin()); + GetGenerationHelper()->PrefetchSpec(origin.GetOrigin()); // Processs the password requirements with expected side effects of // either storing the requirements from the AutofillQueryResponseContents) // in the PasswordRequirementsService. - GetGenerationManager()->ProcessPasswordRequirements(forms); + GetGenerationHelper()->ProcessPasswordRequirements(forms); // Validate the result. autofill::FormSignature form_signature = @@ -337,7 +337,7 @@ } } -TEST_F(PasswordGenerationManagerTest, DetectFormsEligibleForGeneration) { +TEST_F(PasswordGenerationFrameHelperTest, DetectFormsEligibleForGeneration) { // Setup so that IsGenerationEnabled() returns true. EXPECT_CALL(*client_, IsSavingAndFillingEnabled(_)) .WillRepeatedly(testing::Return(true)); @@ -441,7 +441,7 @@ .confirmation_field_signature.value()); } -TEST_F(PasswordGenerationManagerTest, UpdatePasswordSyncStateIncognito) { +TEST_F(PasswordGenerationFrameHelperTest, UpdatePasswordSyncStateIncognito) { // Disable password manager by going incognito. Even though password // syncing is enabled, generation should still be disabled. EXPECT_CALL(*client_, IsSavingAndFillingEnabled(_))
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc index 4d42018..16d9522 100644 --- a/components/password_manager/core/browser/password_manager.cc +++ b/components/password_manager/core/browser/password_manager.cc
@@ -28,7 +28,7 @@ #include "components/password_manager/core/browser/new_password_form_manager.h" #include "components/password_manager/core/browser/password_autofill_manager.h" #include "components/password_manager/core/browser/password_form_manager.h" -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/password_manager/core/browser/password_generation_frame_helper.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_driver.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" @@ -718,8 +718,8 @@ const std::vector<PasswordForm>& forms) { CreatePendingLoginManagers(driver, forms); - PasswordGenerationManager* password_generation_manager = - driver ? driver->GetPasswordGenerationManager() : nullptr; + PasswordGenerationFrameHelper* password_generation_manager = + driver ? driver->GetPasswordGenerationHelper() : nullptr; if (password_generation_manager) { password_generation_manager->PrefetchSpec( client_->GetLastCommittedEntryURL().GetOrigin());
diff --git a/components/password_manager/core/browser/password_manager_driver.h b/components/password_manager/core/browser/password_manager_driver.h index 1206b23..1761090b 100644 --- a/components/password_manager/core/browser/password_manager_driver.h +++ b/components/password_manager/core/browser/password_manager_driver.h
@@ -27,7 +27,7 @@ namespace password_manager { class PasswordAutofillManager; -class PasswordGenerationManager; +class PasswordGenerationFrameHelper; class PasswordManager; // Interface that allows PasswordManager core code to interact with its driver @@ -94,8 +94,8 @@ // Tells the driver to clear previewed password and username fields. virtual void ClearPreviewedForm() = 0; - // Returns the PasswordGenerationManager associated with this instance. - virtual PasswordGenerationManager* GetPasswordGenerationManager() = 0; + // Returns the PasswordGenerationFrameHelper associated with this instance. + virtual PasswordGenerationFrameHelper* GetPasswordGenerationHelper() = 0; // Returns the PasswordManager associated with this instance. virtual PasswordManager* GetPasswordManager() = 0;
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc index 48ebe36..6b3d9084 100644 --- a/components/password_manager/core/browser/password_manager_util.cc +++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -21,7 +21,7 @@ #include "components/password_manager/core/browser/credentials_cleaner_runner.h" #include "components/password_manager/core/browser/http_credentials_cleaner.h" #include "components/password_manager/core/browser/log_manager.h" -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/password_manager/core/browser/password_generation_frame_helper.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_driver.h" @@ -130,8 +130,8 @@ bool ManualPasswordGenerationEnabled( password_manager::PasswordManagerDriver* driver) { - password_manager::PasswordGenerationManager* password_generation_manager = - driver ? driver->GetPasswordGenerationManager() : nullptr; + password_manager::PasswordGenerationFrameHelper* password_generation_manager = + driver ? driver->GetPasswordGenerationHelper() : nullptr; if (!password_generation_manager || !password_generation_manager->IsGenerationEnabled(false /*logging*/)) { return false;
diff --git a/components/password_manager/core/browser/stub_password_manager_driver.cc b/components/password_manager/core/browser/stub_password_manager_driver.cc index ff2e06d5..691c6a9 100644 --- a/components/password_manager/core/browser/stub_password_manager_driver.cc +++ b/components/password_manager/core/browser/stub_password_manager_driver.cc
@@ -42,8 +42,8 @@ void StubPasswordManagerDriver::ClearPreviewedForm() { } -PasswordGenerationManager* -StubPasswordManagerDriver::GetPasswordGenerationManager() { +PasswordGenerationFrameHelper* +StubPasswordManagerDriver::GetPasswordGenerationHelper() { return nullptr; }
diff --git a/components/password_manager/core/browser/stub_password_manager_driver.h b/components/password_manager/core/browser/stub_password_manager_driver.h index 0e860748..b281c5e1 100644 --- a/components/password_manager/core/browser/stub_password_manager_driver.h +++ b/components/password_manager/core/browser/stub_password_manager_driver.h
@@ -33,7 +33,7 @@ void ShowInitialPasswordAccountSuggestions( const autofill::PasswordFormFillData& form_data) override; void ClearPreviewedForm() override; - PasswordGenerationManager* GetPasswordGenerationManager() override; + PasswordGenerationFrameHelper* GetPasswordGenerationHelper() override; PasswordManager* GetPasswordManager() override; PasswordAutofillManager* GetPasswordAutofillManager() override; autofill::AutofillDriver* GetAutofillDriver() override;
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc index 8c0e968..85e03c5 100644 --- a/components/password_manager/core/common/password_manager_features.cc +++ b/components/password_manager/core/common/password_manager_features.cc
@@ -27,6 +27,7 @@ "DeleteCorruptedPasswords", base::FEATURE_DISABLED_BY_DEFAULT}; // Use HTML based username detector. +// TODO(https://crbug.com/931591): Remove this. const base::Feature kHtmlBasedUsernameDetector = { "HtmlBaseUsernameDetector", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto index f673ab22..35f3225 100644 --- a/components/policy/proto/chrome_device_policy.proto +++ b/components/policy/proto/chrome_device_policy.proto
@@ -821,6 +821,11 @@ optional bool allow_bluetooth = 1 [default = true]; } +message DeviceWiFiAllowedProto { + // Policy which controls the ability to connect to wireless networks. + optional bool device_wifi_allowed = 1 [default = true]; +} + // Settings that control whether a device can download hardware configuration // files from the Quirks Server. message DeviceQuirksDownloadEnabledProto { @@ -1262,4 +1267,5 @@ optional DeviceRebootOnUserSignoutProto device_reboot_on_user_signout = 79; optional DeviceWilcoDtcAllowedProto device_wilco_dtc_allowed = 80; optional DeviceWilcoDtcConfigurationProto device_wilco_dtc_configuration = 81; + optional DeviceWiFiAllowedProto device_wifi_allowed = 82; }
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index b068d8c..9baa254 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -796,7 +796,8 @@ 'DeviceDataRoamingEnabled', 'NetworkThrottlingEnabled', 'DeviceHostnameTemplate', - 'DeviceWiFiFastTransitionEnabled' + 'DeviceWiFiFastTransitionEnabled', + 'DeviceWiFiAllowed' ], }, { @@ -10983,6 +10984,24 @@ 'id': 501, }, { + 'name': 'DeviceWiFiAllowed', + 'device_only': True, + 'caption': '''Enable WiFi''', + 'desc': ''' + If the policy is set to false, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will disable WiFi and users cannot enable it back. + If the policy is set to true or left unset, users will be able to enable or disable WiFi as they wish.''', + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome_os:75-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': False, + }, + 'example_value': True, + 'tags': [], + 'id': 537, + }, + { 'name': 'LoginVideoCaptureAllowedUrls', 'type': 'list', 'schema': { @@ -14982,12 +15001,12 @@ }, 'example_value': True, 'id': 529, - 'caption': '''"Allow Google Access Assistant to listen for the voice activation phrase"''', + 'caption': '''Allow Google Assistant to listen for the voice activation phrase''', 'desc': '''This policy gives Google Assistant permission to listen for the voice activation phrase. If the policy is enabled, Google Assistant would listen for the voice activation phrase. If the policy is disabled, Google Assistant would not listen for the voice activation phrase. - If not set, users can decide whether to allow Google Assistant to listen to the voice activation phrase. + If the policy is not set, Google Assistant would not listen for the voice activation phrase. ''', }, { @@ -15230,5 +15249,5 @@ }, 'placeholders': [], 'deleted_policy_ids': [412], - 'highest_id_currently_used': 536 + 'highest_id_currently_used': 537 }
diff --git a/components/sync/driver/data_type_manager.h b/components/sync/driver/data_type_manager.h index 3365290..1664f84 100644 --- a/components/sync/driver/data_type_manager.h +++ b/components/sync/driver/data_type_manager.h
@@ -79,7 +79,7 @@ // Informs the data type manager that the ready-for-start status of a // controller has changed. If the controller is not ready any more, it will // stop |type|. Otherwise, it will trigger reconfiguration so that |type| gets - // started again. + // started again. No-op if the type's state didn't actually change. virtual void ReadyForStartChanged(ModelType type) = 0; // Resets all data type error state.
diff --git a/components/sync/driver/data_type_manager_impl_unittest.cc b/components/sync/driver/data_type_manager_impl_unittest.cc index 5f97069..8bf9cf9 100644 --- a/components/sync/driver/data_type_manager_impl_unittest.cc +++ b/components/sync/driver/data_type_manager_impl_unittest.cc
@@ -1387,6 +1387,70 @@ EXPECT_EQ(0U, configurer_.activated_types().Size()); } +TEST_F(SyncDataTypeManagerImplTest, UnreadyTypeLaterReady) { + AddController(BOOKMARKS); + GetController(BOOKMARKS)->SetReadyForStart(false); + + // Bookmarks is never started due to being unready. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::OK, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(), ModelTypeSet(BOOKMARKS), + ModelTypeSet())); + Configure(ModelTypeSet(BOOKMARKS)); + FinishDownload(ModelTypeSet(), ModelTypeSet()); + ASSERT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); + ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + ASSERT_EQ(0U, configurer_.activated_types().Size()); + + // Bookmarks should start normally now. + GetController(BOOKMARKS)->SetReadyForStart(true); + dtm_->ReadyForStartChanged(BOOKMARKS); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_NE(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); +} + +TEST_F(SyncDataTypeManagerImplTest, NoOpReadyForStartChangedWhileStillUnready) { + AddController(BOOKMARKS); + GetController(BOOKMARKS)->SetReadyForStart(false); + + // Bookmarks is never started due to being unready. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::OK, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(), ModelTypeSet(BOOKMARKS), + ModelTypeSet())); + Configure(ModelTypeSet(BOOKMARKS)); + FinishDownload(ModelTypeSet(), ModelTypeSet()); + ASSERT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); + ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + ASSERT_EQ(0U, configurer_.activated_types().Size()); + + // Bookmarks is still unready so ReadyForStartChanged() should be ignored. + dtm_->ReadyForStartChanged(BOOKMARKS); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); +} + +TEST_F(SyncDataTypeManagerImplTest, NoOpReadyForStartChangedWhileStillReady) { + AddController(BOOKMARKS); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + Configure(ModelTypeSet(BOOKMARKS)); + FinishDownload(ModelTypeSet(), ModelTypeSet()); + FinishDownload(ModelTypeSet(BOOKMARKS), ModelTypeSet()); + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + ASSERT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + ASSERT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state()); + + // Bookmarks is still ready so ReadyForStartChanged() should be ignored. + dtm_->ReadyForStartChanged(BOOKMARKS); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state()); +} + TEST_F(SyncDataTypeManagerImplTest, ModelLoadError) { AddController(BOOKMARKS); GetController(BOOKMARKS)->SetModelLoadError(
diff --git a/components/sync/driver/model_association_manager.cc b/components/sync/driver/model_association_manager.cc index e1e34b8..18b3acb 100644 --- a/components/sync/driver/model_association_manager.cc +++ b/components/sync/driver/model_association_manager.cc
@@ -183,11 +183,16 @@ ShutdownReason shutdown_reason, SyncError error) { DCHECK(error.IsSet()); + desired_types_.Remove(type); + DataTypeController* dtc = controllers_->find(type)->second.get(); if (dtc->state() != DataTypeController::NOT_RUNNING && dtc->state() != DataTypeController::STOPPING) { StopDatatypeImpl(error, shutdown_reason, dtc, base::DoNothing()); } + + // Removing a desired type may mean all models are now loaded. + NotifyDelegateIfReadyForConfigure(); } void ModelAssociationManager::StopDatatypeImpl( @@ -336,7 +341,8 @@ return; } - // This happens when slow loading type is disabled by new configuration. + // This happens when slow loading type is disabled by new configuration or + // the model came unready during loading. if (!desired_types_.Has(type)) return;
diff --git a/components/sync/driver/sync_service.h b/components/sync/driver/sync_service.h index 5cb7f526..f7c634e 100644 --- a/components/sync/driver/sync_service.h +++ b/components/sync/driver/sync_service.h
@@ -273,7 +273,7 @@ // Informs the data type manager that the ready-for-start status of a // controller has changed. If the controller is not ready any more, it will // stop |type|. Otherwise, it will trigger reconfiguration so that |type| gets - // started again. + // started again. No-op if the type's state didn't actually change. virtual void ReadyForStartChanged(ModelType type) = 0; // Enables/disables invalidations for session sync related datatypes.
diff --git a/components/viz/client/client_resource_provider.cc b/components/viz/client/client_resource_provider.cc index efca8bb..2c59c0b 100644 --- a/components/viz/client/client_resource_provider.cc +++ b/components/viz/client/client_resource_provider.cc
@@ -364,6 +364,7 @@ ClientResourceProvider::ScopedSkSurface::ScopedSkSurface( GrContext* gr_context, + sk_sp<SkColorSpace> color_space, GLuint texture_id, GLenum texture_target, const gfx::Size& size, @@ -381,7 +382,7 @@ bool gpu_compositing = true; surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget( gr_context, backend_texture, kTopLeft_GrSurfaceOrigin, msaa_sample_count, - ResourceFormatToClosestSkColorType(gpu_compositing, format), nullptr, + ResourceFormatToClosestSkColorType(gpu_compositing, format), color_space, &surface_props); }
diff --git a/components/viz/client/client_resource_provider.h b/components/viz/client/client_resource_provider.h index f3965af..b5d8c1d 100644 --- a/components/viz/client/client_resource_provider.h +++ b/components/viz/client/client_resource_provider.h
@@ -113,6 +113,7 @@ class VIZ_CLIENT_EXPORT ScopedSkSurface { public: ScopedSkSurface(GrContext* gr_context, + sk_sp<SkColorSpace> color_space, GLuint texture_id, GLenum texture_target, const gfx::Size& size,
diff --git a/components/viz/service/display/dc_layer_overlay.cc b/components/viz/service/display/dc_layer_overlay.cc index a1fe587..78e0793 100644 --- a/components/viz/service/display/dc_layer_overlay.cc +++ b/components/viz/service/display/dc_layer_overlay.cc
@@ -190,6 +190,19 @@ break; } } + +void RecordOverlayHistograms(bool is_overlay, + bool has_occluding_surface_damage, + bool is_full_screen_mode, + bool zero_damage_rect, + bool occluding_damage_equal_to_damage_rect) { + UMA_HISTOGRAM_BOOLEAN("GPU.DirectComposition.IsUnderlay", !is_overlay); + UMA_HISTOGRAM_BOOLEAN("GPU.DirectComposition.FullScreenOverlay", + is_full_screen_mode); + OverlayProcessor::RecordOverlayDamageRectHistograms( + is_overlay, has_occluding_surface_damage, zero_damage_rect, + occluding_damage_equal_to_damage_rect); +} } // namespace DCLayerOverlay::DCLayerOverlay() = default; @@ -435,6 +448,10 @@ current_frame_overlay_rect_union_.Union(rect_in_root); RecordDCLayerResult(DC_LAYER_SUCCESS, dc_layer.protected_video_type); + bool is_full_screen_mode = gfx::RectF(rect_in_root) == display_rect; + RecordOverlayHistograms(is_overlay, has_occluding_surface_damage, + is_full_screen_mode, damage_rect->IsEmpty(), + occlusion_bounding_box == gfx::RectF(*damage_rect)); dc_layer_overlays->push_back(dc_layer); // Only allow one overlay unless it's hardware protected video.
diff --git a/components/viz/service/display/overlay_processor.cc b/components/viz/service/display/overlay_processor.cc index 965663d..1d7a526 100644 --- a/components/viz/service/display/overlay_processor.cc +++ b/components/viz/service/display/overlay_processor.cc
@@ -46,6 +46,53 @@ } // namespace +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class UnderlayDamage { + kZeroDamageRect, + kNonOccludingDamageOnly, + kOccludingDamageOnly, + kOccludingAndNonOccludingDamages, + kMaxValue = kOccludingAndNonOccludingDamages, +}; + +// Record UMA histograms for overlays +// 1. Underlay vs. Overlay +// 2. Full screen mode vs. Non Full screen (Windows) mode +// 3. Overlay zero damage rect vs. non zero damage rect +// 4. Underlay zero damage rect, non-zero damage rect with non-occluding damage +// only, non-zero damage rect with occluding damage, and non-zero damage rect +// with both damages + +// static +void OverlayProcessor::RecordOverlayDamageRectHistograms( + bool is_overlay, + bool has_occluding_surface_damage, + bool zero_damage_rect, + bool occluding_damage_equal_to_damage_rect) { + if (is_overlay) { + UMA_HISTOGRAM_BOOLEAN("Viz.DisplayCompositor.RootDamageRect.Overlay", + !zero_damage_rect); + } else { // underlay + UnderlayDamage underlay_damage = UnderlayDamage::kZeroDamageRect; + if (zero_damage_rect) { + underlay_damage = UnderlayDamage::kZeroDamageRect; + } else { + if (has_occluding_surface_damage) { + if (occluding_damage_equal_to_damage_rect) { + underlay_damage = UnderlayDamage::kOccludingDamageOnly; + } else { + underlay_damage = UnderlayDamage::kOccludingAndNonOccludingDamages; + } + } else { + underlay_damage = UnderlayDamage::kNonOccludingDamageOnly; + } + } + UMA_HISTOGRAM_ENUMERATION("Viz.DisplayCompositor.RootDamageRect.Underlay", + underlay_damage); + } +} + OverlayStrategy OverlayProcessor::Strategy::GetUMAEnum() const { return OverlayStrategy::kUnknown; }
diff --git a/components/viz/service/display/overlay_processor.h b/components/viz/service/display/overlay_processor.h index 1a696cfe..7b01c0e 100644 --- a/components/viz/service/display/overlay_processor.h +++ b/components/viz/service/display/overlay_processor.h
@@ -28,6 +28,12 @@ using FilterOperationsMap = base::flat_map<RenderPassId, cc::FilterOperations*>; + static void RecordOverlayDamageRectHistograms( + bool is_overlay, + bool has_occluding_surface_damage, + bool zero_damage_rect, + bool occluding_damage_equal_to_damage_rect); + class VIZ_SERVICE_EXPORT Strategy { public: virtual ~Strategy() {}
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 37d18bd..e983645 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1732,8 +1732,6 @@ "service_worker/service_worker_url_request_job.h", "service_worker/service_worker_version.cc", "service_worker/service_worker_version.h", - "service_worker/service_worker_write_to_cache_job.cc", - "service_worker/service_worker_write_to_cache_job.h", "site_instance_impl.cc", "site_instance_impl.h", "speech/speech_recognition_dispatcher_host.cc",
diff --git a/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc b/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc index fc09678c..5a662f8 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
@@ -337,6 +337,14 @@ WriteAttribute(true, table_property, &line); } + const base::ListValue* cell_info; + node.GetList("cell", &cell_info); + for (auto it = cell_info->begin(); it != cell_info->end(); ++it) { + std::string cell_property; + if (it->GetAsString(&cell_property)) + WriteAttribute(true, cell_property, &line); + } + return line; }
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index 5225b6a..90086a4 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -176,11 +176,6 @@ int len, bool clipped = false) const; - // Same as |GetPageBoundsForRange| but in screen coordinates. - gfx::Rect GetScreenBoundsForRange(int start, - int len, - bool clipped = false) const; - // Convert a bounding rectangle from this node's coordinate system // (which is relative to its nearest scrollable ancestor) to // absolute bounds, either in page coordinates (when |frameOnly| is @@ -362,6 +357,9 @@ gfx::NativeViewAccessible ChildAtIndex(int index) override; gfx::Rect GetClippedScreenBoundsRect() const override; gfx::Rect GetUnclippedScreenBoundsRect() const override; + gfx::Rect GetScreenBoundsForRange(int start, + int len, + bool clipped = false) const override; gfx::NativeViewAccessible HitTestSync(int x, int y) override; gfx::NativeViewAccessible GetFocus() override; ui::AXPlatformNode* GetFromNodeID(int32_t id) override;
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index e6c8a1d..7c523d7 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -1220,6 +1220,20 @@ return nullptr; } +ui::AXPlatformNodeDelegate* BrowserAccessibilityManager::GetDelegate( + ui::AXTreeID tree_id, + int32_t node_id) { + auto* manager = BrowserAccessibilityManager::FromID(tree_id); + if (!manager) + return nullptr; + + BrowserAccessibility* wrapper = manager->GetFromID(node_id); + if (wrapper) + return wrapper; + + return nullptr; +} + BrowserAccessibilityManager* BrowserAccessibilityManager::GetRootManager() { BrowserAccessibility* parent = GetParentNodeFromParentTree(); if (!parent)
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h index 61328b4..bbf62299 100644 --- a/content/browser/accessibility/browser_accessibility_manager.h +++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -378,6 +378,8 @@ // AXTreeManager implementation. ui::AXNode* GetNodeFromTree(ui::AXTreeID tree_id, int32_t node_id) override; + ui::AXPlatformNodeDelegate* GetDelegate(ui::AXTreeID tree_id, + int32_t node_id) override; BrowserAccessibilityDelegate* delegate() const { return delegate_; }
diff --git a/content/browser/appcache/appcache_request_handler.cc b/content/browser/appcache/appcache_request_handler.cc index 327e8e4..a5f05bcb 100644 --- a/content/browser/appcache/appcache_request_handler.cc +++ b/content/browser/appcache/appcache_request_handler.cc
@@ -19,7 +19,6 @@ #include "content/browser/appcache/appcache_url_loader_job.h" #include "content/browser/appcache/appcache_url_loader_request.h" #include "content/browser/appcache/appcache_url_request_job.h" -#include "content/browser/service_worker/service_worker_request_handler.h" #include "content/common/navigation_subresource_loader_params.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_job.h" @@ -347,19 +346,6 @@ DCHECK(!job_.get()); DCHECK(host_); - // If a page falls into the scope of a ServiceWorker, any matching AppCaches - // should be ignored. This depends on the ServiceWorker handler being invoked - // prior to the AppCache handler. - // TODO(ananta/michaeln) - // We need to handle this for AppCache requests initiated for the network - // service - if (request_->GetURLRequest() && - ServiceWorkerRequestHandler::IsControlledByServiceWorker( - request_->GetURLRequest())) { - host_->enable_cache_selection(false); - return nullptr; - } - if (storage()->IsInitialized() && !base::ContainsKey(*service_->storage()->usage_map(), url::Origin::Create(request_->GetURL()))) {
diff --git a/content/browser/devtools/protocol/background_service_handler.cc b/content/browser/devtools/protocol/background_service_handler.cc index 6a63edd..12cad8e8 100644 --- a/content/browser/devtools/protocol/background_service_handler.cc +++ b/content/browser/devtools/protocol/background_service_handler.cc
@@ -154,7 +154,7 @@ if (service_enum == devtools::proto::BackgroundService::UNKNOWN) return Response::InvalidParams("Invalid service name"); - if (enabled_services_.count(service_enum)) + if (!enabled_services_.count(service_enum)) return Response::OK(); enabled_services_.erase(service_enum);
diff --git a/content/browser/gpu/gpu_ipc_browsertests.cc b/content/browser/gpu/gpu_ipc_browsertests.cc index dffed661..0c28a05 100644 --- a/content/browser/gpu/gpu_ipc_browsertests.cc +++ b/content/browser/gpu/gpu_ipc_browsertests.cc
@@ -180,34 +180,6 @@ } #endif -// Test fails on Chromeos + Mac, flaky on Windows because UI Compositor -// establishes a GPU channel. -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) -#define MAYBE_CallbacksDontRunOnEstablishSync CallbacksDontRunOnEstablishSync -#else -#define MAYBE_CallbacksDontRunOnEstablishSync \ - DISABLED_CallbacksDontRunOnEstablishSync -#endif -IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, - MAYBE_CallbacksDontRunOnEstablishSync) { - DCHECK(!IsChannelEstablished()); - bool event = false; - base::RunLoop run_loop; - GetFactory()->EstablishGpuChannel( - base::BindOnce(&BrowserGpuChannelHostFactoryTest::SignalAndQuitLoop, - base::Unretained(this), &event, &run_loop)); - - scoped_refptr<gpu::GpuChannelHost> gpu_channel = - GetFactory()->EstablishGpuChannelSync(); - - // Expect async callback didn't run yet. - EXPECT_FALSE(event); - - run_loop.Run(); - EXPECT_TRUE(event); - EXPECT_EQ(gpu_channel.get(), GetGpuChannel()); -} - // Test fails on Windows because GPU Channel set-up fails. #if !defined(OS_WIN) #define MAYBE_GrContextKeepsGpuChannelAlive GrContextKeepsGpuChannelAlive
diff --git a/content/browser/indexed_db/indexed_db_callbacks.cc b/content/browser/indexed_db/indexed_db_callbacks.cc index ac86581..7cc498b 100644 --- a/content/browser/indexed_db/indexed_db_callbacks.cc +++ b/content/browser/indexed_db/indexed_db_callbacks.cc
@@ -48,14 +48,14 @@ namespace { -// The following two objects protect the given objects from being destructed on -// the IO thread if we have a shutdown or an error. -class SafeIOThreadConnectionWrapper { +// The following two objects protect the given objects from being destructed +// while the current transaction task queue is being processed. +class SafeConnectionWrapper { public: - SafeIOThreadConnectionWrapper(std::unique_ptr<IndexedDBConnection> connection) + SafeConnectionWrapper(std::unique_ptr<IndexedDBConnection> connection) : connection_(std::move(connection)), idb_runner_(base::SequencedTaskRunnerHandle::Get()) {} - ~SafeIOThreadConnectionWrapper() { + ~SafeConnectionWrapper() { if (connection_) { idb_runner_->PostTask( FROM_HERE, base::BindOnce( @@ -65,32 +65,31 @@ std::move(connection_))); } } - SafeIOThreadConnectionWrapper(SafeIOThreadConnectionWrapper&& other) = - default; + SafeConnectionWrapper(SafeConnectionWrapper&& other) = default; std::unique_ptr<IndexedDBConnection> connection_; scoped_refptr<base::SequencedTaskRunner> idb_runner_; private: - DISALLOW_COPY_AND_ASSIGN(SafeIOThreadConnectionWrapper); + DISALLOW_COPY_AND_ASSIGN(SafeConnectionWrapper); }; -class SafeIOThreadCursorWrapper { +class SafeCursorWrapper { public: - SafeIOThreadCursorWrapper(std::unique_ptr<IndexedDBCursor> cursor) + SafeCursorWrapper(std::unique_ptr<IndexedDBCursor> cursor) : cursor_(std::move(cursor)), idb_runner_(base::SequencedTaskRunnerHandle::Get()) {} - ~SafeIOThreadCursorWrapper() { + ~SafeCursorWrapper() { if (cursor_) idb_runner_->DeleteSoon(FROM_HERE, cursor_.release()); } - SafeIOThreadCursorWrapper(SafeIOThreadCursorWrapper&& other) = default; + SafeCursorWrapper(SafeCursorWrapper&& other) = default; std::unique_ptr<IndexedDBCursor> cursor_; scoped_refptr<base::SequencedTaskRunner> idb_runner_; private: - DISALLOW_COPY_AND_ASSIGN(SafeIOThreadCursorWrapper); + DISALLOW_COPY_AND_ASSIGN(SafeCursorWrapper); }; std::unique_ptr<storage::BlobDataHandle> CreateBlobData( @@ -121,52 +120,6 @@ } // namespace -// TODO(cmp): Flatten calls / remove this class once IDB task runner CL settles. -class IndexedDBCallbacks::Helper { - public: - Helper(IDBCallbacksAssociatedPtrInfo callbacks_info, - base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, - url::Origin origin, - scoped_refptr<base::SequencedTaskRunner> idb_runner); - ~Helper(); - - void SendError(const IndexedDBDatabaseError& error); - void SendSuccessNamesAndVersionsList( - std::vector<blink::mojom::IDBNameAndVersionPtr> names_and_versions); - void SendSuccessStringList(const std::vector<base::string16>& value); - void SendBlocked(int64_t existing_version); - void SendUpgradeNeeded(SafeIOThreadConnectionWrapper connection, - int64_t old_version, - blink::mojom::IDBDataLoss data_loss, - const std::string& data_loss_message, - const IndexedDBDatabaseMetadata& metadata); - void SendSuccessDatabase(SafeIOThreadConnectionWrapper connection, - const IndexedDBDatabaseMetadata& metadata); - void SendSuccessCursor(SafeIOThreadCursorWrapper cursor, - const IndexedDBKey& key, - const IndexedDBKey& primary_key, - blink::mojom::IDBValuePtr value, - const std::vector<IndexedDBBlobInfo>& blob_info); - void SendSuccessValue(blink::mojom::IDBReturnValuePtr value, - const std::vector<IndexedDBBlobInfo>& blob_info); - void SendSuccessArray( - std::vector<blink::mojom::IDBReturnValuePtr> mojo_values, - const std::vector<IndexedDBReturnValue>& values); - void SendSuccessKey(const IndexedDBKey& value); - void SendSuccessInteger(int64_t value); - void SendSuccess(); - - void OnConnectionError(); - - private: - base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host_; - blink::mojom::IDBCallbacksAssociatedPtr callbacks_; - url::Origin origin_; - scoped_refptr<base::SequencedTaskRunner> idb_runner_; - SEQUENCE_CHECKER(sequence_checker_); - DISALLOW_COPY_AND_ASSIGN(Helper); -}; - IndexedDBCallbacks::IndexedDBValueBlob::IndexedDBValueBlob( const IndexedDBBlobInfo& blob_info, blink::mojom::IDBBlobInfoPtr* blob_or_file_info) @@ -265,12 +218,19 @@ blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks_info, scoped_refptr<base::SequencedTaskRunner> idb_runner) : data_loss_(blink::mojom::IDBDataLoss::None), - helper_(new Helper(std::move(callbacks_info), - std::move(dispatcher_host), - origin, - idb_runner)) { - DCHECK(idb_runner->RunsTasksInCurrentSequence()); + dispatcher_host_(std::move(dispatcher_host)), + origin_(origin), + idb_runner_(std::move(idb_runner)) { + DCHECK(idb_runner_->RunsTasksInCurrentSequence()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (callbacks_info.is_valid()) { + callbacks_.Bind(std::move(callbacks_info)); + // |callbacks_| is owned by |this|, so if |this| is destroyed, then + // |callbacks_| will also be destroyed. While |callbacks_| is otherwise + // alive, |this| will always be valid. + callbacks_.set_connection_error_handler(base::BindOnce( + &IndexedDBCallbacks::OnConnectionError, base::Unretained(this))); + } } IndexedDBCallbacks::~IndexedDBCallbacks() { @@ -281,7 +241,13 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!complete_); - helper_->SendError(error); + if (!callbacks_) + return; + if (!dispatcher_host_) { + OnConnectionError(); + return; + } + callbacks_->Error(error.code(), error.message()); complete_ = true; } @@ -289,32 +255,46 @@ std::vector<blink::mojom::IDBNameAndVersionPtr> names_and_versions) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!complete_); - DCHECK(helper_); - helper_->SendSuccessNamesAndVersionsList(std::move(names_and_versions)); + if (!callbacks_) + return; + if (!dispatcher_host_) { + OnConnectionError(); + return; + } + callbacks_->SuccessNamesAndVersionsList(std::move(names_and_versions)); complete_ = true; } void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!complete_); - DCHECK(helper_); - helper_->SendSuccessStringList(value); + if (!callbacks_) + return; + if (!dispatcher_host_) { + OnConnectionError(); + return; + } + callbacks_->SuccessStringList(value); complete_ = true; } void IndexedDBCallbacks::OnBlocked(int64_t existing_version) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!complete_); - DCHECK(helper_); if (sent_blocked_) return; sent_blocked_ = true; - helper_->SendBlocked(existing_version); + if (!dispatcher_host_) { + OnConnectionError(); + return; + } + if (callbacks_) + callbacks_->Blocked(existing_version); } void IndexedDBCallbacks::OnUpgradeNeeded( @@ -324,17 +304,31 @@ const IndexedDBDataLossInfo& data_loss_info) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!complete_); - DCHECK(helper_); DCHECK(!connection_created_); data_loss_ = data_loss_info.status; connection_created_ = true; - SafeIOThreadConnectionWrapper wrapper(std::move(connection)); - helper_->SendUpgradeNeeded(std::move(wrapper), old_version, - data_loss_info.status, data_loss_info.message, - metadata); + SafeConnectionWrapper wrapper(std::move(connection)); + if (!callbacks_) + return; + if (!dispatcher_host_) { + OnConnectionError(); + return; + } + + auto database = + std::make_unique<DatabaseImpl>(std::move(wrapper.connection_), origin_, + dispatcher_host_.get(), idb_runner_); + + blink::mojom::IDBDatabaseAssociatedPtrInfo ptr_info; + auto request = mojo::MakeRequest(&ptr_info); + + dispatcher_host_->AddDatabaseBinding(std::move(database), std::move(request)); + callbacks_->UpgradeNeeded(std::move(ptr_info), old_version, + data_loss_info.status, data_loss_info.message, + metadata); } void IndexedDBCallbacks::OnSuccess( @@ -342,7 +336,6 @@ const IndexedDBDatabaseMetadata& metadata) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!complete_); - DCHECK(helper_); DCHECK_EQ(connection_created_, !connection); @@ -354,8 +347,24 @@ if (!connection_created_) database_connection = std::move(connection); - SafeIOThreadConnectionWrapper wrapper(std::move(database_connection)); - helper_->SendSuccessDatabase(std::move(wrapper), metadata); + SafeConnectionWrapper wrapper(std::move(database_connection)); + if (!callbacks_) + return; + if (!dispatcher_host_) { + OnConnectionError(); + return; + } + blink::mojom::IDBDatabaseAssociatedPtrInfo ptr_info; + if (wrapper.connection_) { + auto database = + std::make_unique<DatabaseImpl>(std::move(wrapper.connection_), origin_, + dispatcher_host_.get(), idb_runner_); + + auto request = mojo::MakeRequest(&ptr_info); + dispatcher_host_->AddDatabaseBinding(std::move(database), + std::move(request)); + } + callbacks_->SuccessDatabase(std::move(ptr_info), metadata); complete_ = true; } @@ -365,7 +374,6 @@ IndexedDBValue* value) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!complete_); - DCHECK(helper_); DCHECK_EQ(blink::mojom::IDBDataLoss::None, data_loss_); @@ -376,9 +384,29 @@ blob_info.swap(value->blob_info); } - SafeIOThreadCursorWrapper cursor_wrapper(std::move(cursor)); - helper_->SendSuccessCursor(std::move(cursor_wrapper), key, primary_key, - std::move(mojo_value), std::move(blob_info)); + SafeCursorWrapper cursor_wrapper(std::move(cursor)); + if (!callbacks_) + return; + if (!dispatcher_host_) { + OnConnectionError(); + return; + } + auto cursor_impl = + std::make_unique<CursorImpl>(std::move(cursor_wrapper.cursor_), origin_, + dispatcher_host_.get(), idb_runner_); + if (mojo_value && !IndexedDBCallbacks::CreateAllBlobs( + dispatcher_host_->blob_storage_context(), idb_runner_, + IndexedDBValueBlob::GetIndexedDBValueBlobs( + blob_info, &mojo_value->blob_or_file_info))) { + return; + } + + blink::mojom::IDBCursorAssociatedPtrInfo ptr_info; + auto request = mojo::MakeRequest(&ptr_info); + dispatcher_host_->AddCursorBinding(std::move(cursor_impl), + std::move(request)); + callbacks_->SuccessCursor(std::move(ptr_info), key, primary_key, + std::move(mojo_value)); complete_ = true; } @@ -395,7 +423,22 @@ blob_info = value->blob_info; } - helper_->SendSuccessValue(std::move(mojo_value), std::move(blob_info)); + if (!callbacks_) + return; + if (!dispatcher_host_) { + OnConnectionError(); + return; + } + + if (mojo_value && + !IndexedDBCallbacks::CreateAllBlobs( + dispatcher_host_->blob_storage_context(), idb_runner_, + IndexedDBValueBlob::GetIndexedDBValueBlobs( + blob_info, &mojo_value->value->blob_or_file_info))) { + return; + } + + callbacks_->SuccessValue(std::move(mojo_value)); complete_ = true; } @@ -403,7 +446,6 @@ std::vector<IndexedDBReturnValue>* values) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!complete_); - DCHECK(helper_); DCHECK_EQ(blink::mojom::IDBDataLoss::None, data_loss_); @@ -414,216 +456,6 @@ IndexedDBReturnValue::ConvertReturnValue(&(*values)[i])); } - helper_->SendSuccessArray(std::move(mojo_values), *values); - complete_ = true; -} - -void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(!complete_); - DCHECK(helper_); - - DCHECK_EQ(blink::mojom::IDBDataLoss::None, data_loss_); - - helper_->SendSuccessKey(value); - complete_ = true; -} - -void IndexedDBCallbacks::OnSuccess(int64_t value) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(!complete_); - - helper_->SendSuccessInteger(value); - complete_ = true; -} - -void IndexedDBCallbacks::OnSuccess() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(!complete_); - DCHECK(helper_); - - DCHECK_EQ(blink::mojom::IDBDataLoss::None, data_loss_); - - helper_->SendSuccess(); - complete_ = true; -} - -IndexedDBCallbacks::Helper::Helper( - IDBCallbacksAssociatedPtrInfo callbacks_info, - base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, - url::Origin origin, - scoped_refptr<base::SequencedTaskRunner> idb_runner) - : dispatcher_host_(std::move(dispatcher_host)), - origin_(origin), - idb_runner_(idb_runner) { - DCHECK(idb_runner_->RunsTasksInCurrentSequence()); - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (callbacks_info.is_valid()) { - callbacks_.Bind(std::move(callbacks_info)); - // |callbacks_| is owned by |this|, so if |this| is destroyed, then - // |callbacks_| will also be destroyed. While |callbacks_| is otherwise - // alive, |this| will always be valid. - callbacks_.set_connection_error_handler( - base::BindOnce(&Helper::OnConnectionError, base::Unretained(this))); - } -} - -IndexedDBCallbacks::Helper::~Helper() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -} - -void IndexedDBCallbacks::Helper::SendError( - const IndexedDBDatabaseError& error) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!callbacks_) - return; - if (!dispatcher_host_) { - OnConnectionError(); - return; - } - callbacks_->Error(error.code(), error.message()); -} - -void IndexedDBCallbacks::Helper::SendSuccessNamesAndVersionsList( - std::vector<blink::mojom::IDBNameAndVersionPtr> names_and_versions) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!callbacks_) - return; - if (!dispatcher_host_) { - OnConnectionError(); - return; - } - callbacks_->SuccessNamesAndVersionsList(std::move(names_and_versions)); -} - -void IndexedDBCallbacks::Helper::SendSuccessStringList( - const std::vector<base::string16>& value) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!callbacks_) - return; - if (!dispatcher_host_) { - OnConnectionError(); - return; - } - callbacks_->SuccessStringList(value); -} - -void IndexedDBCallbacks::Helper::SendBlocked(int64_t existing_version) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!dispatcher_host_) { - OnConnectionError(); - return; - } - if (callbacks_) - callbacks_->Blocked(existing_version); -} - -void IndexedDBCallbacks::Helper::SendUpgradeNeeded( - SafeIOThreadConnectionWrapper connection_wrapper, - int64_t old_version, - blink::mojom::IDBDataLoss data_loss, - const std::string& data_loss_message, - const IndexedDBDatabaseMetadata& metadata) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!callbacks_) - return; - if (!dispatcher_host_) { - OnConnectionError(); - return; - } - - auto database = std::make_unique<DatabaseImpl>( - std::move(connection_wrapper.connection_), origin_, - dispatcher_host_.get(), idb_runner_); - - blink::mojom::IDBDatabaseAssociatedPtrInfo ptr_info; - auto request = mojo::MakeRequest(&ptr_info); - - dispatcher_host_->AddDatabaseBinding(std::move(database), std::move(request)); - callbacks_->UpgradeNeeded(std::move(ptr_info), old_version, data_loss, - data_loss_message, metadata); -} - -void IndexedDBCallbacks::Helper::SendSuccessDatabase( - SafeIOThreadConnectionWrapper connection_wrapper, - const IndexedDBDatabaseMetadata& metadata) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!callbacks_) - return; - if (!dispatcher_host_) { - OnConnectionError(); - return; - } - blink::mojom::IDBDatabaseAssociatedPtrInfo ptr_info; - if (connection_wrapper.connection_) { - auto database = std::make_unique<DatabaseImpl>( - std::move(connection_wrapper.connection_), origin_, - dispatcher_host_.get(), idb_runner_); - - auto request = mojo::MakeRequest(&ptr_info); - dispatcher_host_->AddDatabaseBinding(std::move(database), - std::move(request)); - } - callbacks_->SuccessDatabase(std::move(ptr_info), metadata); -} - -void IndexedDBCallbacks::Helper::SendSuccessCursor( - SafeIOThreadCursorWrapper cursor, - const IndexedDBKey& key, - const IndexedDBKey& primary_key, - blink::mojom::IDBValuePtr value, - const std::vector<IndexedDBBlobInfo>& blob_info) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!callbacks_) - return; - if (!dispatcher_host_) { - OnConnectionError(); - return; - } - auto cursor_impl = std::make_unique<CursorImpl>( - std::move(cursor.cursor_), origin_, dispatcher_host_.get(), idb_runner_); - if (value && !IndexedDBCallbacks::CreateAllBlobs( - dispatcher_host_->blob_storage_context(), idb_runner_, - IndexedDBValueBlob::GetIndexedDBValueBlobs( - blob_info, &value->blob_or_file_info))) { - return; - } - - blink::mojom::IDBCursorAssociatedPtrInfo ptr_info; - auto request = mojo::MakeRequest(&ptr_info); - dispatcher_host_->AddCursorBinding(std::move(cursor_impl), - std::move(request)); - callbacks_->SuccessCursor(std::move(ptr_info), key, primary_key, - std::move(value)); -} - -void IndexedDBCallbacks::Helper::SendSuccessValue( - blink::mojom::IDBReturnValuePtr value, - const std::vector<IndexedDBBlobInfo>& blob_info) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!callbacks_) - return; - if (!dispatcher_host_) { - OnConnectionError(); - return; - } - - if (value && !IndexedDBCallbacks::CreateAllBlobs( - dispatcher_host_->blob_storage_context(), idb_runner_, - IndexedDBValueBlob::GetIndexedDBValueBlobs( - blob_info, &value->value->blob_or_file_info))) { - return; - } - - callbacks_->SuccessValue(std::move(value)); -} - -void IndexedDBCallbacks::Helper::SendSuccessArray( - std::vector<blink::mojom::IDBReturnValuePtr> mojo_values, - const std::vector<IndexedDBReturnValue>& values) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(mojo_values.size(), values.size()); - if (!callbacks_) return; if (!dispatcher_host_) { @@ -634,7 +466,7 @@ std::vector<IndexedDBValueBlob> value_blobs; for (size_t i = 0; i < mojo_values.size(); ++i) { IndexedDBValueBlob::GetIndexedDBValueBlobs( - &value_blobs, values[i].blob_info, + &value_blobs, (*values)[i].blob_info, &mojo_values[i]->value->blob_or_file_info); } @@ -645,10 +477,15 @@ } callbacks_->SuccessArray(std::move(mojo_values)); + complete_ = true; } -void IndexedDBCallbacks::Helper::SendSuccessKey(const IndexedDBKey& value) { +void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!complete_); + + DCHECK_EQ(blink::mojom::IDBDataLoss::None, data_loss_); + if (!callbacks_) return; if (!dispatcher_host_) { @@ -656,10 +493,13 @@ return; } callbacks_->SuccessKey(value); + complete_ = true; } -void IndexedDBCallbacks::Helper::SendSuccessInteger(int64_t value) { +void IndexedDBCallbacks::OnSuccess(int64_t value) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!complete_); + if (!callbacks_) return; if (!dispatcher_host_) { @@ -667,10 +507,15 @@ return; } callbacks_->SuccessInteger(value); + complete_ = true; } -void IndexedDBCallbacks::Helper::SendSuccess() { +void IndexedDBCallbacks::OnSuccess() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!complete_); + + DCHECK_EQ(blink::mojom::IDBDataLoss::None, data_loss_); + if (!callbacks_) return; if (!dispatcher_host_) { @@ -678,9 +523,10 @@ return; } callbacks_->Success(); + complete_ = true; } -void IndexedDBCallbacks::Helper::OnConnectionError() { +void IndexedDBCallbacks::OnConnectionError() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); callbacks_.reset(); dispatcher_host_ = nullptr;
diff --git a/content/browser/indexed_db/indexed_db_callbacks.h b/content/browser/indexed_db/indexed_db_callbacks.h index c64914e..b26cb874 100644 --- a/content/browser/indexed_db/indexed_db_callbacks.h +++ b/content/browser/indexed_db/indexed_db_callbacks.h
@@ -135,14 +135,14 @@ // IndexedDBCursor::Continue / Advance (when complete) virtual void OnSuccess(); + void OnConnectionError(); + protected: virtual ~IndexedDBCallbacks(); private: friend class base::RefCounted<IndexedDBCallbacks>; - class Helper; - // Stores if this callbacks object is complete and should not be called again. bool complete_ = false; @@ -157,7 +157,11 @@ // The "blocked" event should be sent at most once per request. bool sent_blocked_ = false; - std::unique_ptr<Helper> helper_; + base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host_; + url::Origin origin_; + scoped_refptr<base::SequencedTaskRunner> idb_runner_; + blink::mojom::IDBCallbacksAssociatedPtr callbacks_; + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(IndexedDBCallbacks);
diff --git a/content/browser/indexed_db/indexed_db_database_callbacks.cc b/content/browser/indexed_db/indexed_db_database_callbacks.cc index 6544d35e..85d981e8 100644 --- a/content/browser/indexed_db/indexed_db_database_callbacks.cc +++ b/content/browser/indexed_db/indexed_db_database_callbacks.cc
@@ -16,34 +16,21 @@ namespace content { -// TODO(cmp): Flatten calls / remove this class once IDB task runner CL settles. -class IndexedDBDatabaseCallbacks::Helper { - public: - explicit Helper(IDBDatabaseCallbacksAssociatedPtrInfo callbacks_info, - base::SequencedTaskRunner* idb_runner); - ~Helper(); - - void SendForcedClose(); - void SendVersionChange(int64_t old_version, int64_t new_version); - void SendAbort(int64_t transaction_id, const IndexedDBDatabaseError& error); - void SendComplete(int64_t transaction_id); - void SendChanges(blink::mojom::IDBObserverChangesPtr changes); - void OnConnectionError(); - - private: - blink::mojom::IDBDatabaseCallbacksAssociatedPtr callbacks_; - SEQUENCE_CHECKER(sequence_checker_); - DISALLOW_COPY_AND_ASSIGN(Helper); -}; - IndexedDBDatabaseCallbacks::IndexedDBDatabaseCallbacks( scoped_refptr<IndexedDBContextImpl> context, IDBDatabaseCallbacksAssociatedPtrInfo callbacks_info, base::SequencedTaskRunner* idb_runner) - : indexed_db_context_(std::move(context)), - helper_(new Helper(std::move(callbacks_info), idb_runner)) { + : indexed_db_context_(std::move(context)) { DCHECK(idb_runner->RunsTasksInCurrentSequence()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!callbacks_info.is_valid()) + return; + callbacks_.Bind(std::move(callbacks_info)); + // |callbacks_| is owned by |this|, so if |this| is destroyed, then + // |callbacks_| will also be destroyed. While |callbacks_| is otherwise + // alive, |this| will always be valid. + callbacks_.set_connection_error_handler(base::BindOnce( + &IndexedDBDatabaseCallbacks::OnConnectionError, base::Unretained(this))); } IndexedDBDatabaseCallbacks::~IndexedDBDatabaseCallbacks() { @@ -55,8 +42,8 @@ if (complete_) return; - DCHECK(helper_); - helper_->SendForcedClose(); + if (callbacks_) + callbacks_->ForcedClose(); complete_ = true; } @@ -66,8 +53,8 @@ if (complete_) return; - DCHECK(helper_); - helper_->SendVersionChange(old_version, new_version); + if (callbacks_) + callbacks_->VersionChange(old_version, new_version); } void IndexedDBDatabaseCallbacks::OnAbort( @@ -77,8 +64,8 @@ if (complete_) return; - DCHECK(helper_); - helper_->SendAbort(transaction.id(), error); + if (callbacks_) + callbacks_->Abort(transaction.id(), error.code(), error.message()); } void IndexedDBDatabaseCallbacks::OnComplete( @@ -88,72 +75,18 @@ return; indexed_db_context_->TransactionComplete(transaction.database()->origin()); - DCHECK(helper_); - helper_->SendComplete(transaction.id()); + if (callbacks_) + callbacks_->Complete(transaction.id()); } void IndexedDBDatabaseCallbacks::OnDatabaseChange( blink::mojom::IDBObserverChangesPtr changes) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(helper_); - helper_->SendChanges(std::move(changes)); -} - -IndexedDBDatabaseCallbacks::Helper::Helper( - IDBDatabaseCallbacksAssociatedPtrInfo callbacks_info, - base::SequencedTaskRunner* idb_runner) { - DCHECK(idb_runner->RunsTasksInCurrentSequence()); - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!callbacks_info.is_valid()) - return; - callbacks_.Bind(std::move(callbacks_info)); - // |callbacks_| is owned by |this|, so if |this| is destroyed, then - // |callbacks_| will also be destroyed. While |callbacks_| is otherwise - // alive, |this| will always be valid. - callbacks_.set_connection_error_handler( - base::BindOnce(&Helper::OnConnectionError, base::Unretained(this))); -} - -IndexedDBDatabaseCallbacks::Helper::~Helper() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -} - -void IndexedDBDatabaseCallbacks::Helper::SendForcedClose() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (callbacks_) - callbacks_->ForcedClose(); -} - -void IndexedDBDatabaseCallbacks::Helper::SendVersionChange( - int64_t old_version, - int64_t new_version) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (callbacks_) - callbacks_->VersionChange(old_version, new_version); -} - -void IndexedDBDatabaseCallbacks::Helper::SendAbort( - int64_t transaction_id, - const IndexedDBDatabaseError& error) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (callbacks_) - callbacks_->Abort(transaction_id, error.code(), error.message()); -} - -void IndexedDBDatabaseCallbacks::Helper::SendComplete(int64_t transaction_id) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (callbacks_) - callbacks_->Complete(transaction_id); -} - -void IndexedDBDatabaseCallbacks::Helper::SendChanges( - blink::mojom::IDBObserverChangesPtr changes) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (callbacks_) callbacks_->Changes(std::move(changes)); } -void IndexedDBDatabaseCallbacks::Helper::OnConnectionError() { +void IndexedDBDatabaseCallbacks::OnConnectionError() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); callbacks_.reset(); }
diff --git a/content/browser/indexed_db/indexed_db_database_callbacks.h b/content/browser/indexed_db/indexed_db_database_callbacks.h index 031a968..a446488 100644 --- a/content/browser/indexed_db/indexed_db_database_callbacks.h +++ b/content/browser/indexed_db/indexed_db_database_callbacks.h
@@ -38,17 +38,17 @@ virtual void OnComplete(const IndexedDBTransaction& transaction); virtual void OnDatabaseChange(blink::mojom::IDBObserverChangesPtr changes); + void OnConnectionError(); + protected: virtual ~IndexedDBDatabaseCallbacks(); private: friend class base::RefCounted<IndexedDBDatabaseCallbacks>; - class Helper; - bool complete_ = false; scoped_refptr<IndexedDBContextImpl> indexed_db_context_; - std::unique_ptr<Helper> helper_; + blink::mojom::IDBDatabaseCallbacksAssociatedPtr callbacks_; SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(IndexedDBDatabaseCallbacks);
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 6ffe770..819f665 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -56,7 +56,6 @@ #include "content/browser/loader/throttling_resource_handler.h" #include "content/browser/loader/upload_data_stream_builder.h" #include "content/browser/resource_context_impl.h" -#include "content/browser/service_worker/service_worker_request_handler.h" #include "content/browser/streams/stream.h" #include "content/browser/streams/stream_context.h" #include "content/browser/streams/stream_registry.h" @@ -1086,18 +1085,6 @@ ->GetBlobDataFromPublicURL(new_request->url())); } - // Initialize the service worker handler for the request. - ServiceWorkerRequestHandler::InitializeHandler( - new_request.get(), requester_info->service_worker_context(), blob_context, - child_id, request_data.service_worker_provider_id, - request_data.skip_service_worker, request_data.fetch_request_mode, - request_data.fetch_credentials_mode, request_data.fetch_redirect_mode, - request_data.fetch_integrity, request_data.keepalive, - static_cast<ResourceType>(request_data.resource_type), - static_cast<blink::mojom::RequestContextType>( - request_data.fetch_request_context_type), - request_data.fetch_frame_type, request_data.request_body); - // Have the appcache associate its extra info with the request. AppCacheInterceptor::SetExtraRequestInfo( new_request.get(), requester_info->appcache_service(), child_id,
diff --git a/content/browser/notifications/platform_notification_context_impl.cc b/content/browser/notifications/platform_notification_context_impl.cc index 9d43b4e..739a98f 100644 --- a/content/browser/notifications/platform_notification_context_impl.cc +++ b/content/browser/notifications/platform_notification_context_impl.cc
@@ -93,16 +93,24 @@ bool supports_synchronization) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + // Check if there are pending notifications to display. + base::Time next_trigger = base::Time::Max(); + if (service_proxy_ && + base::FeatureList::IsEnabled(features::kNotificationTriggers)) { + next_trigger = service_proxy_->GetNextTrigger(); + } + // Synchronize the notifications stored in the database with the set of // displaying notifications in |displayed_notifications|. This is necessary // because flakiness may cause a platform to inform Chrome of a notification // that has since been closed, or because the platform does not support // notifications that exceed the lifetime of the browser process. - if (supports_synchronization || - base::FeatureList::IsEnabled(features::kNotificationTriggers)) { + if (supports_synchronization || next_trigger <= base::Time::Now()) { LazyInitialize(base::BindOnce( &PlatformNotificationContextImpl::DoSyncNotificationData, this, supports_synchronization, std::move(displayed_notifications))); + } else if (service_proxy_ && next_trigger != base::Time::Max()) { + service_proxy_->ScheduleTrigger(next_trigger); } // |service_worker_context_| may be NULL in tests. @@ -132,12 +140,8 @@ DestroyDatabase(); // Schedule the next trigger timestamp. - if (next_trigger_) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_VISIBLE}, - base::BindOnce(&PlatformNotificationContextImpl::ScheduleTrigger, this, - next_trigger_.value())); - } + if (next_trigger_ && service_proxy_) + service_proxy_->ScheduleTrigger(next_trigger_.value()); } void PlatformNotificationContextImpl::DoHandleSyncNotification( @@ -248,19 +252,6 @@ NotificationDatabaseData())); } -void PlatformNotificationContextImpl::ScheduleTrigger(base::Time timestamp) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::TimeDelta delay = timestamp - base::Time::Now(); - if (delay.InMicroseconds() < 0) - delay = base::TimeDelta(); - - if (trigger_timer_.IsRunning() && trigger_timer_.GetCurrentDelay() <= delay) - return; - - trigger_timer_.Start(FROM_HERE, delay, this, - &PlatformNotificationContextImpl::TriggerNotifications); -} - void PlatformNotificationContextImpl::TriggerNotifications() { DCHECK_CURRENTLY_ON(BrowserThread::UI); std::set<std::string> displayed_notifications; @@ -568,16 +559,12 @@ NotificationDatabase::STATUS_COUNT); if (status == NotificationDatabase::STATUS_OK) { - if (CanTrigger(write_database_data)) { + if (CanTrigger(write_database_data) && service_proxy_) { if (replaces_existing) service_proxy_->CloseNotification(notification_id); // Schedule notification to be shown. - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_VISIBLE}, - base::BindOnce(&PlatformNotificationContextImpl::ScheduleTrigger, - this, - write_database_data.notification_data - .show_trigger_timestamp.value())); + service_proxy_->ScheduleTrigger( + write_database_data.notification_data.show_trigger_timestamp.value()); } base::PostTaskWithTraits(
diff --git a/content/browser/notifications/platform_notification_context_impl.h b/content/browser/notifications/platform_notification_context_impl.h index c7c9bc8f..24918ced 100644 --- a/content/browser/notifications/platform_notification_context_impl.h +++ b/content/browser/notifications/platform_notification_context_impl.h
@@ -18,7 +18,6 @@ #include "base/memory/ref_counted.h" #include "base/optional.h" #include "base/time/time.h" -#include "base/timer/timer.h" #include "content/browser/notifications/notification_database.h" #include "content/browser/notifications/notification_id_generator.h" #include "content/browser/service_worker/service_worker_context_core_observer.h" @@ -99,6 +98,7 @@ const GURL& origin, int64_t service_worker_registration_id, ReadAllResultCallback callback) override; + void TriggerNotifications() override; // ServiceWorkerContextCoreObserver implementation. void OnRegistrationDeleted(int64_t registration_id, @@ -121,12 +121,6 @@ // called with true, otherwise it will be called with false. void LazyInitialize(InitializeResultCallback callback); - // Schedules a job to run at |timestamp| and call TriggerNotifications. - void ScheduleTrigger(base::Time timestamp); - - // Trigger all pending notifications. - void TriggerNotifications(); - // Marks this notification as shown and displays it. void DoTriggerNotification(const NotificationDatabaseData& database_data); @@ -239,9 +233,6 @@ NotificationIdGenerator notification_id_generator_; - // Triggers pending notifications, set by ScheduleTrigger. - base::OneShotTimer trigger_timer_; - // Keeps track of the next trigger timestamp. base::Optional<base::Time> next_trigger_;
diff --git a/content/browser/notifications/platform_notification_context_trigger_unittest.cc b/content/browser/notifications/platform_notification_context_trigger_unittest.cc index 9d43d36c..5bb6420 100644 --- a/content/browser/notifications/platform_notification_context_trigger_unittest.cc +++ b/content/browser/notifications/platform_notification_context_trigger_unittest.cc
@@ -121,6 +121,11 @@ return displayed_notification_ids_; } + void TriggerNotifications() { + platform_notification_context_->TriggerNotifications(); + base::RunLoop().RunUntilIdle(); + } + TestBrowserThreadBundle thread_bundle_; // Must be first member TestBrowserContext browser_context_; @@ -148,12 +153,20 @@ // Wait until the trigger timestamp is reached. thread_bundle_.FastForwardBy(TimeDelta::FromSeconds(10)); + + // This gets called by the notification scheduling system. + TriggerNotifications(); + ASSERT_EQ(1u, GetDisplayedNotifications().size()); } TEST_F(PlatformNotificationContextTriggerTest, TriggerInPast) { // Trigger timestamp in the past should immediately trigger. WriteNotificationData("1", Time::Now() - TimeDelta::FromSeconds(10)); + + // This gets called by the notification scheduling system. + TriggerNotifications(); + ASSERT_EQ(1u, GetDisplayedNotifications().size()); } @@ -172,6 +185,10 @@ ASSERT_EQ(0u, GetDisplayedNotifications().size()); thread_bundle_.FastForwardBy(TimeDelta::FromSeconds(5)); + + // This gets called by the notification scheduling system. + TriggerNotifications(); + ASSERT_EQ(1u, GetDisplayedNotifications().size()); } @@ -183,6 +200,10 @@ // Overwrites the scheduled notifications with a new trigger timestamp. WriteNotificationData("1", Time::Now() - TimeDelta::FromSeconds(10)); + + // This gets called by the notification scheduling system. + TriggerNotifications(); + ASSERT_EQ(1u, GetDisplayedNotifications().size()); } @@ -193,6 +214,10 @@ // Overwrites a displayed notification with a trigger timestamp in the past. WriteNotificationData("1", Time::Now() - TimeDelta::FromSeconds(10)); + + // This gets called by the notification scheduling system. + TriggerNotifications(); + ASSERT_EQ(1u, GetDisplayedNotifications().size()); } @@ -201,6 +226,9 @@ WriteNotificationData("1", Time::Now() + TimeDelta::FromSeconds(10)); thread_bundle_.FastForwardBy(TimeDelta::FromSeconds(10)); + // This gets called by the notification scheduling system. + TriggerNotifications(); + // Overwrites a displayed notification which hides it until the trigger // timestamp is reached. WriteNotificationData("1", Time::Now() + TimeDelta::FromSeconds(10)); @@ -208,6 +236,10 @@ ASSERT_EQ(0u, GetDisplayedNotifications().size()); thread_bundle_.FastForwardBy(TimeDelta::FromSeconds(10)); + + // This gets called by the notification scheduling system. + TriggerNotifications(); + ASSERT_EQ(1u, GetDisplayedNotifications().size()); }
diff --git a/content/browser/notifications/platform_notification_service_proxy.cc b/content/browser/notifications/platform_notification_service_proxy.cc index 8ce2ed287..a921c03 100644 --- a/content/browser/notifications/platform_notification_service_proxy.cc +++ b/content/browser/notifications/platform_notification_service_proxy.cc
@@ -97,4 +97,22 @@ notification_id)); } +void PlatformNotificationServiceProxy::ScheduleTrigger(base::Time timestamp) { + if (!notification_service_) + return; + + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_VISIBLE}, + base::BindOnce(&PlatformNotificationService::ScheduleTrigger, + base::Unretained(notification_service_), browser_context_, + timestamp)); +} + +base::Time PlatformNotificationServiceProxy::GetNextTrigger() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!notification_service_) + return base::Time::Max(); + return notification_service_->ReadNextTriggerTimestamp(browser_context_); +} + } // namespace content
diff --git a/content/browser/notifications/platform_notification_service_proxy.h b/content/browser/notifications/platform_notification_service_proxy.h index 85f59099d..1bbac28 100644 --- a/content/browser/notifications/platform_notification_service_proxy.h +++ b/content/browser/notifications/platform_notification_service_proxy.h
@@ -48,6 +48,13 @@ // Closes the notification with |notification_id|. void CloseNotification(const std::string& notification_id); + // Schedules a notification trigger for |timestamp|. + void ScheduleTrigger(base::Time timestamp); + + // Gets the next notification trigger or base::Time::Max if none set. Must be + // called on the UI thread. + base::Time GetNextTrigger(); + private: // Actually calls |notification_service_| to display the notification after // verifying the |service_worker_scope|.
diff --git a/content/browser/renderer_host/input/fling_controller.cc b/content/browser/renderer_host/input/fling_controller.cc index 0ec5116..b0006ef 100644 --- a/content/browser/renderer_host/input/fling_controller.cc +++ b/content/browser/renderer_host/input/fling_controller.cc
@@ -146,7 +146,7 @@ return should_filter_event; } -bool FlingController::FilterGestureEvent( +bool FlingController::ObserveAndMaybeConsumeGestureEvent( const GestureEventWithLatencyInfo& gesture_event) { if (!ShouldForwardForGFCFiltering(gesture_event) || !ShouldForwardForTapSuppression(gesture_event) ||
diff --git a/content/browser/renderer_host/input/fling_controller.h b/content/browser/renderer_host/input/fling_controller.h index 4254134b..bcb5aec2 100644 --- a/content/browser/renderer_host/input/fling_controller.h +++ b/content/browser/renderer_host/input/fling_controller.h
@@ -83,7 +83,11 @@ // Used to halt an active fling progress whenever needed. void StopFling(); - bool FilterGestureEvent(const GestureEventWithLatencyInfo& gesture_event); + // The fling controller needs to observe all gesture events. It may consume + // or filter some events. It will return true if the event was consumed or + // filtered and should not be propagated further. + bool ObserveAndMaybeConsumeGestureEvent( + const GestureEventWithLatencyInfo& gesture_event); void ProcessGestureFlingStart( const GestureEventWithLatencyInfo& gesture_event);
diff --git a/content/browser/renderer_host/input/fling_controller_unittest.cc b/content/browser/renderer_host/input/fling_controller_unittest.cc index 502026f..82635184 100644 --- a/content/browser/renderer_host/input/fling_controller_unittest.cc +++ b/content/browser/renderer_host/input/fling_controller_unittest.cc
@@ -97,7 +97,8 @@ // Wait for up to one frame before processing the event. AdvanceTime(base::RandInt(0, static_cast<int>(kFrameDelta))); } - fling_controller_->FilterGestureEvent(fling_start_with_latency); + fling_controller_->ObserveAndMaybeConsumeGestureEvent( + fling_start_with_latency); } void SimulateScrollUpdate(blink::WebGestureDevice source_device, @@ -116,7 +117,8 @@ WebGestureEvent::kPrecisePixels; GestureEventWithLatencyInfo scroll_update_with_latency(scroll_update); - fling_controller_->FilterGestureEvent(scroll_update_with_latency); + fling_controller_->ObserveAndMaybeConsumeGestureEvent( + scroll_update_with_latency); } void SimulateFlingCancel(blink::WebGestureDevice source_device) { @@ -127,7 +129,8 @@ if (source_device == blink::kWebGestureDeviceSyntheticAutoscroll) fling_cancel.data.fling_cancel.prevent_boosting = true; GestureEventWithLatencyInfo fling_cancel_with_latency(fling_cancel); - fling_controller_->FilterGestureEvent(fling_cancel_with_latency); + fling_controller_->ObserveAndMaybeConsumeGestureEvent( + fling_cancel_with_latency); } void ProgressFling(base::TimeTicks current_time) {
diff --git a/content/browser/renderer_host/input/fling_scheduler_unittest.cc b/content/browser/renderer_host/input/fling_scheduler_unittest.cc index 1a13b4f..4a18b3d 100644 --- a/content/browser/renderer_host/input/fling_scheduler_unittest.cc +++ b/content/browser/renderer_host/input/fling_scheduler_unittest.cc
@@ -86,7 +86,8 @@ fling_start.data.fling_start.velocity_x = velocity.x(); fling_start.data.fling_start.velocity_y = velocity.y(); GestureEventWithLatencyInfo fling_start_with_latency(fling_start); - fling_controller_->FilterGestureEvent(fling_start_with_latency); + fling_controller_->ObserveAndMaybeConsumeGestureEvent( + fling_start_with_latency); } void SimulateFlingCancel() { @@ -95,7 +96,8 @@ blink::kWebGestureDeviceTouchscreen); fling_cancel.data.fling_cancel.prevent_boosting = true; GestureEventWithLatencyInfo fling_cancel_with_latency(fling_cancel); - fling_controller_->FilterGestureEvent(fling_cancel_with_latency); + fling_controller_->ObserveAndMaybeConsumeGestureEvent( + fling_cancel_with_latency); } // FlingControllerEventSenderClient
diff --git a/content/browser/renderer_host/input/gesture_event_queue.cc b/content/browser/renderer_host/input/gesture_event_queue.cc index e9d5dc6..d266c05 100644 --- a/content/browser/renderer_host/input/gesture_event_queue.cc +++ b/content/browser/renderer_host/input/gesture_event_queue.cc
@@ -44,7 +44,7 @@ bool GestureEventQueue::DebounceOrForwardEvent( const GestureEventWithLatencyInfo& gesture_event) { - // GFS and GFC should have been filtered in FlingControllerFilterEvent. + // GFS and GFC should have been filtered in PassToFlingController. DCHECK_NE(gesture_event.event.GetType(), WebInputEvent::kGestureFlingStart); DCHECK_NE(gesture_event.event.GetType(), WebInputEvent::kGestureFlingCancel); if (!ShouldForwardForBounceReduction(gesture_event)) @@ -54,10 +54,10 @@ return true; } -bool GestureEventQueue::FlingControllerFilterEvent( +bool GestureEventQueue::PassToFlingController( const GestureEventWithLatencyInfo& gesture_event) { TRACE_EVENT0("input", "GestureEventQueue::QueueEvent"); - return fling_controller_.FilterGestureEvent(gesture_event); + return fling_controller_.ObserveAndMaybeConsumeGestureEvent(gesture_event); } void GestureEventQueue::QueueDeferredEvents( @@ -152,8 +152,8 @@ void GestureEventQueue::ForwardGestureEvent( const GestureEventWithLatencyInfo& gesture_event) { - // GFS and GFC should have been filtered in FlingControllerFilterEvent to - // get handled by fling controller. + // GFS and GFC should have been filtered in PassToFlingController to get + // handled by fling controller. DCHECK_NE(gesture_event.event.GetType(), WebInputEvent::kGestureFlingStart); DCHECK_NE(gesture_event.event.GetType(), WebInputEvent::kGestureFlingCancel); sent_events_awaiting_ack_.push_back(gesture_event); @@ -222,7 +222,7 @@ debouncing_deferral_queue.swap(debouncing_deferral_queue_); for (GestureQueue::const_iterator it = debouncing_deferral_queue.begin(); it != debouncing_deferral_queue.end(); it++) { - if (!fling_controller_.FilterGestureEvent(*it)) { + if (!fling_controller_.ObserveAndMaybeConsumeGestureEvent(*it)) { if (it->event.GetType() == WebInputEvent::kGestureScrollEnd) scroll_end_filtered_by_deboucing_deferral_queue_ = false; ForwardGestureEvent(*it);
diff --git a/content/browser/renderer_host/input/gesture_event_queue.h b/content/browser/renderer_host/input/gesture_event_queue.h index 503347f..48976bcf 100644 --- a/content/browser/renderer_host/input/gesture_event_queue.h +++ b/content/browser/renderer_host/input/gesture_event_queue.h
@@ -80,10 +80,10 @@ const Config& config); ~GestureEventQueue(); - // Uses fling controller to filter the gesture event. Returns true if the - // event was filtered by the fling controller and shouldn't be further + // Allow the fling controller to observe the gesture event. Returns true if + // the event was filtered by the fling controller and shouldn't be further // forwarded. - bool FlingControllerFilterEvent(const GestureEventWithLatencyInfo&); + bool PassToFlingController(const GestureEventWithLatencyInfo&); // Filter the event for debouncing or forward it to the renderer. Returns // true if the event was forwarded, false if was filtered for debouncing.
diff --git a/content/browser/renderer_host/input/gesture_event_queue_unittest.cc b/content/browser/renderer_host/input/gesture_event_queue_unittest.cc index e5d7ffc..63be8fe 100644 --- a/content/browser/renderer_host/input/gesture_event_queue_unittest.cc +++ b/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
@@ -113,7 +113,7 @@ void SimulateGestureEvent(const WebGestureEvent& gesture) { GestureEventWithLatencyInfo gesture_event(gesture); - if (!queue()->FlingControllerFilterEvent(gesture_event)) { + if (!queue()->PassToFlingController(gesture_event)) { queue()->DebounceOrForwardEvent(gesture_event); } }
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc index 04ee7dd..b103fee2 100644 --- a/content/browser/renderer_host/input/input_router_impl.cc +++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -138,7 +138,7 @@ GestureEventWithLatencyInfo gesture_event(original_gesture_event); - if (gesture_event_queue_.FlingControllerFilterEvent(gesture_event)) { + if (gesture_event_queue_.PassToFlingController(gesture_event)) { disposition_handler_->OnGestureEventAck(gesture_event, InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_CONSUMED);
diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host.cc b/content/browser/renderer_host/media/media_devices_dispatcher_host.cc index 4624422..de160ca6 100644 --- a/content/browser/renderer_host/media/media_devices_dispatcher_host.cc +++ b/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
@@ -106,7 +106,9 @@ EnumerateDevicesCallback client_callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!request_audio_input && !request_video_input && !request_audio_output) { + if ((!request_audio_input && !request_video_input && !request_audio_output) || + (request_video_input_capabilities && !request_video_input) || + (request_audio_input_capabilities && !request_audio_input)) { bad_message::ReceivedBadMessage( render_process_id_, bad_message::MDDH_INVALID_DEVICE_TYPE_REQUEST); return;
diff --git a/content/browser/renderer_host/media/media_devices_manager.cc b/content/browser/renderer_host/media/media_devices_manager.cc index 2136faa3..8cd6a561 100644 --- a/content/browser/renderer_host/media/media_devices_manager.cc +++ b/content/browser/renderer_host/media/media_devices_manager.cc
@@ -429,6 +429,12 @@ bool request_audio_input_capabilities, EnumerateDevicesCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK(request_video_input_capabilities && + requested_types[blink::MEDIA_DEVICE_TYPE_VIDEO_INPUT] || + !request_video_input_capabilities); + DCHECK(request_audio_input_capabilities && + requested_types[blink::MEDIA_DEVICE_TYPE_AUDIO_INPUT] || + !request_audio_input_capabilities); base::PostTaskAndReplyWithResult( base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}).get(),
diff --git a/content/browser/service_worker/service_worker_content_settings_proxy_impl.cc b/content/browser/service_worker/service_worker_content_settings_proxy_impl.cc index f768373..f23f068 100644 --- a/content/browser/service_worker/service_worker_content_settings_proxy_impl.cc +++ b/content/browser/service_worker/service_worker_content_settings_proxy_impl.cc
@@ -49,6 +49,29 @@ render_frames)); } +void ServiceWorkerContentSettingsProxyImpl::AllowCacheStorage( + AllowCacheStorageCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + // May be shutting down. + if (!context_ || !context_->wrapper()->resource_context()) { + std::move(callback).Run(false); + return; + } + if (origin_.opaque()) { + std::move(callback).Run(false); + return; + } + // |render_frames| is used to show UI for the frames affected by the + // content setting. However, service worker is not necessarily associated + // with frames or making the request on behalf of frames, + // so just pass an empty |render_frames|. + std::vector<GlobalFrameRoutingId> render_frames; + std::move(callback).Run( + GetContentClient()->browser()->AllowWorkerCacheStorage( + origin_.GetURL(), context_->wrapper()->resource_context(), + render_frames)); +} + void ServiceWorkerContentSettingsProxyImpl::RequestFileSystemAccessSync( RequestFileSystemAccessSyncCallback callback) { mojo::ReportBadMessage(
diff --git a/content/browser/service_worker/service_worker_content_settings_proxy_impl.h b/content/browser/service_worker/service_worker_content_settings_proxy_impl.h index 77f86b3f..a736928 100644 --- a/content/browser/service_worker/service_worker_content_settings_proxy_impl.h +++ b/content/browser/service_worker/service_worker_content_settings_proxy_impl.h
@@ -34,6 +34,7 @@ // blink::mojom::WorkerContentSettingsProxy implementation void AllowIndexedDB(AllowIndexedDBCallback callback) override; + void AllowCacheStorage(AllowCacheStorageCallback callback) override; void RequestFileSystemAccessSync( RequestFileSystemAccessSyncCallback callback) override;
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.cc b/content/browser/service_worker/service_worker_controllee_request_handler.cc index 6cab376..54f561d1 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler.cc +++ b/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -175,74 +175,6 @@ provider_host_->controller()->DeferScheduledUpdate(); } -net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob( - net::URLRequest* request, - net::NetworkDelegate* network_delegate, - ResourceContext* resource_context) { - ClearJob(); - ServiceWorkerResponseInfo::ResetDataForRequest(request); - - if (!context_ || !provider_host_) { - // We can't do anything other than to fall back to network. - return nullptr; - } - - // This may get called multiple times for original and redirect requests: - // A. original request case: use_network_ is false, no previous location info. - // B. redirect or restarted request case: - // a) use_network_ is false if the previous location was forwarded to SW. - // b) use_network_ is false if the previous location was fallback. - // c) use_network_ is true if additional restart was required to fall back. - - // Fall back to network. (Case B-c) - if (use_network_) { - // Once a subresource request has fallen back to the network once, it will - // never be handled by a service worker. This is not true of main frame - // requests. - if (is_main_resource_load_) - use_network_ = false; - return nullptr; - } - -#if BUILDFLAG(ENABLE_OFFLINE_PAGES) - // Fall back for the subsequent offline page interceptor to load the offline - // snapshot of the page if required. - if (ShouldFallbackToLoadOfflinePage(request->extra_request_headers())) - return nullptr; -#endif // BUILDFLAG(ENABLE_OFFLINE_PAGES) - - // It's for original request (A) or redirect case (B-a or B-b). - auto job = std::make_unique<ServiceWorkerURLRequestJob>( - request, network_delegate, provider_host_, blob_storage_context_, - resource_context, request_mode_, credentials_mode_, redirect_mode_, - integrity_, keepalive_, resource_type_, request_context_type_, - frame_type_, body_, this); - url_job_ = std::make_unique<ServiceWorkerURLJobWrapper>(job->GetWeakPtr()); - - resource_context_ = resource_context; - - if (is_main_resource_load_) - PrepareForMainResource(request->url(), request->site_for_cookies()); - else - PrepareForSubResource(); - - if (url_job_->ShouldFallbackToNetwork()) { - // If we know we can fallback to network at this point (in case - // the storage lookup returned immediately), just destroy the job and return - // NULL here to fallback to network. - - // If this is a subresource request, all subsequent requests should also use - // the network. - if (!is_main_resource_load_) - use_network_ = true; - - job.reset(); - ClearJob(); - } - - return job.release(); -} - void ServiceWorkerControlleeRequestHandler::MaybeCreateLoader( const network::ResourceRequest& tentative_resource_request, ResourceContext* resource_context,
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.h b/content/browser/service_worker/service_worker_controllee_request_handler.h index 4f557eb..1eb88992 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler.h +++ b/content/browser/service_worker/service_worker_controllee_request_handler.h
@@ -25,11 +25,6 @@ #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" #include "url/gurl.h" -namespace net { -class NetworkDelegate; -class URLRequest; -} - namespace network { class ResourceRequestBody; } @@ -63,19 +58,6 @@ scoped_refptr<network::ResourceRequestBody> body); ~ServiceWorkerControlleeRequestHandler() override; - // Non-S13nServiceWorker: - // Called via custom URLRequestJobFactory. - // Returning a nullptr indicates that the request is not handled by - // this handler. - // This could get called multiple times during the lifetime. - net::URLRequestJob* MaybeCreateJob( - net::URLRequest* request, - net::NetworkDelegate* network_delegate, - ResourceContext* resource_context) override; - - // S13nServiceWorker: - // MaybeCreateLoader replaces MaybeCreateJob() when S13nServiceWorker is - // enabled. // This could get called multiple times during the lifetime in redirect // cases. (In fallback-to-network cases we basically forward the request // to the request to the next request handler)
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc index 1ac76b0..f4150f5 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc +++ b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
@@ -69,11 +69,6 @@ scoped_refptr<network::ResourceRequestBody>())), job_(nullptr) {} - ServiceWorkerURLRequestJob* MaybeCreateJob() { - job_.reset(handler_->MaybeCreateJob(request_.get(), nullptr, nullptr)); - return static_cast<ServiceWorkerURLRequestJob*>(job_.get()); - } - void MaybeCreateLoader() { network::ResourceRequest resource_request; resource_request.url = request_->url();
diff --git a/content/browser/service_worker/service_worker_installed_script_loader.cc b/content/browser/service_worker/service_worker_installed_script_loader.cc index 2a6df6c4..917a79d 100644 --- a/content/browser/service_worker/service_worker_installed_script_loader.cc +++ b/content/browser/service_worker/service_worker_installed_script_loader.cc
@@ -11,7 +11,6 @@ #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_storage.h" #include "content/browser/service_worker/service_worker_version.h" -#include "content/browser/service_worker/service_worker_write_to_cache_job.h" #include "content/browser/url_loader_factory_getter.h" #include "content/common/service_worker/service_worker_utils.h" #include "net/base/ip_endpoint.h"
diff --git a/content/browser/service_worker/service_worker_new_script_loader.cc b/content/browser/service_worker/service_worker_new_script_loader.cc index 9a4ebc2..849d52be 100644 --- a/content/browser/service_worker/service_worker_new_script_loader.cc +++ b/content/browser/service_worker/service_worker_new_script_loader.cc
@@ -14,11 +14,11 @@ #include "content/browser/service_worker/service_worker_disk_cache.h" #include "content/browser/service_worker/service_worker_storage.h" #include "content/browser/service_worker/service_worker_version.h" -#include "content/browser/service_worker/service_worker_write_to_cache_job.h" #include "content/browser/url_loader_factory_getter.h" #include "content/common/service_worker/service_worker_utils.h" #include "net/base/ip_endpoint.h" #include "net/base/load_flags.h" +#include "net/base/net_errors.h" #include "net/cert/cert_status_flags.h" #include "services/network/public/cpp/resource_response.h" #include "third_party/blink/public/common/mime_util/mime_util.h" @@ -561,7 +561,7 @@ if (!cache_writer_->did_replace()) { version_->SetStartWorkerStatusCode( blink::ServiceWorkerStatusCode::kErrorExists); - error_code = ServiceWorkerWriteToCacheJob::kIdenticalScriptError; + error_code = net::ERR_FILE_EXISTS; } bytes_written = cache_writer_->bytes_written(); } else {
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index c19abba..c342250 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -80,18 +80,6 @@ resource_type) {} ~ServiceWorkerURLTrackingRequestHandler() override {} - // Called via custom URLRequestJobFactory. - net::URLRequestJob* MaybeCreateJob(net::URLRequest* request, - net::NetworkDelegate*, - ResourceContext*) override { - // |provider_host_| may have been deleted when the request is resumed. - if (!provider_host_) - return nullptr; - const GURL stripped_url = net::SimplifyUrlForRequest(request->url()); - provider_host_->UpdateUrls(stripped_url, request->site_for_cookies()); - return nullptr; - } - void MaybeCreateLoader( const network::ResourceRequest& tentative_resource_request, ResourceContext*,
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc index 99b0c6c..41e82056 100644 --- a/content/browser/service_worker/service_worker_register_job.cc +++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -21,7 +21,6 @@ #include "content/browser/service_worker/service_worker_registration.h" #include "content/browser/service_worker/service_worker_storage.h" #include "content/browser/service_worker/service_worker_version.h" -#include "content/browser/service_worker/service_worker_write_to_cache_job.h" #include "content/browser/url_loader_factory_getter.h" #include "content/common/service_worker/service_worker_types.h" #include "content/common/service_worker/service_worker_utils.h" @@ -700,8 +699,7 @@ // OnPausedAfterDownload() signifies a successful network load, which // translates into a script cache error only in the byte-for-byte identical // case. - DCHECK_EQ(status.error(), - ServiceWorkerWriteToCacheJob::kIdenticalScriptError); + DCHECK_EQ(status.error(), net::ERR_FILE_EXISTS); BumpLastUpdateCheckTimeIfNeeded(); ResolvePromise(blink::ServiceWorkerStatusCode::kOk, std::string(),
diff --git a/content/browser/service_worker/service_worker_request_handler.cc b/content/browser/service_worker/service_worker_request_handler.cc index b32c8f49..f742c0ac 100644 --- a/content/browser/service_worker/service_worker_request_handler.cc +++ b/content/browser/service_worker/service_worker_request_handler.cc
@@ -25,7 +25,6 @@ #include "content/public/common/url_constants.h" #include "ipc/ipc_message.h" #include "net/base/url_util.h" -#include "net/url_request/url_request.h" #include "services/network/public/cpp/resource_request_body.h" #include "storage/browser/blob/blob_storage_context.h" #include "third_party/blink/public/common/service_worker/service_worker_utils.h" @@ -135,81 +134,6 @@ return base::WrapUnique<NavigationLoaderInterceptor>(handler.release()); } -// static -void ServiceWorkerRequestHandler::InitializeHandler( - net::URLRequest* request, - ServiceWorkerContextWrapper* context_wrapper, - storage::BlobStorageContext* blob_storage_context, - int process_id, - int provider_id, - bool skip_service_worker, - network::mojom::FetchRequestMode request_mode, - network::mojom::FetchCredentialsMode credentials_mode, - network::mojom::FetchRedirectMode redirect_mode, - const std::string& integrity, - bool keepalive, - ResourceType resource_type, - blink::mojom::RequestContextType request_context_type, - network::mojom::RequestContextFrameType frame_type, - scoped_refptr<network::ResourceRequestBody> body) { - // S13nServiceWorker enabled, NetworkService disabled: - // for subresource requests, subresource loader should be used, but when that - // request handler falls back to network, InitializeHandler() is called. - // Since we already determined to fall back to network, don't create another - // handler. - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - // Create the handler even for insecure HTTP since it's used in the - // case of redirect to HTTPS. - if (!request->url().SchemeIsHTTPOrHTTPS() && - !OriginCanAccessServiceWorkers(request->url())) { - return; - } - - if (!context_wrapper || !context_wrapper->context() || - provider_id == kInvalidServiceWorkerProviderId) { - return; - } - - ServiceWorkerProviderHost* provider_host = - context_wrapper->context()->GetProviderHost(provider_id); - if (!provider_host || !provider_host->IsContextAlive()) - return; - - std::unique_ptr<ServiceWorkerRequestHandler> handler( - provider_host->CreateRequestHandler( - request_mode, credentials_mode, redirect_mode, integrity, keepalive, - resource_type, request_context_type, frame_type, - blob_storage_context->AsWeakPtr(), body, skip_service_worker)); - if (handler) - request->SetUserData(&user_data_key_, std::move(handler)); -} - -// static -ServiceWorkerRequestHandler* ServiceWorkerRequestHandler::GetHandler( - const net::URLRequest* request) { - return static_cast<ServiceWorkerRequestHandler*>( - request->GetUserData(&user_data_key_)); -} - -// static -bool ServiceWorkerRequestHandler::IsControlledByServiceWorker( - const net::URLRequest* request) { - ServiceWorkerRequestHandler* handler = GetHandler(request); - if (!handler || !handler->provider_host_) - return false; - return handler->provider_host_->controller() || - handler->provider_host_->running_hosted_version(); -} - -// static -ServiceWorkerProviderHost* ServiceWorkerRequestHandler::GetProviderHost( - const net::URLRequest* request) { - ServiceWorkerRequestHandler* handler = GetHandler(request); - return handler ? handler->provider_host_.get() : nullptr; -} - void ServiceWorkerRequestHandler::MaybeCreateLoader( const network::ResourceRequest& tentative_request, ResourceContext* resource_context,
diff --git a/content/browser/service_worker/service_worker_request_handler.h b/content/browser/service_worker/service_worker_request_handler.h index 9e723d58..3cf10ff 100644 --- a/content/browser/service_worker/service_worker_request_handler.h +++ b/content/browser/service_worker/service_worker_request_handler.h
@@ -11,22 +11,15 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/supports_user_data.h" -#include "base/time/time.h" #include "content/browser/loader/navigation_loader_interceptor.h" #include "content/common/content_export.h" #include "content/common/service_worker/service_worker_types.h" #include "content/public/common/resource_type.h" -#include "net/url_request/url_request_job_factory.h" #include "services/network/public/mojom/fetch_api.mojom.h" #include "services/network/public/mojom/request_context_frame_type.mojom.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" -namespace net { -class NetworkDelegate; -class URLRequest; -} - namespace network { class ResourceRequestBody; } @@ -39,7 +32,6 @@ class ResourceContext; class ServiceWorkerContextCore; -class ServiceWorkerContextWrapper; class ServiceWorkerNavigationHandleCore; class ServiceWorkerProviderHost; class WebContents; @@ -73,53 +65,8 @@ const network::ResourceRequest& resource_request, base::WeakPtr<ServiceWorkerProviderHost> host); - // Attaches a newly created handler if the given |request| needs to - // be handled by ServiceWorker. - // TODO(kinuko): While utilizing UserData to attach data to URLRequest - // has some precedence, it might be better to attach this handler in a more - // explicit way within content layer, e.g. have ResourceRequestInfoImpl - // own it. - static void InitializeHandler( - net::URLRequest* request, - ServiceWorkerContextWrapper* context_wrapper, - storage::BlobStorageContext* blob_storage_context, - int process_id, - int provider_id, - bool skip_service_worker, - network::mojom::FetchRequestMode request_mode, - network::mojom::FetchCredentialsMode credentials_mode, - network::mojom::FetchRedirectMode redirect_mode, - const std::string& integrity, - bool keepalive, - ResourceType resource_type, - blink::mojom::RequestContextType request_context_type, - network::mojom::RequestContextFrameType frame_type, - scoped_refptr<network::ResourceRequestBody> body); - - // Returns the handler attached to |request|. This may return NULL - // if no handler is attached. - static ServiceWorkerRequestHandler* GetHandler( - const net::URLRequest* request); - - // Returns true if the request falls into the scope of a ServiceWorker. - // It's only reliable after the ServiceWorkerRequestHandler MaybeCreateJob - // method runs to completion for this request. The AppCache handler uses - // this to avoid colliding with ServiceWorkers. - static bool IsControlledByServiceWorker(const net::URLRequest* request); - - // Returns the ServiceWorkerProviderHost the request is associated with. - // Only valid after InitializeHandler has been called. Can return null. - static ServiceWorkerProviderHost* GetProviderHost( - const net::URLRequest* request); - ~ServiceWorkerRequestHandler() override; - // Called via custom URLRequestJobFactory. - virtual net::URLRequestJob* MaybeCreateJob( - net::URLRequest* request, - net::NetworkDelegate* network_delegate, - ResourceContext* context) = 0; - // NavigationLoaderInterceptor overrides. void MaybeCreateLoader(const network::ResourceRequest& tentative_request, ResourceContext* resource_context,
diff --git a/content/browser/service_worker/service_worker_request_handler_unittest.cc b/content/browser/service_worker/service_worker_request_handler_unittest.cc index ceac781f..30b62bd0 100644 --- a/content/browser/service_worker/service_worker_request_handler_unittest.cc +++ b/content/browser/service_worker/service_worker_request_handler_unittest.cc
@@ -50,13 +50,6 @@ } protected: - void InitializeProviderHostForWindow() { - // An empty host. - provider_host_ = CreateProviderHostForWindow( - helper_->mock_render_process_id(), true /* is_parent_frame_secure */, - context()->AsWeakPtr(), &remote_endpoint_); - } - static std::unique_ptr<ServiceWorkerNavigationHandleCore> CreateNavigationHandleCore(ServiceWorkerContextWrapper* context_wrapper) { std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core; @@ -78,58 +71,6 @@ return navigation_handle_core; } - std::unique_ptr<net::URLRequest> CreateRequest(const std::string& url, - const std::string& method) { - std::unique_ptr<net::URLRequest> request = - url_request_context_.CreateRequest(GURL(url), net::DEFAULT_PRIORITY, - &url_request_delegate_, - TRAFFIC_ANNOTATION_FOR_TESTS); - request->set_method(method); - return request; - } - - void InitializeHandler(net::URLRequest* request, - bool skip_service_worker, - ResourceType resource_type) { - ServiceWorkerRequestHandler::InitializeHandler( - request, context_wrapper(), &blob_storage_context_, - helper_->mock_render_process_id(), provider_host_->provider_id(), - skip_service_worker, network::mojom::FetchRequestMode::kNoCors, - network::mojom::FetchCredentialsMode::kOmit, - network::mojom::FetchRedirectMode::kFollow, - std::string() /* integrity */, false /* keepalive */, resource_type, - blink::mojom::RequestContextType::HYPERLINK, - network::mojom::RequestContextFrameType::kTopLevel, nullptr); - } - - static ServiceWorkerRequestHandler* GetHandler(net::URLRequest* request) { - return ServiceWorkerRequestHandler::GetHandler(request); - } - - std::unique_ptr<net::URLRequestJob> MaybeCreateJob(net::URLRequest* request) { - return std::unique_ptr<net::URLRequestJob>( - GetHandler(request)->MaybeCreateJob( - request, url_request_context_.network_delegate(), - context_wrapper()->resource_context())); - } - - void InitializeHandlerSimpleTest(const std::string& url, - const std::string& method, - bool skip_service_worker, - ResourceType resource_type) { - // Skip handler initialization tests when S13nServiceWorker is enabled - // because we don't use this path. See also comments in - // ServiceWorkerRequestHandler::InitializeHandler(). - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - InitializeProviderHostForWindow(); - std::unique_ptr<net::URLRequest> request = CreateRequest(url, method); - InitializeHandler(request.get(), skip_service_worker, resource_type); - ASSERT_TRUE(GetHandler(request.get())); - MaybeCreateJob(request.get()); - EXPECT_EQ(url, provider_host_->url().spec()); - } - void InitializeHandlerForNavigationSimpleTest(const std::string& url, bool expected_handler_created) { std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core = @@ -157,62 +98,6 @@ ServiceWorkerRemoteProviderEndpoint remote_endpoint_; }; -TEST_F(ServiceWorkerRequestHandlerTest, InitializeHandler_FTP) { - InitializeProviderHostForWindow(); - std::unique_ptr<net::URLRequest> request = - CreateRequest("ftp://host/scope/doc", "GET"); - InitializeHandler(request.get(), false, RESOURCE_TYPE_MAIN_FRAME); - // Cannot initialize a handler for non-secure origins. - EXPECT_FALSE(GetHandler(request.get())); -} - -TEST_F(ServiceWorkerRequestHandlerTest, InitializeHandler_HTTP_MAIN_FRAME) { - // HTTP should have the handler because the response is possible to be a - // redirect to HTTPS. - InitializeHandlerSimpleTest("http://host/scope/doc", "GET", false, - RESOURCE_TYPE_MAIN_FRAME); -} - -TEST_F(ServiceWorkerRequestHandlerTest, InitializeHandler_HTTPS_MAIN_FRAME) { - InitializeHandlerSimpleTest("https://host/scope/doc", "GET", false, - RESOURCE_TYPE_MAIN_FRAME); -} - -TEST_F(ServiceWorkerRequestHandlerTest, InitializeHandler_HTTP_SUB_FRAME) { - // HTTP should have the handler because the response is possible to be a - // redirect to HTTPS. - InitializeHandlerSimpleTest("http://host/scope/doc", "GET", false, - RESOURCE_TYPE_SUB_FRAME); -} - -TEST_F(ServiceWorkerRequestHandlerTest, InitializeHandler_HTTPS_SUB_FRAME) { - InitializeHandlerSimpleTest("https://host/scope/doc", "GET", false, - RESOURCE_TYPE_SUB_FRAME); -} - -TEST_F(ServiceWorkerRequestHandlerTest, InitializeHandler_HTTPS_OPTIONS) { - // OPTIONS is also supported. See crbug.com/434660. - InitializeHandlerSimpleTest("https://host/scope/doc", "OPTIONS", false, - RESOURCE_TYPE_MAIN_FRAME); -} - -TEST_F(ServiceWorkerRequestHandlerTest, InitializeHandler_HTTPS_SKIP) { - InitializeHandlerSimpleTest("https://host/scope/doc", "GET", true, - RESOURCE_TYPE_MAIN_FRAME); -} - -TEST_F(ServiceWorkerRequestHandlerTest, InitializeHandler_IMAGE) { - InitializeProviderHostForWindow(); - // Check provider host's URL after initializing a handler for an image. - provider_host_.get()->UpdateUrls(GURL("https://host/scope/doc"), - GURL("https://host/scope/doc")); - std::unique_ptr<net::URLRequest> request = - CreateRequest("https://host/scope/image", "GET"); - InitializeHandler(request.get(), true, RESOURCE_TYPE_IMAGE); - ASSERT_FALSE(GetHandler(request.get())); - EXPECT_EQ(GURL("https://host/scope/doc"), provider_host_->url()); -} - TEST_F(ServiceWorkerRequestHandlerTest, InitializeForNavigation_HTTP) { InitializeHandlerForNavigationSimpleTest("http://host/scope/doc", true); }
diff --git a/content/browser/service_worker/service_worker_storage.h b/content/browser/service_worker/service_worker_storage.h index 72abeea..9a69a5f 100644 --- a/content/browser/service_worker/service_worker_storage.h +++ b/content/browser/service_worker/service_worker_storage.h
@@ -47,10 +47,6 @@ class ServiceWorkerResponseWriter; struct ServiceWorkerRegistrationInfo; -namespace service_worker_write_to_cache_job_unittest { -class ServiceWorkerWriteToCacheJobTest; -} // namespace service_worker_write_to_cache_job_unittest - namespace service_worker_storage_unittest { class ServiceWorkerStorageTest; class ServiceWorkerResourceStorageTest; @@ -286,8 +282,6 @@ friend class service_worker_storage_unittest::ServiceWorkerStorageTest; friend class service_worker_storage_unittest:: ServiceWorkerResourceStorageTest; - friend class service_worker_write_to_cache_job_unittest:: - ServiceWorkerWriteToCacheJobTest; FRIEND_TEST_ALL_PREFIXES( service_worker_storage_unittest::ServiceWorkerResourceStorageDiskTest, CleanupOnRestart);
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job.cc b/content/browser/service_worker/service_worker_write_to_cache_job.cc deleted file mode 100644 index 95be06c..0000000 --- a/content/browser/service_worker/service_worker_write_to_cache_job.cc +++ /dev/null
@@ -1,522 +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/browser/service_worker/service_worker_write_to_cache_job.h" - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/trace_event/trace_event.h" -#include "content/browser/service_worker/service_worker_cache_writer.h" -#include "content/browser/service_worker/service_worker_context_core.h" -#include "content/browser/service_worker/service_worker_disk_cache.h" -#include "content/browser/service_worker/service_worker_metrics.h" -#include "content/common/net/url_request_service_worker_data.h" -#include "content/common/service_worker/service_worker_types.h" -#include "content/common/service_worker/service_worker_utils.h" -#include "net/base/io_buffer.h" -#include "net/base/net_errors.h" -#include "net/base/url_util.h" -#include "net/http/http_network_session.h" -#include "net/http/http_request_headers.h" -#include "net/http/http_response_headers.h" -#include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/url_request.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_status.h" -#include "third_party/blink/public/common/mime_util/mime_util.h" -#include "third_party/blink/public/web/web_console_message.h" - -namespace content { - -namespace { - -const char kKilledError[] = "The request to fetch the script was interrupted."; -const char kClientAuthenticationError[] = - "Client authentication was required to fetch the script."; - -bool ShouldIgnoreSSLError(net::URLRequest* request) { - const net::HttpNetworkSession::Params* session_params = - request->context()->GetNetworkSessionParams(); - if (session_params && session_params->ignore_certificate_errors) - return true; - bool allow_localhost = base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAllowInsecureLocalhost); - if (allow_localhost && net::IsLocalhost(request->url())) - return true; - return false; -} - -} // namespace - -const net::Error ServiceWorkerWriteToCacheJob::kIdenticalScriptError = - net::ERR_FILE_EXISTS; - -ServiceWorkerWriteToCacheJob::ServiceWorkerWriteToCacheJob( - net::URLRequest* request, - net::NetworkDelegate* network_delegate, - ResourceType resource_type, - base::WeakPtr<ServiceWorkerContextCore> context, - ServiceWorkerVersion* version, - int extra_load_flags, - int64_t resource_id, - int64_t incumbent_resource_id) - : net::URLRequestJob(request, network_delegate), - resource_type_(resource_type), - context_(context), - url_(request->url()), - resource_id_(resource_id), - incumbent_resource_id_(incumbent_resource_id), - version_(version), - weak_factory_(this) { - DCHECK(version_); - -#if DCHECK_IS_ON() - switch (version_->script_type()) { - case blink::mojom::ScriptType::kClassic: - // For classic scripts, the main service worker script should have the - // "service worker" resource type and imported scripts should have the - // "script" resource type. - DCHECK(resource_type_ == RESOURCE_TYPE_SCRIPT || - (resource_type_ == RESOURCE_TYPE_SERVICE_WORKER && - version_->script_url() == url_)); - break; - case blink::mojom::ScriptType::kModule: - // For module scripts, both the main service worker script and - // static-imported scripts should have the "service worker" resource type - // because static import inherits the resource type of the top-level - // module script. - DCHECK_EQ(RESOURCE_TYPE_SERVICE_WORKER, resource_type_); - break; - } -#endif // DCHECK_IS_ON() - InitNetRequest(extra_load_flags); -} - -ServiceWorkerWriteToCacheJob::~ServiceWorkerWriteToCacheJob() { - Kill(); - DCHECK_EQ(did_notify_started_, did_notify_finished_); -} - -void ServiceWorkerWriteToCacheJob::Start() { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&ServiceWorkerWriteToCacheJob::StartAsync, - weak_factory_.GetWeakPtr())); -} - -void ServiceWorkerWriteToCacheJob::StartAsync() { - TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker", - "ServiceWorkerWriteToCacheJob::ExecutingJob", - this, - "URL", request_->url().spec()); - if (!context_) { - // NotifyStartError is not safe to call synchronously in Start(). - NotifyStartError( - net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED)); - return; - } - - if (ShouldByteForByteCheck()) { - // Create response readers only when we have to do the byte-for-byte check. - cache_writer_ = ServiceWorkerCacheWriter::CreateForComparison( - context_->storage()->CreateResponseReader(incumbent_resource_id_), - context_->storage()->CreateResponseReader(incumbent_resource_id_), - context_->storage()->CreateResponseWriter(resource_id_), - false /* pause_when_not_identical */); - } else { - cache_writer_ = ServiceWorkerCacheWriter::CreateForWriteBack( - context_->storage()->CreateResponseWriter(resource_id_)); - } - - version_->script_cache_map()->NotifyStartedCaching(url_, resource_id_); - did_notify_started_ = true; - StartNetRequest(); -} - -void ServiceWorkerWriteToCacheJob::Kill() { - if (has_been_killed_) - return; - weak_factory_.InvalidateWeakPtrs(); - has_been_killed_ = true; - net_request_.reset(); - if (did_notify_started_) { - net::Error error = NotifyFinishedCaching(net::ERR_ABORTED, kKilledError); - DCHECK_EQ(net::ERR_ABORTED, error); - } - writer_.reset(); - context_.reset(); - net::URLRequestJob::Kill(); -} - -net::LoadState ServiceWorkerWriteToCacheJob::GetLoadState() const { - if (writer_ && writer_->IsWritePending()) - return net::LOAD_STATE_WAITING_FOR_APPCACHE; - if (net_request_) - return net_request_->GetLoadState().state; - return net::LOAD_STATE_IDLE; -} - -bool ServiceWorkerWriteToCacheJob::GetCharset(std::string* charset) { - if (!http_info()) - return false; - return http_info()->headers->GetCharset(charset); -} - -bool ServiceWorkerWriteToCacheJob::GetMimeType(std::string* mime_type) const { - if (!http_info()) - return false; - return http_info()->headers->GetMimeType(mime_type); -} - -void ServiceWorkerWriteToCacheJob::GetResponseInfo( - net::HttpResponseInfo* info) { - if (!http_info()) - return; - *info = *http_info(); -} - -void ServiceWorkerWriteToCacheJob::SetExtraRequestHeaders( - const net::HttpRequestHeaders& headers) { - std::string value; - DCHECK(!headers.GetHeader(net::HttpRequestHeaders::kRange, &value)); - net_request_->SetExtraRequestHeaders(headers); -} - -int ServiceWorkerWriteToCacheJob::ReadRawData(net::IOBuffer* buf, - int buf_size) { - int rv = ReadNetData(buf, buf_size); - if (rv == net::ERR_IO_PENDING) - return net::ERR_IO_PENDING; - - if (rv < 0) { - net::Error error = static_cast<net::Error>(rv); - error = NotifyFinishedCaching(error, kServiceWorkerFetchScriptError); - DCHECK_EQ(rv, error); - return error; - } - - return HandleNetData(rv); -} - -const net::HttpResponseInfo* ServiceWorkerWriteToCacheJob::http_info() const { - return http_info_.get(); -} - -void ServiceWorkerWriteToCacheJob::InitNetRequest( - int extra_load_flags) { - DCHECK(request()); - net::NetworkTrafficAnnotationTag traffic_annotation = - net::DefineNetworkTrafficAnnotation("service_worker_write_to_cache_job", - R"( - semantics { - sender: "ServiceWorker System" - description: - "When a ServiceWorker is registered, its script and immediate " - "imports are cached for performance and offline access. The " - "resources are periodically updated." - trigger: - "User visits a site which registers a ServiceWorker." - data: "None" - destination: WEBSITE - } - policy { - cookies_allowed: YES - cookies_store: "user" - setting: - "Users can control this feature via the 'Cookies' setting under " - "'Privacy, Content settings'. If cookies are disabled for a " - "single site, serviceworkers are disabled for the site only. If " - "they are totally disabled, all serviceworker requests will be " - "stopped." - chrome_policy { - DefaultCookiesSetting { - policy_options {mode: MANDATORY} - DefaultCookiesSetting: 2 - } - } - })"); - net_request_ = request()->context()->CreateRequest( - request()->url(), request()->priority(), this, traffic_annotation); - net_request_->set_site_for_cookies(request()->site_for_cookies()); - net_request_->set_initiator(request()->initiator()); - net_request_->SetReferrer(request()->referrer()); - net_request_->SetUserData(URLRequestServiceWorkerData::kUserDataKey, - std::make_unique<URLRequestServiceWorkerData>()); - if (extra_load_flags) - net_request_->SetLoadFlags(net_request_->load_flags() | extra_load_flags); - - // Add the 'Service-Worker' header for the main script request. - // https://w3c.github.io/ServiceWorker/#service-worker-script-request - if (IsMainScript()) { - // This will get copied into net_request_ when URLRequest::StartJob calls - // ServiceWorkerWriteToCacheJob::SetExtraRequestHeaders. - request()->SetExtraRequestHeaderByName("Service-Worker", "script", true); - } -} - -void ServiceWorkerWriteToCacheJob::StartNetRequest() { - TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker", - "ServiceWorkerWriteToCacheJob::ExecutingJob", - this, - "NetRequest"); - net_request_->Start(); // We'll continue in OnResponseStarted. -} - -int ServiceWorkerWriteToCacheJob::ReadNetData(net::IOBuffer* buf, - int buf_size) { - DCHECK_GT(buf_size, 0); - io_buffer_ = buf; - io_buffer_bytes_ = 0; - return net_request_->Read(buf, buf_size); -} - -void ServiceWorkerWriteToCacheJob::OnReceivedRedirect( - net::URLRequest* request, - const net::RedirectInfo& redirect_info, - bool* defer_redirect) { - DCHECK_EQ(net_request_.get(), request); - TRACE_EVENT0("ServiceWorker", - "ServiceWorkerWriteToCacheJob::OnReceivedRedirect"); - // Script resources can't redirect. - NotifyStartErrorHelper(net::ERR_UNSAFE_REDIRECT, kServiceWorkerRedirectError); -} - -void ServiceWorkerWriteToCacheJob::OnAuthRequired( - net::URLRequest* request, - net::AuthChallengeInfo* auth_info) { - DCHECK_EQ(net_request_.get(), request); - TRACE_EVENT0("ServiceWorker", - "ServiceWorkerWriteToCacheJob::OnAuthRequired"); - // TODO(michaeln): Pass this thru to our jobs client. - NotifyStartErrorHelper(net::ERR_FAILED, kClientAuthenticationError); -} - -void ServiceWorkerWriteToCacheJob::OnCertificateRequested( - net::URLRequest* request, - net::SSLCertRequestInfo* cert_request_info) { - DCHECK_EQ(net_request_.get(), request); - TRACE_EVENT0("ServiceWorker", - "ServiceWorkerWriteToCacheJob::OnCertificateRequested"); - // TODO(michaeln): Pass this thru to our jobs client. - // see NotifyCertificateRequested. - NotifyStartErrorHelper(net::ERR_FAILED, kClientAuthenticationError); -} - -void ServiceWorkerWriteToCacheJob::OnSSLCertificateError( - net::URLRequest* request, - const net::SSLInfo& ssl_info, - bool fatal) { - DCHECK_EQ(net_request_.get(), request); - TRACE_EVENT0("ServiceWorker", - "ServiceWorkerWriteToCacheJob::OnSSLCertificateError"); - if (ShouldIgnoreSSLError(request)) { - request->ContinueDespiteLastError(); - } else { - NotifyStartErrorHelper( - net::Error(net::MapCertStatusToNetError(ssl_info.cert_status)), - kServiceWorkerSSLError); - } -} - -void ServiceWorkerWriteToCacheJob::OnResponseStarted(net::URLRequest* request, - int net_error) { - DCHECK_NE(net::ERR_IO_PENDING, net_error); - DCHECK_EQ(net_request_.get(), request); - - if (net_error != net::OK) { - net::Error error = static_cast<net::Error>(net_error); - NotifyStartErrorHelper(error, kServiceWorkerFetchScriptError); - return; - } - if (request->GetResponseCode() / 100 != 2) { - std::string error_message = base::StringPrintf( - kServiceWorkerBadHTTPResponseError, request->GetResponseCode()); - NotifyStartErrorHelper(net::ERR_INVALID_RESPONSE, error_message); - // TODO(michaeln): Instead of error'ing immediately, send the net - // response to our consumer, just don't cache it? - return; - } - // OnSSLCertificateError is not called when the HTTPS connection is reused. - // So we check cert_status here. - if (net::IsCertStatusError(request->ssl_info().cert_status) && - !ShouldIgnoreSSLError(request)) { - NotifyStartErrorHelper(net::Error(net::MapCertStatusToNetError( - request->ssl_info().cert_status)), - kServiceWorkerSSLError); - return; - } - - if (IsMainScript()) { - std::string mime_type; - request->GetMimeType(&mime_type); - if (!blink::IsSupportedJavascriptMimeType(mime_type)) { - std::string error_message = - mime_type.empty() ? kServiceWorkerNoMIMEError - : base::StringPrintf(kServiceWorkerBadMIMEError, - mime_type.c_str()); - NotifyStartErrorHelper(net::ERR_INSECURE_RESPONSE, error_message); - return; - } - - if (!CheckPathRestriction(request)) - return; - - version_->SetMainScriptHttpResponseInfo(net_request_->response_info()); - } - - if (net_request_->response_info().network_accessed && - !(net_request_->response_info().was_cached)) { - version_->embedded_worker()->OnNetworkAccessedForScriptLoad(); - } - - http_info_ = - std::make_unique<net::HttpResponseInfo>(net_request_->response_info()); - scoped_refptr<HttpResponseInfoIOBuffer> info_buffer = - base::MakeRefCounted<HttpResponseInfoIOBuffer>( - std::make_unique<net::HttpResponseInfo>( - net_request_->response_info())); - net::Error error = cache_writer_->MaybeWriteHeaders( - info_buffer.get(), - base::BindOnce(&ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete, - weak_factory_.GetWeakPtr())); - if (error == net::ERR_IO_PENDING) - return; - OnWriteHeadersComplete(error); -} - -void ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete(net::Error error) { - DCHECK_NE(net::ERR_IO_PENDING, error); - if (error != net::OK) { - ServiceWorkerMetrics::CountWriteResponseResult( - ServiceWorkerMetrics::WRITE_HEADERS_ERROR); - NotifyStartError(net::URLRequestStatus::FromError(error)); - return; - } - NotifyHeadersComplete(); -} - -void ServiceWorkerWriteToCacheJob::OnWriteDataComplete(net::Error error) { - DCHECK_NE(net::ERR_IO_PENDING, error); - if (io_buffer_bytes_ == 0) - error = NotifyFinishedCaching(error, ""); - if (error != net::OK) { - ServiceWorkerMetrics::CountWriteResponseResult( - ServiceWorkerMetrics::WRITE_DATA_ERROR); - ReadRawDataComplete(error); - return; - } - ServiceWorkerMetrics::CountWriteResponseResult( - ServiceWorkerMetrics::WRITE_OK); - ReadRawDataComplete(io_buffer_bytes_); -} - -void ServiceWorkerWriteToCacheJob::OnReadCompleted(net::URLRequest* request, - int bytes_read) { - DCHECK_NE(net::ERR_IO_PENDING, bytes_read); - DCHECK_EQ(net_request_.get(), request); - - int result; - if (bytes_read < 0) { - net::Error error = static_cast<net::Error>(bytes_read); - result = NotifyFinishedCaching(error, kServiceWorkerFetchScriptError); - } else { - result = HandleNetData(bytes_read); - } - - // ReadRawDataComplete will be called in OnWriteDataComplete, so return early. - if (result == net::ERR_IO_PENDING) - return; - - ReadRawDataComplete(result); -} - -bool ServiceWorkerWriteToCacheJob::CheckPathRestriction( - net::URLRequest* request) { - std::string service_worker_allowed; - const net::HttpResponseHeaders* headers = request->response_headers(); - bool has_header = headers->EnumerateHeader(nullptr, kServiceWorkerAllowed, - &service_worker_allowed); - - std::string error_message; - if (!ServiceWorkerUtils::IsPathRestrictionSatisfied( - version_->scope(), url_, - has_header ? &service_worker_allowed : nullptr, &error_message)) { - NotifyStartErrorHelper(net::ERR_INSECURE_RESPONSE, error_message); - return false; - } - return true; -} - -int ServiceWorkerWriteToCacheJob::HandleNetData(int bytes_read) { - io_buffer_bytes_ = bytes_read; - net::Error error = cache_writer_->MaybeWriteData( - io_buffer_.get(), bytes_read, - base::BindOnce(&ServiceWorkerWriteToCacheJob::OnWriteDataComplete, - weak_factory_.GetWeakPtr())); - - // In case of ERR_IO_PENDING, this logic is done in OnWriteDataComplete. - if (error != net::ERR_IO_PENDING && bytes_read == 0) { - error = NotifyFinishedCaching(error, std::string()); - } - return error == net::OK ? bytes_read : error; -} - -void ServiceWorkerWriteToCacheJob::NotifyStartErrorHelper( - net::Error net_error, - const std::string& status_message) { - NotifyFinishedCaching(net_error, status_message); - NotifyStartError(net::URLRequestStatus::FromError(net_error)); -} - -net::Error ServiceWorkerWriteToCacheJob::NotifyFinishedCaching( - net::Error net_error, - const std::string& status_message) { - DCHECK_NE(net::ERR_IO_PENDING, net_error); - - if (did_notify_finished_) - return net_error; - - int size = -1; - if (net_error != net::OK) { - // AddMessageToConsole must be called before this job notifies that an error - // occurred because the worker stops soon after receiving the error - // response. - version_->embedded_worker()->AddMessageToConsole( - blink::mojom::ConsoleMessageLevel::kError, - status_message.empty() ? kServiceWorkerFetchScriptError - : status_message); - } else { - size = cache_writer_->bytes_written(); - } - - // If all the calls to MaybeWriteHeaders/MaybeWriteData succeeded, but the - // incumbent entry wasn't actually replaced because the new entry was - // equivalent, the new version didn't actually install because it already - // exists. - if (net_error == net::OK && !cache_writer_->did_replace()) { - version_->SetStartWorkerStatusCode( - blink::ServiceWorkerStatusCode::kErrorExists); - version_->script_cache_map()->NotifyFinishedCaching( - url_, size, kIdenticalScriptError, std::string()); - } else { - version_->script_cache_map()->NotifyFinishedCaching(url_, size, net_error, - status_message); - } - - did_notify_finished_ = true; - return net_error; -} - -bool ServiceWorkerWriteToCacheJob::ShouldByteForByteCheck() const { - return incumbent_resource_id_ != kInvalidServiceWorkerResourceId && - version_->pause_after_download(); -} - -bool ServiceWorkerWriteToCacheJob::IsMainScript() const { - return url_ == version_->script_url() && - resource_type_ == RESOURCE_TYPE_SERVICE_WORKER; -} - -} // namespace content
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job.h b/content/browser/service_worker/service_worker_write_to_cache_job.h deleted file mode 100644 index 35b7f83..0000000 --- a/content/browser/service_worker/service_worker_write_to_cache_job.h +++ /dev/null
@@ -1,157 +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_BROWSER_SERVICE_WORKER_SERVICE_WORKER_WRITE_TO_CACHE_JOB_H_ -#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_WRITE_TO_CACHE_JOB_H_ - -#include <stdint.h> - -#include <string> - -#include "base/gtest_prod_util.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "content/browser/service_worker/service_worker_disk_cache.h" -#include "content/browser/service_worker/service_worker_version.h" -#include "content/common/content_export.h" -#include "content/common/service_worker/service_worker_types.h" -#include "content/public/common/resource_type.h" -#include "net/base/net_errors.h" -#include "net/url_request/url_request.h" -#include "net/url_request/url_request_job.h" -#include "third_party/blink/public/common/service_worker/service_worker_status_code.h" - -namespace content { - -class ServiceWorkerCacheWriter; -class ServiceWorkerContextCore; - -// A URLRequestJob derivative used to cache the main script -// and its imports during the initial install of a new version. -// Another separate URLRequest is started which will perform -// a network fetch. The response produced for that separate -// request is written to the service worker script cache and piped -// to the consumer of the ServiceWorkerWriteToCacheJob for delivery -// to the renderer process housing the worker. -// -// For updates, the main script is not written to disk until a change with the -// incumbent script is detected. The incumbent script is progressively compared -// with the new script as it is read from network. Once a change is detected, -// everything that matched is copied to disk, and from then on the script is -// written as it continues to be read from network. If the scripts are -// identical, the resulting ServiceWorkerScriptCacheMap's main script status is -// set to kIdenticalScriptError. -class CONTENT_EXPORT ServiceWorkerWriteToCacheJob - : public net::URLRequestJob, - public net::URLRequest::Delegate { - public: - ServiceWorkerWriteToCacheJob(net::URLRequest* request, - net::NetworkDelegate* network_delegate, - ResourceType resource_type, - base::WeakPtr<ServiceWorkerContextCore> context, - ServiceWorkerVersion* version, - int extra_load_flags, - int64_t resource_id, - int64_t incumbent_resource_id); - - // The error code used when update fails because the new - // script is byte-by-byte identical to the incumbent script. - const static net::Error kIdenticalScriptError; - - private: - ~ServiceWorkerWriteToCacheJob() override; - - // net::URLRequestJob overrides - void Start() override; - void StartAsync(); - void Kill() override; - net::LoadState GetLoadState() const override; - bool GetCharset(std::string* charset) override; - bool GetMimeType(std::string* mime_type) const override; - void GetResponseInfo(net::HttpResponseInfo* info) override; - void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override; - int ReadRawData(net::IOBuffer* buf, int buf_size) override; - - const net::HttpResponseInfo* http_info() const; - - // Methods to drive the net request forward and - // write data to the disk cache. - void InitNetRequest(int extra_load_flags); - void StartNetRequest(); - int ReadNetData(net::IOBuffer* buf, int buf_size); - - // Callbacks for writing headers and data via |cache_writer_|. Note that since - // the MaybeWriteHeaders and MaybeWriteData methods on |cache_writer_| are - // guaranteed not to do short writes, these functions only receive a - // net::Error indicating success or failure, not a count of bytes written. - void OnWriteHeadersComplete(net::Error error); - void OnWriteDataComplete(net::Error error); - - // net::URLRequest::Delegate overrides that observe the net request. - void OnReceivedRedirect(net::URLRequest* request, - const net::RedirectInfo& redirect_info, - bool* defer_redirect) override; - void OnAuthRequired(net::URLRequest* request, - net::AuthChallengeInfo* auth_info) override; - void OnCertificateRequested( - net::URLRequest* request, - net::SSLCertRequestInfo* cert_request_info) override; - void OnSSLCertificateError(net::URLRequest* request, - const net::SSLInfo& ssl_info, - bool fatal) override; - void OnResponseStarted(net::URLRequest* request, int net_error) override; - void OnReadCompleted(net::URLRequest* request, int bytes_read) override; - - bool CheckPathRestriction(net::URLRequest* request); - - // Writes network data back to the script cache if needed, and notifies the - // script cache of fetch completion at EOF. This function returns - // net::IO_PENDING if the IO is to be completed asynchronously, returns a - // negative number that represents a corresponding net error code (other than - // net::IO_PENDING) if an error occurred, or returns a non-negative number - // that represents the number of network bytes read. If the return value is - // non-negative, all of the data in |io_buffer_| has been written back to the - // script cache if necessary. - int HandleNetData(int bytes_read); - - void NotifyStartErrorHelper(net::Error net_error, - const std::string& status_message); - - // Returns the error code, which is |net_error| or - // a new one if an additional error is found. - net::Error NotifyFinishedCaching(net::Error net_error, - const std::string& status_message); - - // Returns true when the incumbent service worker exists and it's required to - // do the byte-for-byte check. - bool ShouldByteForByteCheck() const; - - // Returns true if this writer is writing the main script for the service - // worker. - bool IsMainScript() const; - - const ResourceType resource_type_; // Differentiate main script and imports - scoped_refptr<net::IOBuffer> io_buffer_; - int io_buffer_bytes_; - base::WeakPtr<ServiceWorkerContextCore> context_; - const GURL url_; - const int64_t resource_id_; - const int64_t incumbent_resource_id_; - std::unique_ptr<net::URLRequest> net_request_; - std::unique_ptr<net::HttpResponseInfo> http_info_; - std::unique_ptr<ServiceWorkerResponseWriter> writer_; - scoped_refptr<ServiceWorkerVersion> version_; - std::unique_ptr<ServiceWorkerCacheWriter> cache_writer_; - bool has_been_killed_ = false; - bool did_notify_started_ = false; - bool did_notify_finished_ = false; - - base::WeakPtrFactory<ServiceWorkerWriteToCacheJob> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(ServiceWorkerWriteToCacheJob); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_WRITE_TO_CACHE_JOB_H_
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc b/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc deleted file mode 100644 index ef4cacf..0000000 --- a/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc +++ /dev/null
@@ -1,727 +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 <stddef.h> -#include <stdint.h> - -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/location.h" -#include "base/memory/ptr_util.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/stl_util.h" -#include "base/threading/thread_task_runner_handle.h" -#include "content/browser/service_worker/embedded_worker_test_helper.h" -#include "content/browser/service_worker/service_worker_context_core.h" -#include "content/browser/service_worker/service_worker_disk_cache.h" -#include "content/browser/service_worker/service_worker_provider_host.h" -#include "content/browser/service_worker/service_worker_registration.h" -#include "content/browser/service_worker/service_worker_request_handler.h" -#include "content/browser/service_worker/service_worker_test_utils.h" -#include "content/common/service_worker/service_worker_utils.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "net/base/io_buffer.h" -#include "net/base/load_flags.h" -#include "net/base/net_errors.h" -#include "net/http/http_response_headers.h" -#include "net/test/url_request/url_request_failed_job.h" -#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_job_factory_impl.h" -#include "net/url_request/url_request_test_job.h" -#include "net/url_request/url_request_test_util.h" -#include "services/network/public/cpp/resource_request_body.h" -#include "services/network/public/mojom/request_context_frame_type.mojom.h" -#include "storage/browser/blob/blob_storage_context.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/service_worker/service_worker_utils.h" -#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" - -// Note for S13nServiceWorker: All tests are skipped as we don't use -// ServiceWorkerWriteToCacheJob when S13nServiceWorker is enabled. - -namespace content { -namespace service_worker_write_to_cache_job_unittest { - -const char kHeaders[] = - "HTTP/1.1 200 OK\n" - "Content-Type: text/javascript\n" - "Expires: Thu, 1 Jan 2100 20:00:00 GMT\n" - "\n"; -const char kScriptCode[] = "// no script code\n"; - -// The blocksize that ServiceWorkerWriteToCacheJob reads/writes at a time. -const int kBlockSize = 16 * 1024; -const int kNumBlocks = 8; -const int kMiddleBlock = 5; - -std::string GenerateLongResponse() { - return std::string(kNumBlocks * kBlockSize, 'a'); -} - -net::URLRequestJob* CreateNormalURLRequestJob( - net::URLRequest* request, - net::NetworkDelegate* network_delegate) { - return new net::URLRequestTestJob(request, network_delegate, - std::string(kHeaders, base::size(kHeaders)), - kScriptCode, true); -} - -net::URLRequestJob* CreateResponseJob(const std::string& response_data, - net::URLRequest* request, - net::NetworkDelegate* network_delegate) { - return new net::URLRequestTestJob(request, network_delegate, - std::string(kHeaders, base::size(kHeaders)), - response_data, true); -} - -net::URLRequestJob* CreateFailedURLRequestJob( - net::URLRequest* request, - net::NetworkDelegate* network_delegate) { - return new net::URLRequestFailedJob(request, network_delegate, - net::URLRequestFailedJob::START, - net::ERR_FAILED); -} - -net::URLRequestJob* CreateInvalidMimeTypeJob( - net::URLRequest* request, - net::NetworkDelegate* network_delegate) { - const char kPlainTextHeaders[] = - "HTTP/1.1 200 OK\n" - "Content-Type: text/plain\n" - "Expires: Thu, 1 Jan 2100 20:00:00 GMT\n" - "\n"; - return new net::URLRequestTestJob( - request, network_delegate, - std::string(kPlainTextHeaders, base::size(kPlainTextHeaders)), - kScriptCode, true); -} - -class SSLCertificateErrorJob : public net::URLRequestTestJob { - public: - SSLCertificateErrorJob(net::URLRequest* request, - net::NetworkDelegate* network_delegate, - const std::string& response_headers, - const std::string& response_data, - bool auto_advance) - : net::URLRequestTestJob(request, - network_delegate, - response_headers, - response_data, - auto_advance), - weak_factory_(this) {} - void Start() override { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&SSLCertificateErrorJob::NotifyError, - weak_factory_.GetWeakPtr())); - } - void NotifyError() { - net::SSLInfo info; - info.cert_status = net::CERT_STATUS_DATE_INVALID; - NotifySSLCertificateError(info, true); - } - void ContinueDespiteLastError() override { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&SSLCertificateErrorJob::StartAsync, - weak_factory_.GetWeakPtr())); - } - - protected: - ~SSLCertificateErrorJob() override {} - base::WeakPtrFactory<SSLCertificateErrorJob> weak_factory_; -}; - -net::URLRequestJob* CreateSSLCertificateErrorJob( - net::URLRequest* request, - net::NetworkDelegate* network_delegate) { - return new SSLCertificateErrorJob(request, network_delegate, - std::string(kHeaders, base::size(kHeaders)), - kScriptCode, true); -} - -class CertStatusErrorJob : public net::URLRequestTestJob { - public: - CertStatusErrorJob(net::URLRequest* request, - net::NetworkDelegate* network_delegate, - const std::string& response_headers, - const std::string& response_data, - bool auto_advance) - : net::URLRequestTestJob(request, - network_delegate, - response_headers, - response_data, - auto_advance) {} - void GetResponseInfo(net::HttpResponseInfo* info) override { - URLRequestTestJob::GetResponseInfo(info); - info->ssl_info.cert_status = net::CERT_STATUS_DATE_INVALID; - } - - protected: - ~CertStatusErrorJob() override {} -}; - -net::URLRequestJob* CreateCertStatusErrorJob( - net::URLRequest* request, - net::NetworkDelegate* network_delegate) { - return new CertStatusErrorJob(request, network_delegate, - std::string(kHeaders, base::size(kHeaders)), - kScriptCode, true); -} - -class MockHttpProtocolHandler - : public net::URLRequestJobFactory::ProtocolHandler { - public: - using JobCallback = - base::OnceCallback<net::URLRequestJob*(net::URLRequest*, - net::NetworkDelegate*)>; - - MockHttpProtocolHandler() {} - ~MockHttpProtocolHandler() override {} - - net::URLRequestJob* MaybeCreateJob( - net::URLRequest* request, - net::NetworkDelegate* network_delegate) const override { - ServiceWorkerRequestHandler* handler = - ServiceWorkerRequestHandler::GetHandler(request); - if (handler) { - return handler->MaybeCreateJob(request, network_delegate, nullptr); - } - return std::move(create_job_callback_).Run(request, network_delegate); - } - void SetCreateJobCallback(JobCallback callback) { - create_job_callback_ = std::move(callback); - } - - private: - mutable JobCallback create_job_callback_; -}; - -class ResponseVerifier : public base::RefCounted<ResponseVerifier> { - public: - ResponseVerifier(std::unique_ptr<ServiceWorkerResponseReader> reader, - const std::string& expected, - base::OnceCallback<void(bool)> callback) - : reader_(reader.release()), - expected_(expected), - callback_(std::move(callback)) {} - - void Start() { - info_buffer_ = new HttpResponseInfoIOBuffer(); - io_buffer_ = base::MakeRefCounted<net::IOBuffer>(kBlockSize); - reader_->ReadInfo( - info_buffer_.get(), - base::BindOnce(&ResponseVerifier::OnReadInfoComplete, this)); - bytes_read_ = 0; - } - - void OnReadInfoComplete(int result) { - if (result < 0) { - std::move(callback_).Run(false); - return; - } - if (info_buffer_->response_data_size != - static_cast<int>(expected_.size())) { - std::move(callback_).Run(false); - return; - } - ReadSomeData(); - } - - void ReadSomeData() { - reader_->ReadData( - io_buffer_.get(), kBlockSize, - base::BindOnce(&ResponseVerifier::OnReadDataComplete, this)); - } - - void OnReadDataComplete(int result) { - if (result < 0) { - std::move(callback_).Run(false); - return; - } - if (result == 0) { - std::move(callback_).Run(true); - return; - } - std::string str(io_buffer_->data(), result); - std::string expect = expected_.substr(bytes_read_, result); - if (str != expect) { - std::move(callback_).Run(false); - return; - } - bytes_read_ += result; - ReadSomeData(); - } - - private: - friend class base::RefCounted<ResponseVerifier>; - ~ResponseVerifier() {} - - std::unique_ptr<ServiceWorkerResponseReader> reader_; - const std::string expected_; - base::OnceCallback<void(bool)> callback_; - scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_; - scoped_refptr<net::IOBuffer> io_buffer_; - size_t bytes_read_; -}; - -class ServiceWorkerWriteToCacheJobTest : public testing::Test { - public: - ServiceWorkerWriteToCacheJobTest() - : ServiceWorkerWriteToCacheJobTest("https://host/scope/", - "https://host/script.js") {} - ServiceWorkerWriteToCacheJobTest(const std::string& scope, - const std::string& script_url) - : scope_(scope), - script_url_(script_url), - browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), - mock_protocol_handler_(nullptr) {} - ~ServiceWorkerWriteToCacheJobTest() override {} - - base::WeakPtr<ServiceWorkerProviderHost> CreateHostForVersion( - int process_id, - const scoped_refptr<ServiceWorkerVersion>& version) { - return CreateProviderHostForServiceWorkerContext( - process_id, true /* is_parent_frame_secure */, version.get(), - context()->AsWeakPtr(), &remote_endpoint_); - } - - void SetUpScriptRequest(int process_id, int provider_id) { - request_.reset(); - url_request_context_.reset(); - url_request_job_factory_.reset(); - mock_protocol_handler_ = nullptr; - // URLRequestJobs may post clean-up tasks on destruction. - base::RunLoop().RunUntilIdle(); - - url_request_context_.reset(new net::URLRequestContext); - mock_protocol_handler_ = new MockHttpProtocolHandler; - url_request_job_factory_.reset(new net::URLRequestJobFactoryImpl); - url_request_job_factory_->SetProtocolHandler( - "https", base::WrapUnique(mock_protocol_handler_)); - url_request_context_->set_job_factory(url_request_job_factory_.get()); - - request_ = url_request_context_->CreateRequest( - script_url_, net::DEFAULT_PRIORITY, &url_request_delegate_, - TRAFFIC_ANNOTATION_FOR_TESTS); - ServiceWorkerRequestHandler::InitializeHandler( - request_.get(), context_wrapper(), &blob_storage_context_, process_id, - provider_id, false, network::mojom::FetchRequestMode::kNoCors, - network::mojom::FetchCredentialsMode::kOmit, - network::mojom::FetchRedirectMode::kFollow, - std::string() /* integrity */, false /* keepalive */, - RESOURCE_TYPE_SERVICE_WORKER, - blink::mojom::RequestContextType::SERVICE_WORKER, - network::mojom::RequestContextFrameType::kNone, - scoped_refptr<network::ResourceRequestBody>()); - } - - int NextVersionId() { return next_version_id_++; } - - void SetUp() override { - helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath())); - - // A new unstored registration/version. - blink::mojom::ServiceWorkerRegistrationOptions options; - options.scope = scope_; - registration_ = - new ServiceWorkerRegistration(options, 1L, context()->AsWeakPtr()); - version_ = new ServiceWorkerVersion( - registration_.get(), script_url_, blink::mojom::ScriptType::kClassic, - NextVersionId(), context()->AsWeakPtr()); - base::WeakPtr<ServiceWorkerProviderHost> host = - CreateHostForVersion(helper_->mock_render_process_id(), version_); - ASSERT_TRUE(host); - SetUpScriptRequest(helper_->mock_render_process_id(), host->provider_id()); - - context()->storage()->LazyInitializeForTest(base::DoNothing()); - base::RunLoop().RunUntilIdle(); - } - - void TearDown() override { - request_.reset(); - url_request_context_.reset(); - url_request_job_factory_.reset(); - mock_protocol_handler_ = nullptr; - version_ = nullptr; - registration_ = nullptr; - helper_.reset(); - // URLRequestJobs may post clean-up tasks on destruction. - base::RunLoop().RunUntilIdle(); - } - - int CreateIncumbent(const std::string& response) { - mock_protocol_handler_->SetCreateJobCallback( - base::BindOnce(&CreateResponseJob, response)); - request_->Start(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(net::URLRequestStatus::SUCCESS, request_->status().status()); - int64_t incumbent_resource_id = - version_->script_cache_map()->LookupResourceId(script_url_); - EXPECT_NE(kInvalidServiceWorkerResourceId, incumbent_resource_id); - - registration_->SetActiveVersion(version_); - - // Teardown the request. - request_.reset(); - url_request_context_.reset(); - url_request_job_factory_.reset(); - mock_protocol_handler_ = nullptr; - base::RunLoop().RunUntilIdle(); - - return incumbent_resource_id; - } - - int64_t GetResourceId(ServiceWorkerVersion* version) { - return version->script_cache_map()->LookupResourceId(script_url_); - } - - // Performs the net request for an update of |registration_|'s incumbent - // to the script |response|. Returns the new version. - scoped_refptr<ServiceWorkerVersion> UpdateScript( - const std::string& response) { - scoped_refptr<ServiceWorkerVersion> new_version = new ServiceWorkerVersion( - registration_.get(), script_url_, blink::mojom::ScriptType::kClassic, - NextVersionId(), context()->AsWeakPtr()); - new_version->SetToPauseAfterDownload(base::DoNothing()); - base::WeakPtr<ServiceWorkerProviderHost> host = - CreateHostForVersion(helper_->mock_render_process_id(), new_version); - EXPECT_TRUE(host); - SetUpScriptRequest(helper_->mock_render_process_id(), host->provider_id()); - mock_protocol_handler_->SetCreateJobCallback( - base::BindOnce(&CreateResponseJob, response)); - request_->Start(); - base::RunLoop().RunUntilIdle(); - return new_version; - } - - void VerifyResource(int64_t id, const std::string& expected) { - ASSERT_NE(kInvalidServiceWorkerResourceId, id); - base::Optional<bool> is_equal; - std::unique_ptr<ServiceWorkerResponseReader> reader = - context()->storage()->CreateResponseReader(id); - scoped_refptr<ResponseVerifier> verifier = new ResponseVerifier( - std::move(reader), expected, CreateReceiverOnCurrentThread(&is_equal)); - verifier->Start(); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(is_equal.value()); - } - - ServiceWorkerContextCore* context() const { return helper_->context(); } - ServiceWorkerContextWrapper* context_wrapper() const { - return helper_->context_wrapper(); - } - - // Disables the cache to simulate cache errors. - void DisableCache() { context()->storage()->disk_cache()->Disable(); } - - protected: - const GURL scope_; - const GURL script_url_; - - TestBrowserThreadBundle browser_thread_bundle_; - std::unique_ptr<EmbeddedWorkerTestHelper> helper_; - scoped_refptr<ServiceWorkerRegistration> registration_; - scoped_refptr<ServiceWorkerVersion> version_; - std::unique_ptr<net::URLRequestContext> url_request_context_; - std::unique_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_; - std::unique_ptr<net::URLRequest> request_; - MockHttpProtocolHandler* mock_protocol_handler_; - - storage::BlobStorageContext blob_storage_context_; - ServiceWorkerRemoteProviderEndpoint remote_endpoint_; - - net::TestDelegate url_request_delegate_; - int next_provider_id_ = 1; - int64_t next_version_id_ = 1L; -}; - -TEST_F(ServiceWorkerWriteToCacheJobTest, Normal) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - mock_protocol_handler_->SetCreateJobCallback( - base::BindOnce(&CreateNormalURLRequestJob)); - request_->Start(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(net::URLRequestStatus::SUCCESS, request_->status().status()); - EXPECT_NE(kInvalidServiceWorkerResourceId, - version_->script_cache_map()->LookupResourceId(script_url_)); -} - -TEST_F(ServiceWorkerWriteToCacheJobTest, InvalidMimeType) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - mock_protocol_handler_->SetCreateJobCallback( - base::BindOnce(&CreateInvalidMimeTypeJob)); - request_->Start(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status()); - EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error()); - EXPECT_EQ(kInvalidServiceWorkerResourceId, - version_->script_cache_map()->LookupResourceId(script_url_)); -} - -TEST_F(ServiceWorkerWriteToCacheJobTest, SSLCertificateError) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - mock_protocol_handler_->SetCreateJobCallback( - base::BindOnce(&CreateSSLCertificateErrorJob)); - request_->Start(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status()); - EXPECT_EQ(net::ERR_CERT_DATE_INVALID, request_->status().error()); - EXPECT_EQ(kInvalidServiceWorkerResourceId, - version_->script_cache_map()->LookupResourceId(script_url_)); -} - -class ServiceWorkerWriteToCacheLocalhostTest - : public ServiceWorkerWriteToCacheJobTest { - public: - ServiceWorkerWriteToCacheLocalhostTest() - : ServiceWorkerWriteToCacheJobTest("https://localhost/scope/", - "https://localhost/script.js") {} - ~ServiceWorkerWriteToCacheLocalhostTest() override {} -}; - -TEST_F(ServiceWorkerWriteToCacheLocalhostTest, - SSLCertificateError_AllowInsecureLocalhost) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kAllowInsecureLocalhost); - - mock_protocol_handler_->SetCreateJobCallback( - base::BindOnce(&CreateSSLCertificateErrorJob)); - request_->Start(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(net::URLRequestStatus::SUCCESS, request_->status().status()); - EXPECT_EQ(net::OK, request_->status().error()); - EXPECT_NE(kInvalidServiceWorkerResourceId, - version_->script_cache_map()->LookupResourceId(script_url_)); -} - -TEST_F(ServiceWorkerWriteToCacheLocalhostTest, SSLCertificateError) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - mock_protocol_handler_->SetCreateJobCallback( - base::BindOnce(&CreateSSLCertificateErrorJob)); - request_->Start(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status()); - EXPECT_EQ(net::ERR_CERT_DATE_INVALID, request_->status().error()); - EXPECT_EQ(kInvalidServiceWorkerResourceId, - version_->script_cache_map()->LookupResourceId(script_url_)); -} - -TEST_F(ServiceWorkerWriteToCacheLocalhostTest, - CertStatusError_AllowInsecureLocalhost) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kAllowInsecureLocalhost); - - mock_protocol_handler_->SetCreateJobCallback( - base::BindOnce(&CreateCertStatusErrorJob)); - request_->Start(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(net::URLRequestStatus::SUCCESS, request_->status().status()); - EXPECT_EQ(net::OK, request_->status().error()); - EXPECT_NE(kInvalidServiceWorkerResourceId, - version_->script_cache_map()->LookupResourceId(script_url_)); -} - -TEST_F(ServiceWorkerWriteToCacheLocalhostTest, CertStatusError) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - mock_protocol_handler_->SetCreateJobCallback( - base::BindOnce(&CreateCertStatusErrorJob)); - request_->Start(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status()); - EXPECT_EQ(net::ERR_CERT_DATE_INVALID, request_->status().error()); - EXPECT_EQ(kInvalidServiceWorkerResourceId, - version_->script_cache_map()->LookupResourceId(script_url_)); -} - -TEST_F(ServiceWorkerWriteToCacheJobTest, CertStatusError) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - mock_protocol_handler_->SetCreateJobCallback( - base::BindOnce(&CreateCertStatusErrorJob)); - request_->Start(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status()); - EXPECT_EQ(net::ERR_CERT_DATE_INVALID, request_->status().error()); - EXPECT_EQ(kInvalidServiceWorkerResourceId, - version_->script_cache_map()->LookupResourceId(script_url_)); -} - -TEST_F(ServiceWorkerWriteToCacheJobTest, Update_SameScript) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - std::string response = GenerateLongResponse(); - CreateIncumbent(response); - scoped_refptr<ServiceWorkerVersion> version = UpdateScript(response); - EXPECT_EQ(kInvalidServiceWorkerResourceId, GetResourceId(version.get())); -} - -TEST_F(ServiceWorkerWriteToCacheJobTest, Update_SameSizeScript) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - std::string response = GenerateLongResponse(); - CreateIncumbent(response); - - // Change the first byte. - response[0] = 'x'; - scoped_refptr<ServiceWorkerVersion> version = UpdateScript(response); - VerifyResource(GetResourceId(version.get()), response); - registration_->SetWaitingVersion(version); - - // Change something within the first block. - response[5555] = 'x'; - version = UpdateScript(response); - VerifyResource(GetResourceId(version.get()), response); - registration_->SetWaitingVersion(version); - - // Change something in a middle block. - response[kMiddleBlock * kBlockSize + 111] = 'x'; - version = UpdateScript(response); - VerifyResource(GetResourceId(version.get()), response); - registration_->SetWaitingVersion(version); - - // Change something within the last block. - response[(kNumBlocks - 1) * kBlockSize] = 'x'; - version = UpdateScript(response); - VerifyResource(GetResourceId(version.get()), response); - registration_->SetWaitingVersion(version); - - // Change the last byte. - response[(kNumBlocks * kBlockSize) - 1] = 'x'; - version = UpdateScript(response); - VerifyResource(GetResourceId(version.get()), response); - registration_->SetWaitingVersion(version); -} - -TEST_F(ServiceWorkerWriteToCacheJobTest, Update_TruncatedScript) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - std::string response = GenerateLongResponse(); - CreateIncumbent(response); - - // Truncate a single byte. - response.resize(response.size() - 1); - scoped_refptr<ServiceWorkerVersion> version = UpdateScript(response); - VerifyResource(GetResourceId(version.get()), response); - registration_->SetWaitingVersion(version); - - // Truncate to a middle block. - response.resize((kMiddleBlock + 1) * kBlockSize + 111); - version = UpdateScript(response); - VerifyResource(GetResourceId(version.get()), response); - registration_->SetWaitingVersion(version); - - // Truncate to a block boundary. - response.resize((kMiddleBlock - 1) * kBlockSize); - version = UpdateScript(response); - VerifyResource(GetResourceId(version.get()), response); - registration_->SetWaitingVersion(version); - - // Truncate to a single byte. - response.resize(1); - version = UpdateScript(response); - VerifyResource(GetResourceId(version.get()), response); - registration_->SetWaitingVersion(version); -} - -TEST_F(ServiceWorkerWriteToCacheJobTest, Update_ElongatedScript) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - std::string original_response = GenerateLongResponse(); - CreateIncumbent(original_response); - - // Extend a single byte. - std::string new_response = original_response + 'a'; - scoped_refptr<ServiceWorkerVersion> version = UpdateScript(new_response); - VerifyResource(GetResourceId(version.get()), new_response); - registration_->SetWaitingVersion(version); - - // Extend multiple blocks. - new_response = original_response + std::string(3 * kBlockSize, 'a'); - version = UpdateScript(new_response); - VerifyResource(GetResourceId(version.get()), new_response); - registration_->SetWaitingVersion(version); - - // Extend multiple blocks and bytes. - new_response = original_response + std::string(7 * kBlockSize + 777, 'a'); - version = UpdateScript(new_response); - VerifyResource(GetResourceId(version.get()), new_response); - registration_->SetWaitingVersion(version); -} - -TEST_F(ServiceWorkerWriteToCacheJobTest, Update_EmptyScript) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - // Create empty incumbent. - CreateIncumbent(std::string()); - - // Update from empty to non-empty. - std::string response = GenerateLongResponse(); - scoped_refptr<ServiceWorkerVersion> version = UpdateScript(response); - VerifyResource(GetResourceId(version.get()), response); - registration_->SetWaitingVersion(version); - - // Update from non-empty to empty. - version = UpdateScript(std::string()); - VerifyResource(GetResourceId(version.get()), std::string()); - registration_->SetWaitingVersion(version); - - // Update from empty to empty. - version = UpdateScript(std::string()); - EXPECT_EQ(kInvalidServiceWorkerResourceId, GetResourceId(version.get())); -} - -TEST_F(ServiceWorkerWriteToCacheJobTest, Error) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - mock_protocol_handler_->SetCreateJobCallback( - base::BindOnce(&CreateFailedURLRequestJob)); - request_->Start(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status()); - EXPECT_EQ(net::ERR_FAILED, request_->status().error()); - EXPECT_EQ(kInvalidServiceWorkerResourceId, - version_->script_cache_map()->LookupResourceId(script_url_)); -} - -TEST_F(ServiceWorkerWriteToCacheJobTest, FailedWriteHeadersToCache) { - if (blink::ServiceWorkerUtils::IsServicificationEnabled()) - return; - - mock_protocol_handler_->SetCreateJobCallback( - base::BindOnce(&CreateNormalURLRequestJob)); - DisableCache(); - request_->Start(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status()); - EXPECT_EQ(net::ERR_FAILED, request_->status().error()); -} - -} // namespace service_worker_write_to_cache_job_unittest -} // namespace content
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc index 58ff795..4308cf6a 100644 --- a/content/browser/tracing/tracing_controller_impl.cc +++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -248,7 +248,7 @@ metadata_dict->SetString("os-version", base::SysInfo::OperatingSystemVersion()); #if defined(OS_WIN) - if (base::win::OSInfo::GetInstance()->architecture() == + if (base::win::OSInfo::GetArchitecture() == base::win::OSInfo::X64_ARCHITECTURE) { if (base::win::OSInfo::GetInstance()->wow64_status() == base::win::OSInfo::WOW64_ENABLED) {
diff --git a/content/browser/web_package/signed_exchange_signature_verifier.cc b/content/browser/web_package/signed_exchange_signature_verifier.cc index 627a9fe1..cf554f5 100644 --- a/content/browser/web_package/signed_exchange_signature_verifier.cc +++ b/content/browser/web_package/signed_exchange_signature_verifier.cc
@@ -60,7 +60,7 @@ base::Optional<crypto::SignatureVerifier::SignatureAlgorithm> GetSignatureAlgorithm(scoped_refptr<net::X509Certificate> cert, SignedExchangeDevToolsProxy* devtools_proxy) { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), "VerifySignature"); + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), "GetSignatureAlgorithm"); base::StringPiece spki; if (!net::asn1::ExtractSPKIFromDERCert( net::x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()), @@ -106,6 +106,7 @@ scoped_refptr<net::X509Certificate> cert, crypto::SignatureVerifier::SignatureAlgorithm algorithm, SignedExchangeDevToolsProxy* devtools_proxy) { + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), "VerifySignature"); crypto::SignatureVerifier verifier; if (!net::x509_util::SignatureVerifierInitWithCertificate( &verifier, algorithm, sig, cert->cert_buffer())) {
diff --git a/content/browser/worker_host/shared_worker_content_settings_proxy_impl.cc b/content/browser/worker_host/shared_worker_content_settings_proxy_impl.cc index 015618e..2eeb30d 100644 --- a/content/browser/worker_host/shared_worker_content_settings_proxy_impl.cc +++ b/content/browser/worker_host/shared_worker_content_settings_proxy_impl.cc
@@ -32,6 +32,15 @@ } } +void SharedWorkerContentSettingsProxyImpl::AllowCacheStorage( + AllowCacheStorageCallback callback) { + if (!origin_.opaque()) { + owner_->AllowCacheStorage(origin_.GetURL(), std::move(callback)); + } else { + std::move(callback).Run(false); + } +} + void SharedWorkerContentSettingsProxyImpl::RequestFileSystemAccessSync( RequestFileSystemAccessSyncCallback callback) { if (!origin_.opaque()) {
diff --git a/content/browser/worker_host/shared_worker_content_settings_proxy_impl.h b/content/browser/worker_host/shared_worker_content_settings_proxy_impl.h index c58bc18..d9e2f72 100644 --- a/content/browser/worker_host/shared_worker_content_settings_proxy_impl.h +++ b/content/browser/worker_host/shared_worker_content_settings_proxy_impl.h
@@ -35,6 +35,7 @@ // blink::mojom::WorkerContentSettingsProxy implementation. void AllowIndexedDB(AllowIndexedDBCallback callback) override; + void AllowCacheStorage(AllowCacheStorageCallback callback) override; void RequestFileSystemAccessSync( RequestFileSystemAccessSyncCallback callback) override;
diff --git a/content/browser/worker_host/shared_worker_host.cc b/content/browser/worker_host/shared_worker_host.cc index 87700df..798e6ba7 100644 --- a/content/browser/worker_host/shared_worker_host.cc +++ b/content/browser/worker_host/shared_worker_host.cc
@@ -70,6 +70,15 @@ url, resource_context, render_frames); } +bool AllowCacheStorageOnIOThread( + const GURL& url, + ResourceContext* resource_context, + std::vector<GlobalFrameRoutingId> render_frames) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + return GetContentClient()->browser()->AllowWorkerCacheStorage( + url, resource_context, render_frames); +} + } // namespace // RAII helper class for talking to SharedWorkerDevToolsManager. @@ -343,6 +352,19 @@ std::move(callback)); } +void SharedWorkerHost::AllowCacheStorage( + const GURL& url, + base::OnceCallback<void(bool)> callback) { + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&AllowCacheStorageOnIOThread, url, + RenderProcessHost::FromID(process_id_) + ->GetBrowserContext() + ->GetResourceContext(), + GetRenderFrameIDsForWorker()), + std::move(callback)); +} + void SharedWorkerHost::TerminateWorker() { switch (phase_) { case Phase::kInitial:
diff --git a/content/browser/worker_host/shared_worker_host.h b/content/browser/worker_host/shared_worker_host.h index ef31b0c..4e72cc3e 100644 --- a/content/browser/worker_host/shared_worker_host.h +++ b/content/browser/worker_host/shared_worker_host.h
@@ -112,6 +112,8 @@ void AllowFileSystem(const GURL& url, base::OnceCallback<void(bool)> callback); void AllowIndexedDB(const GURL& url, base::OnceCallback<void(bool)> callback); + void AllowCacheStorage(const GURL& url, + base::OnceCallback<void(bool)> callback); // Terminates the given worker, i.e. based on a UI action. void TerminateWorker();
diff --git a/content/common/user_agent.cc b/content/common/user_agent.cc index 544ccc3..abff1622 100644 --- a/content/common/user_agent.cc +++ b/content/common/user_agent.cc
@@ -77,7 +77,7 @@ architecture_token = "; WOW64"; } else { base::win::OSInfo::WindowsArchitecture windows_architecture = - os_info->architecture(); + os_info->GetArchitecture(); if (windows_architecture == base::win::OSInfo::X64_ARCHITECTURE) architecture_token = "; Win64; x64"; else if (windows_architecture == base::win::OSInfo::IA64_ARCHITECTURE)
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index f71cc86..48d7499 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -373,6 +373,13 @@ return true; } +bool ContentBrowserClient::AllowWorkerCacheStorage( + const GURL& url, + ResourceContext* context, + const std::vector<GlobalFrameRoutingId>& render_frames) { + return true; +} + ContentBrowserClient::AllowWebBluetoothResult ContentBrowserClient::AllowWebBluetooth( content::BrowserContext* browser_context,
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index bf74558..a657403 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -613,6 +613,14 @@ ResourceContext* context, const std::vector<GlobalFrameRoutingId>& render_frames); + // Allow the embedder to control if access to CacheStorage by a shared worker + // is allowed. + // This is called on the IO thread. + virtual bool AllowWorkerCacheStorage( + const GURL& url, + ResourceContext* context, + const std::vector<GlobalFrameRoutingId>& render_frames); + // Allow the embedder to control whether we can use Web Bluetooth. // TODO(crbug.com/589228): Replace this with a use of the permission system. enum class AllowWebBluetoothResult {
diff --git a/content/public/browser/platform_notification_context.h b/content/public/browser/platform_notification_context.h index 276ca40c..be8cfd6 100644 --- a/content/public/browser/platform_notification_context.h +++ b/content/public/browser/platform_notification_context.h
@@ -6,6 +6,8 @@ #define CONTENT_PUBLIC_BROWSER_PLATFORM_NOTIFICATION_CONTEXT_H_ #include <stdint.h> + +#include <string> #include <vector> #include "base/callback.h" @@ -106,6 +108,9 @@ const GURL& origin, DeleteResultCallback callback) = 0; + // Trigger all pending notifications. + virtual void TriggerNotifications() = 0; + protected: friend class base::DeleteHelper<PlatformNotificationContext>; friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
diff --git a/content/public/browser/platform_notification_service.h b/content/public/browser/platform_notification_service.h index 0199738..b8aaa76 100644 --- a/content/public/browser/platform_notification_service.h +++ b/content/public/browser/platform_notification_service.h
@@ -13,6 +13,7 @@ #include <vector> #include "base/callback_forward.h" +#include "base/time/time.h" #include "content/common/content_export.h" #include "content/public/browser/notification_database_data.h" #include "third_party/blink/public/mojom/permissions/permission_status.mojom.h" @@ -75,6 +76,16 @@ BrowserContext* browser_context, DisplayedNotificationsCallback callback) = 0; + // Schedules a job to run at |timestamp| and call TriggerNotifications + // on all PlatformNotificationContext instances. + virtual void ScheduleTrigger(BrowserContext* browser_context, + base::Time timestamp) = 0; + + // Reads the value of the next notification trigger time for this profile. + // This will return base::Time::Max if there is no trigger set. + virtual base::Time ReadNextTriggerTimestamp( + BrowserContext* browser_context) = 0; + // Reads the value of the next persistent notification ID from the profile and // increments the value, as it is called once per notification write. virtual int64_t ReadNextPersistentNotificationId(
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc index 99e1f619..5a39571 100644 --- a/content/renderer/loader/web_url_loader_impl.cc +++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -1256,7 +1256,7 @@ version = WebURLResponse::kHTTPVersion_1_1; else if (headers->GetHttpVersion() == net::HttpVersion(2, 0)) version = WebURLResponse::kHTTPVersion_2_0; - response->SetHTTPVersion(version); + response->SetHttpVersion(version); response->SetHttpStatusCode(headers->response_code()); response->SetHttpStatusText(WebString::FromLatin1(headers->GetStatusText()));
diff --git a/content/renderer/render_frame_impl_browsertest.cc b/content/renderer/render_frame_impl_browsertest.cc index 4a6e1959..70ad855 100644 --- a/content/renderer/render_frame_impl_browsertest.cc +++ b/content/renderer/render_frame_impl_browsertest.cc
@@ -274,20 +274,6 @@ EXPECT_TRUE(observer.visible()); } -// Ensure that a RenderFrameImpl does not crash if the RenderView receives -// a WasShown message after the frame's widget has been closed. -TEST_F(RenderFrameImplTest, FrameWasShownAfterWidgetClose) { - WidgetMsg_Close close_message(0); - frame_widget()->OnMessageReceived(close_message); - - WidgetMsg_WasShown was_shown_message(0, base::TimeTicks(), - false /* was_evicted */); - // Test passes if this does not crash. - RenderWidget* render_widget = - static_cast<RenderViewImpl*>(view_)->GetWidget(); - render_widget->OnMessageReceived(was_shown_message); -} - // Test that LoFi state only updates for new main frame documents. Subframes // inherit from the main frame and should not change at commit time. TEST_F(RenderFrameImplTest, LoFiNotUpdatedOnSubframeCommits) {
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 7229239..fe8a598 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -451,8 +451,6 @@ is_fullscreen_granted_(false), display_mode_(display_mode), ime_event_guard_(nullptr), - closing_(false), - host_will_close_this_(false), is_frozen_(is_frozen), text_input_type_(ui::TEXT_INPUT_TYPE_NONE), text_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT), @@ -537,6 +535,8 @@ } void RenderWidget::CloseForFrame() { + DCHECK(for_child_local_root_frame_); + closing_for_child_local_root_frame_ = true; OnClose(); } @@ -711,6 +711,13 @@ void RenderWidget::OnClose() { DCHECK(content::RenderThread::Get()); + // TODO(crbug.com/939262): If this fails we're handling a WidgetMsg_Close IPC + // in a RenderWidget that is a child local root. This will leave the + // RenderWidget in a closed state while the blink-side is not closed until the + // frame is detached, leading to crashes later if it tries to use the + // RenderWidget. + if (for_child_local_root_frame_) + CHECK(closing_for_child_local_root_frame_); if (closing_) return; for (auto& observer : render_frames_) @@ -1204,7 +1211,13 @@ void RenderWidget::ScheduleAnimation() { // TODO(crbug.com/939262): This shouldn't be null. That would mean we're // somehow using RenderWidget after it has closed. - CHECK(layer_tree_view_); + if (!layer_tree_view_) { + // Determine if this object is for a child or main frame (it should be one + // of them!) + CHECK(for_child_local_root_frame_); + CHECK(delegate_); + CHECK(!for_child_local_root_frame_ && !delegate_); + } // This call is not needed in single thread mode for tests without a // scheduler, but they need to override the WebWidgetClient and replace this // method in order to schedule a synchronous composite task themselves.
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 96d3384..8d55faf 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -929,10 +929,15 @@ // True if we have requested this widget be closed. No more messages will // be sent, except for a Close. - bool closing_; + bool closing_ = false; + // TODO(crbug.com/939262): This is set when close is initiated from the + // renderer for a child local root, instead from from a WidgetMsg_Close IPC + // from the browser. Child local roots only expect to be closed from the + // renderer. + bool closing_for_child_local_root_frame_ = false; // True if it is known that the host is in the process of being shut down. - bool host_will_close_this_; + bool host_will_close_this_ = false; // A RenderWidget is frozen if it is the RenderWidget attached to the // RenderViewImpl for its main frame, but there is a proxy main frame in
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 28a2ffa..659dd0c 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1671,7 +1671,6 @@ "../browser/service_worker/service_worker_single_script_update_checker_unittest.cc", "../browser/service_worker/service_worker_storage_unittest.cc", "../browser/service_worker/service_worker_version_unittest.cc", - "../browser/service_worker/service_worker_write_to_cache_job_unittest.cc", "../browser/shareable_file_reference_unittest.cc", "../browser/site_instance_impl_unittest.cc", "../browser/speech/tts_controller_unittest.cc",
diff --git a/content/test/data/accessibility/html/caption-expected-auralinux.txt b/content/test/data/accessibility/html/caption-expected-auralinux.txt index 970e6c0..0ac56037 100644 --- a/content/test/data/accessibility/html/caption-expected-auralinux.txt +++ b/content/test/data/accessibility/html/caption-expected-auralinux.txt
@@ -3,17 +3,17 @@ ++++[caption] ++++++[text] name='Browser and Engine' ++++[table row] -++++++[column header] name='Browser' +++++++[column header] name='Browser' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Browser' -++++++[column header] name='Engine' +++++++[column header] name='Engine' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Engine' ++++[table row] -++++++[table cell] name='Chrome' +++++++[table cell] name='Chrome' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='Chrome' -++++++[table cell] name='Blink' +++++++[table cell] name='Blink' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='Blink' ++++[table row] -++++++[table cell] name='Safari' +++++++[table cell] name='Safari' (row=2, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='Safari' -++++++[table cell] name='WebKit' +++++++[table cell] name='WebKit' (row=2, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='WebKit'
diff --git a/content/test/data/accessibility/html/col-expected-auralinux.txt b/content/test/data/accessibility/html/col-expected-auralinux.txt index 293ae464..6863cda8 100644 --- a/content/test/data/accessibility/html/col-expected-auralinux.txt +++ b/content/test/data/accessibility/html/col-expected-auralinux.txt
@@ -1,12 +1,12 @@ [document web] ++[table] cols=2 headers=('Browser', 'Rendering Engine'); rows=2 headers=(NONE); caption=false; spans=(all: 1x1) ++++[table row] -++++++[column header] name='Browser' +++++++[column header] name='Browser' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Browser' -++++++[column header] name='Rendering Engine' +++++++[column header] name='Rendering Engine' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Rendering Engine' ++++[table row] -++++++[table cell] name='Chrome' +++++++[table cell] name='Chrome' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='Chrome' -++++++[table cell] name='Blink' +++++++[table cell] name='Blink' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='Blink'
diff --git a/content/test/data/accessibility/html/colgroup-expected-auralinux.txt b/content/test/data/accessibility/html/colgroup-expected-auralinux.txt index a3b6397..93d4721 100644 --- a/content/test/data/accessibility/html/colgroup-expected-auralinux.txt +++ b/content/test/data/accessibility/html/colgroup-expected-auralinux.txt
@@ -1,12 +1,12 @@ [document web] ++[table] cols=2 headers=('Single', 'Pair'); rows=2 headers=(NONE); caption=false; spans=(all: 1x1) ++++[table row] -++++++[column header] name='Single' +++++++[column header] name='Single' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Single' -++++++[column header] name='Pair' +++++++[column header] name='Pair' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Pair' ++++[table row] -++++++[table cell] name='A' +++++++[table cell] name='A' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='A' -++++++[table cell] name='AA' +++++++[table cell] name='AA' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='AA'
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-expected-auralinux.txt b/content/test/data/accessibility/html/contenteditable-descendants-expected-auralinux.txt index a5a5d7b..fb2efbe 100644 --- a/content/test/data/accessibility/html/contenteditable-descendants-expected-auralinux.txt +++ b/content/test/data/accessibility/html/contenteditable-descendants-expected-auralinux.txt
@@ -11,7 +11,7 @@ ++++++[text] name='.' editable ++++[table] editable cols=1 headers=(NONE); rows=1 headers=(NONE); caption=false; spans=(all: 1x1) ++++++[table row] editable -++++++++[table cell] name='Always expose editable tables as tables.' editable +++++++++[table cell] name='Always expose editable tables as tables.' editable (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++++[text] name='Always expose editable tables as tables.' editable ++++[list] editable ++++++[list item] editable
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-auralinux.txt b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-auralinux.txt index 125348a..2fa7f7a 100644 --- a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-auralinux.txt +++ b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-auralinux.txt
@@ -11,7 +11,7 @@ ++++++[text] name='.' editable ++++[table] editable cols=1 headers=(NONE); rows=1 headers=(NONE); caption=false; spans=(all: 1x1) ++++++[table row] editable -++++++++[table cell] name='Always expose editable tables as tables.' editable +++++++++[table cell] name='Always expose editable tables as tables.' editable (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++++[text] name='Always expose editable tables as tables.' editable ++++[list] editable ++++++[list item] editable
diff --git a/content/test/data/accessibility/html/table-focusable-sections-expected-auralinux.txt b/content/test/data/accessibility/html/table-focusable-sections-expected-auralinux.txt index 97848ca..f776f1df 100644 --- a/content/test/data/accessibility/html/table-focusable-sections-expected-auralinux.txt +++ b/content/test/data/accessibility/html/table-focusable-sections-expected-auralinux.txt
@@ -2,24 +2,24 @@ ++[table] cols=2 headers=('Sum', 'Subtraction'); rows=4 headers=(NONE); caption=false; spans=(all: 1x1) ++++[panel] ++++++[table row] -++++++++[column header] name='Sum' +++++++++[column header] name='Sum' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++++[text] name='Sum' -++++++++[column header] name='Subtraction' +++++++++[column header] name='Subtraction' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++++[text] name='Subtraction' ++++[panel] ++++++[table row] -++++++++[table cell] name='10' +++++++++[table cell] name='10' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++++[text] name='10' -++++++++[table cell] name='7' +++++++++[table cell] name='7' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++++[text] name='7' ++++++[table row] -++++++++[table cell] name='2' +++++++++[table cell] name='2' (row=2, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++++[text] name='2' -++++++++[table cell] name='4' +++++++++[table cell] name='4' (row=2, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++++[text] name='4' ++++[panel] ++++++[table row] -++++++++[table cell] name='12' +++++++++[table cell] name='12' (row=3, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++++[text] name='12' -++++++++[table cell] name='3' +++++++++[table cell] name='3' (row=3, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++++[text] name='3'
diff --git a/content/test/data/accessibility/html/table-simple-expected-auralinux.txt b/content/test/data/accessibility/html/table-simple-expected-auralinux.txt index 0687a97..6f2a7de 100644 --- a/content/test/data/accessibility/html/table-simple-expected-auralinux.txt +++ b/content/test/data/accessibility/html/table-simple-expected-auralinux.txt
@@ -1,17 +1,17 @@ [document web] name='Table example' ++[table] cols=2 headers=('Pair', 'Single'); rows=3 headers=(NONE); caption=false; spans=(all: 1x1) ++++[table row] -++++++[column header] name='Pair' +++++++[column header] name='Pair' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Pair' -++++++[column header] name='Single' +++++++[column header] name='Single' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Single' ++++[table row] -++++++[table cell] name='AB' +++++++[table cell] name='AB' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='AB' -++++++[table cell] name='B' +++++++[table cell] name='B' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='B' ++++[table row] -++++++[table cell] name='CD' +++++++[table cell] name='CD' (row=2, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='CD' -++++++[table cell] name='D' +++++++[table cell] name='D' (row=2, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='D'
diff --git a/content/test/data/accessibility/html/table-spans-expected-auralinux.txt b/content/test/data/accessibility/html/table-spans-expected-auralinux.txt index f0fa7c7..3380342 100644 --- a/content/test/data/accessibility/html/table-spans-expected-auralinux.txt +++ b/content/test/data/accessibility/html/table-spans-expected-auralinux.txt
@@ -1,21 +1,21 @@ [document web] name='Table example with rowspan and colspan' ++[table] cols=2 headers=(NONE); rows=2 headers=(NONE); caption=false; spans=(cell at 0,0: 2x1, cell at 1,0: 2x1) ++++[table row] -++++++[table cell] name='AD' +++++++[table cell] name='AD' (row=0, col=0, row_span=2, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='AD' -++++++[table cell] name='BC' +++++++[table cell] name='BC' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='BC' ++++[table row] -++++++[table cell] name='EF' +++++++[table cell] name='EF' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='EF' ++[table] cols=3 headers=(NONE); rows=2 headers=(NONE); caption=false; spans=(cell at 0,0: 2x1, cell at 0,1: 1x2, cell at 0,2: 1x2, cell at 1,0: 2x1) ++++[table row] -++++++[table cell] name='AD' +++++++[table cell] name='AD' (row=0, col=0, row_span=2, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='AD' -++++++[table cell] name='BC' +++++++[table cell] name='BC' (row=0, col=1, row_span=1, col_span=2 n_row_headers=0, n_col_headers=0) ++++++++[text] name='BC' ++++[table row] -++++++[table cell] name='EF' +++++++[table cell] name='EF' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='EF' -++++++[table cell] name='GH' +++++++[table cell] name='GH' (row=1, col=2, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='GH'
diff --git a/content/test/data/accessibility/html/table-th-colheader-expected-auralinux.txt b/content/test/data/accessibility/html/table-th-colheader-expected-auralinux.txt index 10721b8..15a3f20 100644 --- a/content/test/data/accessibility/html/table-th-colheader-expected-auralinux.txt +++ b/content/test/data/accessibility/html/table-th-colheader-expected-auralinux.txt
@@ -1,12 +1,12 @@ [document web] ++[table] cols=2 headers=('Firstname', 'Lastname'); rows=2 headers=(NONE); caption=false; spans=(all: 1x1) ++++[table row] -++++++[column header] name='Firstname' table-cell-index:0 +++++++[column header] name='Firstname' table-cell-index:0 (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Firstname' -++++++[column header] name='Lastname' table-cell-index:1 +++++++[column header] name='Lastname' table-cell-index:1 (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Lastname' ++++[table row] -++++++[table cell] name='Jill' table-cell-index:2 +++++++[table cell] name='Jill' table-cell-index:2 (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='Jill' -++++++[table cell] name='Smith' table-cell-index:3 +++++++[table cell] name='Smith' table-cell-index:3 (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='Smith'
diff --git a/content/test/data/accessibility/html/table-th-rowheader-expected-auralinux.txt b/content/test/data/accessibility/html/table-th-rowheader-expected-auralinux.txt index db40158..ed81a2c 100644 --- a/content/test/data/accessibility/html/table-th-rowheader-expected-auralinux.txt +++ b/content/test/data/accessibility/html/table-th-rowheader-expected-auralinux.txt
@@ -1,12 +1,12 @@ [document web] name='Table example - th rowheader' ++[table] cols=2 headers=(NONE); rows=2 headers=('Firstname', 'Lastname'); caption=false; spans=(all: 1x1) ++++[table row] -++++++[row header] name='Firstname' +++++++[row header] name='Firstname' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Firstname' -++++++[table cell] name='Jill' +++++++[table cell] name='Jill' (row=0, col=1, row_span=1, col_span=1 n_row_headers=1, n_col_headers=0) ++++++++[text] name='Jill' ++++[table row] -++++++[row header] name='Lastname' +++++++[row header] name='Lastname' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Lastname' -++++++[table cell] name='Smith' +++++++[table cell] name='Smith' (row=1, col=1, row_span=1, col_span=1 n_row_headers=1, n_col_headers=0) ++++++++[text] name='Smith'
diff --git a/content/test/data/accessibility/html/table-thead-tbody-tfoot-expected-auralinux.txt b/content/test/data/accessibility/html/table-thead-tbody-tfoot-expected-auralinux.txt index 285701d..f71c4455 100644 --- a/content/test/data/accessibility/html/table-thead-tbody-tfoot-expected-auralinux.txt +++ b/content/test/data/accessibility/html/table-thead-tbody-tfoot-expected-auralinux.txt
@@ -1,22 +1,22 @@ [document web] name='Table example - thead, tbody, tfoot' ++[table] cols=2 headers=('Sum', 'Subtraction'); rows=4 headers=(NONE); caption=false; spans=(all: 1x1) ++++[table row] -++++++[column header] name='Sum' +++++++[column header] name='Sum' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Sum' -++++++[column header] name='Subtraction' +++++++[column header] name='Subtraction' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0) ++++++++[text] name='Subtraction' ++++[table row] -++++++[table cell] name='10' +++++++[table cell] name='10' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='10' -++++++[table cell] name='7' +++++++[table cell] name='7' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='7' ++++[table row] -++++++[table cell] name='2' +++++++[table cell] name='2' (row=2, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='2' -++++++[table cell] name='4' +++++++[table cell] name='4' (row=2, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='4' ++++[table row] -++++++[table cell] name='12' +++++++[table cell] name='12' (row=3, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='12' -++++++[table cell] name='3' +++++++[table cell] name='3' (row=3, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1) ++++++++[text] name='3'
diff --git a/content/test/data/browsing_data/site_data.html b/content/test/data/browsing_data/site_data.html index 298899a1..5e798c828 100644 --- a/content/test/data/browsing_data/site_data.html +++ b/content/test/data/browsing_data/site_data.html
@@ -95,12 +95,13 @@ function hasWebSql() { var db = openDatabase('testdb', '1.0', 'a test db', 1024); + var num_results; db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS foo (text)'); tx.executeSql('SELECT * FROM foo', [], function (tx, results) { - domAutomationController.send(results.rows.length > 0); + num_results = results.rows.length; }); - }); + }, null, function() { domAutomationController.send(num_results > 0); }); } function setIndexedDb() {
diff --git a/content/test/mock_platform_notification_service.cc b/content/test/mock_platform_notification_service.cc index 7d16ee6..a313cb37 100644 --- a/content/test/mock_platform_notification_service.cc +++ b/content/test/mock_platform_notification_service.cc
@@ -101,6 +101,15 @@ true /* supports_synchronization */)); } +void MockPlatformNotificationService::ScheduleTrigger( + BrowserContext* browser_context, + base::Time timestamp) {} + +base::Time MockPlatformNotificationService::ReadNextTriggerTimestamp( + BrowserContext* browser_context) { + return base::Time::Max(); +} + int64_t MockPlatformNotificationService::ReadNextPersistentNotificationId( BrowserContext* browser_context) { return ++next_persistent_notification_id_;
diff --git a/content/test/mock_platform_notification_service.h b/content/test/mock_platform_notification_service.h index 89aad27b..9488023 100644 --- a/content/test/mock_platform_notification_service.h +++ b/content/test/mock_platform_notification_service.h
@@ -64,6 +64,10 @@ void GetDisplayedNotifications( BrowserContext* browser_context, DisplayedNotificationsCallback callback) override; + + void ScheduleTrigger(BrowserContext* browser_context, + base::Time timestamp) override; + base::Time ReadNextTriggerTimestamp(BrowserContext* browser_context) override; int64_t ReadNextPersistentNotificationId( BrowserContext* browser_context) override; void RecordNotificationUkmEvent(
diff --git a/device/usb/usb_service_linux.cc b/device/usb/usb_service_linux.cc index e6defe9..28a78181 100644 --- a/device/usb/usb_service_linux.cc +++ b/device/usb/usb_service_linux.cc
@@ -99,7 +99,6 @@ DCHECK(sequence_checker_.CalledOnValidSequence()); } -// static void UsbServiceLinux::BlockingTaskHelper::Start() { DCHECK(sequence_checker_.CalledOnValidSequence()); base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
diff --git a/device/vr/vr_display_impl.cc b/device/vr/vr_display_impl.cc index 2deff0c..20a5716 100644 --- a/device/vr/vr_display_impl.cc +++ b/device/vr/vr_display_impl.cc
@@ -9,10 +9,6 @@ #include "base/bind.h" #include "device/vr/vr_device_base.h" -namespace { -constexpr int kMaxImageHeightOrWidth = 8000; -} // namespace - namespace device { VRDisplayImpl::VRDisplayImpl( @@ -20,7 +16,6 @@ mojom::XRFrameDataProviderRequest magic_window_request, mojom::XRSessionControllerRequest session_request) : magic_window_binding_(this, std::move(magic_window_request)), - environment_binding_(this), session_controller_binding_(this, std::move(session_request)), device_(device) { // Unretained is safe because the binding will close when we are destroyed, @@ -45,42 +40,9 @@ void VRDisplayImpl::GetEnvironmentIntegrationProvider( mojom::XREnvironmentIntegrationProviderAssociatedRequest environment_request) { - if (!device_->GetVRDisplayInfo() - ->capabilities->canProvideEnvironmentIntegration) { - // Environment integration is not supported. This call should not - // be made on this device. - mojo::ReportBadMessage("Environment integration is not supported."); - return; - } - - environment_binding_.Bind(std::move(environment_request)); -} - -void VRDisplayImpl::UpdateSessionGeometry(const gfx::Size& frame_size, - display::Display::Rotation rotation) { - // Check for a valid frame size. - - // TODO(https://crbug.com/841062, https://crbug.com/836496): Reconsider how we - // check the sizes. - if (frame_size.width() <= 0 || frame_size.height() <= 0 || - frame_size.width() > kMaxImageHeightOrWidth || - frame_size.height() > kMaxImageHeightOrWidth) { - DLOG(ERROR) << "Invalid frame size passed to UpdateSessionGeometry."; - return; - } - - session_frame_size_ = frame_size; - session_rotation_ = rotation; -} - -void VRDisplayImpl::RequestHitTest( - mojom::XRRayPtr ray, - mojom::XREnvironmentIntegrationProvider::RequestHitTestCallback callback) { - if (restrict_frame_data_) { - std::move(callback).Run(base::nullopt); - return; - } - device_->RequestHitTest(std::move(ray), std::move(callback)); + // Environment integration is not supported. This call should not + // be made on this device. + mojo::ReportBadMessage("Environment integration is not supported."); } // XRSessionController
diff --git a/device/vr/vr_display_impl.h b/device/vr/vr_display_impl.h index 17ec8dd..921de3d 100644 --- a/device/vr/vr_display_impl.h +++ b/device/vr/vr_display_impl.h
@@ -25,10 +25,8 @@ // or WebXR site session. // VRDisplayImpl objects are owned by their respective XRRuntime instances. // TODO(http://crbug.com/842025): Rename this. -class DEVICE_VR_EXPORT VRDisplayImpl - : public mojom::XRFrameDataProvider, - public mojom::XREnvironmentIntegrationProvider, - public mojom::XRSessionController { +class DEVICE_VR_EXPORT VRDisplayImpl : public mojom::XRFrameDataProvider, + public mojom::XRSessionController { public: VRDisplayImpl(VRDeviceBase* device, mojom::XRFrameDataProviderRequest, @@ -47,10 +45,6 @@ protected: // mojom::XRFrameDataProvider void GetFrameData(GetFrameDataCallback callback) override; - void UpdateSessionGeometry(const gfx::Size& frame_size, - display::Display::Rotation rotation) override; - void RequestHitTest(mojom::XRRayPtr ray, - RequestHitTestCallback callback) override; // mojom::XRSessionController void SetFrameDataRestricted(bool paused) override; @@ -58,8 +52,6 @@ void OnMojoConnectionError(); mojo::Binding<mojom::XRFrameDataProvider> magic_window_binding_; - mojo::AssociatedBinding<mojom::XREnvironmentIntegrationProvider> - environment_binding_; mojo::Binding<mojom::XRSessionController> session_controller_binding_; device::VRDeviceBase* device_; bool restrict_frame_data_ = true;
diff --git a/extensions/browser/api/socket/socket.cc b/extensions/browser/api/socket/socket.cc index e8d21a9..4c7b777c 100644 --- a/extensions/browser/api/socket/socket.cc +++ b/extensions/browser/api/socket/socket.cc
@@ -39,7 +39,7 @@ void Socket::Write(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, - const CompletionCallback& callback) { + const net::CompletionCallback& callback) { DCHECK(!callback.is_null()); write_queue_.push(WriteRequest(io_buffer, byte_count, callback)); WriteData(); @@ -136,7 +136,7 @@ Socket::WriteRequest::WriteRequest(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, - const CompletionCallback& callback) + const net::CompletionCallback& callback) : io_buffer(io_buffer), byte_count(byte_count), callback(callback),
diff --git a/extensions/browser/api/socket/socket.h b/extensions/browser/api/socket/socket.h index a55eede..3839099 100644 --- a/extensions/browser/api/socket/socket.h +++ b/extensions/browser/api/socket/socket.h
@@ -18,6 +18,7 @@ #include "content/public/browser/browser_thread.h" #include "extensions/browser/api/api_resource.h" #include "extensions/browser/api/api_resource_manager.h" +#include "net/base/completion_callback.h" #include "net/base/completion_once_callback.h" #include "net/base/io_buffer.h" #include "net/base/ip_endpoint.h" @@ -38,17 +39,16 @@ namespace extensions { -using CompletionCallback = base::Callback<void(int)>; using SetNoDelayCallback = base::OnceCallback<void(bool)>; using SetKeepAliveCallback = base::OnceCallback<void(bool)>; using ReadCompletionCallback = base::OnceCallback< void(int, scoped_refptr<net::IOBuffer> io_buffer, bool socket_destroying)>; using RecvFromCompletionCallback = - base::Callback<void(int, - scoped_refptr<net::IOBuffer> io_buffer, - bool socket_destroying, - const std::string&, - uint16_t)>; + base::OnceCallback<void(int, + scoped_refptr<net::IOBuffer> io_buffer, + bool socket_destroying, + const std::string&, + uint16_t)>; using ListenCallback = base::OnceCallback<void(int, const std::string& error_msg)>; @@ -96,7 +96,7 @@ virtual void Disconnect(bool socket_destroying) = 0; virtual void Bind(const std::string& address, uint16_t port, - const CompletionCallback& callback) = 0; + net::CompletionOnceCallback callback) = 0; // The |callback| will be called with the number of bytes read into the // buffer, or a negative number if an error occurred. @@ -106,14 +106,13 @@ // error occurred. void Write(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, - const CompletionCallback& callback); + const net::CompletionCallback& callback); - virtual void RecvFrom(int count, - const RecvFromCompletionCallback& callback) = 0; + virtual void RecvFrom(int count, RecvFromCompletionCallback callback) = 0; virtual void SendTo(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, const net::IPEndPoint& address, - const CompletionCallback& callback) = 0; + net::CompletionOnceCallback callback) = 0; virtual void SetKeepAlive(bool enable, int delay, @@ -159,12 +158,12 @@ struct WriteRequest { WriteRequest(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, - const CompletionCallback& callback); + const net::CompletionCallback& callback); WriteRequest(const WriteRequest& other); ~WriteRequest(); scoped_refptr<net::IOBuffer> io_buffer; int byte_count; - CompletionCallback callback; + net::CompletionCallback callback; int bytes_written; };
diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc index df937d06..a1a13a4 100644 --- a/extensions/browser/api/socket/socket_api.cc +++ b/extensions/browser/api/socket/socket_api.cc
@@ -358,7 +358,7 @@ } socket->Connect(addresses_, - base::BindRepeating(&SocketConnectFunction::OnConnect, this)); + base::BindOnce(&SocketConnectFunction::OnConnect, this)); } void SocketConnectFunction::OnConnect(int result) { @@ -633,9 +633,8 @@ return; } - socket->RecvFrom( - params_->buffer_size.get() ? *params_->buffer_size : 4096, - base::BindRepeating(&SocketRecvFromFunction::OnCompleted, this)); + socket->RecvFrom(params_->buffer_size.get() ? *params_->buffer_size : 4096, + base::BindOnce(&SocketRecvFromFunction::OnCompleted, this)); } void SocketRecvFromFunction::OnCompleted(int bytes_read, @@ -735,7 +734,7 @@ } socket->SendTo(io_buffer_, io_buffer_size_, addresses_.front(), - base::BindRepeating(&SocketSendToFunction::OnCompleted, this)); + base::BindOnce(&SocketSendToFunction::OnCompleted, this)); } void SocketSendToFunction::OnCompleted(int bytes_written) { @@ -923,7 +922,7 @@ static_cast<UDPSocket*>(socket)->JoinGroup( params_->address, - base::BindRepeating(&SocketJoinGroupFunction::OnCompleted, this)); + base::BindOnce(&SocketJoinGroupFunction::OnCompleted, this)); } void SocketJoinGroupFunction::OnCompleted(int result) { @@ -976,7 +975,7 @@ static_cast<UDPSocket*>(socket)->LeaveGroup( params_->address, - base::BindRepeating(&SocketLeaveGroupFunction::OnCompleted, this)); + base::BindOnce(&SocketLeaveGroupFunction::OnCompleted, this)); } void SocketLeaveGroupFunction::OnCompleted(int result) {
diff --git a/extensions/browser/api/socket/tcp_socket.cc b/extensions/browser/api/socket/tcp_socket.cc index bb4854c..645725d 100644 --- a/extensions/browser/api/socket/tcp_socket.cc +++ b/extensions/browser/api/socket/tcp_socket.cc
@@ -166,8 +166,8 @@ void TCPSocket::Bind(const std::string& address, uint16_t port, - const net::CompletionCallback& callback) { - callback.Run(net::ERR_FAILED); + net::CompletionOnceCallback callback) { + std::move(callback).Run(net::ERR_FAILED); } void TCPSocket::Read(int count, ReadCompletionCallback callback) { @@ -196,17 +196,16 @@ base::Unretained(this))); } -void TCPSocket::RecvFrom(int count, - const RecvFromCompletionCallback& callback) { - callback.Run(net::ERR_FAILED, nullptr, false /* socket_destroying */, nullptr, - 0); +void TCPSocket::RecvFrom(int count, RecvFromCompletionCallback callback) { + std::move(callback).Run(net::ERR_FAILED, nullptr, + false /* socket_destroying */, nullptr, 0); } void TCPSocket::SendTo(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, const net::IPEndPoint& address, - const CompletionCallback& callback) { - callback.Run(net::ERR_FAILED); + net::CompletionOnceCallback callback) { + std::move(callback).Run(net::ERR_FAILED); } void TCPSocket::SetKeepAlive(bool enable,
diff --git a/extensions/browser/api/socket/tcp_socket.h b/extensions/browser/api/socket/tcp_socket.h index ece08e8e..57f62c77 100644 --- a/extensions/browser/api/socket/tcp_socket.h +++ b/extensions/browser/api/socket/tcp_socket.h
@@ -58,13 +58,13 @@ void Disconnect(bool socket_destroying) override; void Bind(const std::string& address, uint16_t port, - const CompletionCallback& callback) override; + net::CompletionOnceCallback callback) override; void Read(int count, ReadCompletionCallback callback) override; - void RecvFrom(int count, const RecvFromCompletionCallback& callback) override; + void RecvFrom(int count, RecvFromCompletionCallback callback) override; void SendTo(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, const net::IPEndPoint& address, - const CompletionCallback& callback) override; + net::CompletionOnceCallback callback) override; void SetKeepAlive(bool enable, int delay, SetKeepAliveCallback callback) override;
diff --git a/extensions/browser/api/socket/udp_socket.cc b/extensions/browser/api/socket/udp_socket.cc index 55aab1db..4e362575 100644 --- a/extensions/browser/api/socket/udp_socket.cc +++ b/extensions/browser/api/socket/udp_socket.cc
@@ -64,20 +64,20 @@ void UDPSocket::Bind(const std::string& address, uint16_t port, - const net::CompletionCallback& callback) { + net::CompletionOnceCallback callback) { if (IsConnectedOrBound()) { - callback.Run(net::ERR_CONNECTION_FAILED); + std::move(callback).Run(net::ERR_CONNECTION_FAILED); return; } net::IPEndPoint ip_end_point; if (!StringAndPortToIPEndPoint(address, port, &ip_end_point)) { - callback.Run(net::ERR_INVALID_ARGUMENT); + std::move(callback).Run(net::ERR_INVALID_ARGUMENT); return; } socket_->Bind(ip_end_point, std::move(socket_options_), base::BindOnce(&UDPSocket::OnBindCompleted, - base::Unretained(this), callback)); + base::Unretained(this), std::move(callback))); } void UDPSocket::Disconnect(bool socket_destroying) { @@ -133,45 +133,44 @@ socket_->Send(data, net::MutableNetworkTrafficAnnotationTag( Socket::GetNetworkTrafficAnnotationTag()), - base::BindOnce(&UDPSocket::OnWriteOrSendToCompleted, + base::BindOnce(&UDPSocket::OnWriteCompleted, base::Unretained(this), callback, data.size())); return net::ERR_IO_PENDING; } -void UDPSocket::RecvFrom(int count, - const RecvFromCompletionCallback& callback) { +void UDPSocket::RecvFrom(int count, RecvFromCompletionCallback callback) { DCHECK(!callback.is_null()); if (!recv_from_callback_.is_null()) { - callback.Run(net::ERR_IO_PENDING, nullptr, false /* socket_destroying */, - std::string(), 0); + std::move(callback).Run(net::ERR_IO_PENDING, nullptr, + false /* socket_destroying */, std::string(), 0); return; } if (count < 0) { - callback.Run(net::ERR_INVALID_ARGUMENT, nullptr, - false /* socket_destroying */, std::string(), 0); + std::move(callback).Run(net::ERR_INVALID_ARGUMENT, nullptr, + false /* socket_destroying */, std::string(), 0); return; } if (!is_bound_) { - callback.Run(net::ERR_SOCKET_NOT_CONNECTED, nullptr, - false /* socket_destroying */, std::string(), 0); + std::move(callback).Run(net::ERR_SOCKET_NOT_CONNECTED, nullptr, + false /* socket_destroying */, std::string(), 0); return; } - recv_from_callback_ = callback; + recv_from_callback_ = std::move(callback); socket_->ReceiveMoreWithBufferSize(1, count); } void UDPSocket::SendTo(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, const net::IPEndPoint& address, - const net::CompletionCallback& callback) { + net::CompletionOnceCallback callback) { DCHECK(!callback.is_null()); if (!is_bound_) { - callback.Run(net::ERR_SOCKET_NOT_CONNECTED); + std::move(callback).Run(net::ERR_SOCKET_NOT_CONNECTED); return; } @@ -182,8 +181,8 @@ address, data, net::MutableNetworkTrafficAnnotationTag( Socket::GetNetworkTrafficAnnotationTag()), - base::BindOnce(&UDPSocket::OnWriteOrSendToCompleted, - base::Unretained(this), callback, data.size())); + base::BindOnce(&UDPSocket::OnSendToCompleted, base::Unretained(this), + std::move(callback), data.size())); } bool UDPSocket::IsConnected() { @@ -263,22 +262,31 @@ } void UDPSocket::OnBindCompleted( - const net::CompletionCallback& callback, + net::CompletionOnceCallback callback, int result, const base::Optional<net::IPEndPoint>& local_addr) { if (result != net::OK) { - callback.Run(result); + std::move(callback).Run(result); return; } local_addr_ = local_addr; is_bound_ = true; - callback.Run(result); + std::move(callback).Run(result); } -void UDPSocket::OnWriteOrSendToCompleted( - const net::CompletionCallback& callback, - size_t byte_count, - int result) { +void UDPSocket::OnSendToCompleted(net::CompletionOnceCallback callback, + size_t byte_count, + int result) { + if (result == net::OK) { + std::move(callback).Run(byte_count); + return; + } + std::move(callback).Run(result); +} + +void UDPSocket::OnWriteCompleted(const net::CompletionCallback& callback, + size_t byte_count, + int result) { if (result == net::OK) { callback.Run(byte_count); return; @@ -286,51 +294,51 @@ callback.Run(result); } -void UDPSocket::OnJoinGroupCompleted(const net::CompletionCallback& callback, +void UDPSocket::OnJoinGroupCompleted(net::CompletionOnceCallback callback, const std::string& normalized_address, int result) { if (result == net::OK) multicast_groups_.push_back(normalized_address); - callback.Run(result); + std::move(callback).Run(result); } -void UDPSocket::OnLeaveGroupCompleted( - const net::CompletionCallback& user_callback, - const std::string& normalized_address, - int result) { +void UDPSocket::OnLeaveGroupCompleted(net::CompletionOnceCallback callback, + const std::string& normalized_address, + int result) { if (result == net::OK) { auto find_result = std::find(multicast_groups_.begin(), multicast_groups_.end(), normalized_address); multicast_groups_.erase(find_result); } - user_callback.Run(result); + std::move(callback).Run(result); } void UDPSocket::JoinGroup(const std::string& address, - const net::CompletionCallback& callback) { + net::CompletionOnceCallback callback) { net::IPAddress ip; if (!ip.AssignFromIPLiteral(address)) { - callback.Run(net::ERR_ADDRESS_INVALID); + std::move(callback).Run(net::ERR_ADDRESS_INVALID); return; } std::string normalized_address = ip.ToString(); if (base::ContainsValue(multicast_groups_, normalized_address)) { - callback.Run(net::ERR_ADDRESS_INVALID); + std::move(callback).Run(net::ERR_ADDRESS_INVALID); return; } socket_->JoinGroup( - ip, base::BindOnce(&UDPSocket::OnJoinGroupCompleted, - base::Unretained(this), callback, normalized_address)); + ip, + base::BindOnce(&UDPSocket::OnJoinGroupCompleted, base::Unretained(this), + std::move(callback), normalized_address)); } void UDPSocket::LeaveGroup(const std::string& address, - const net::CompletionCallback& callback) { + net::CompletionOnceCallback callback) { net::IPAddress ip; if (!ip.AssignFromIPLiteral(address)) { - callback.Run(net::ERR_ADDRESS_INVALID); + std::move(callback).Run(net::ERR_ADDRESS_INVALID); return; } @@ -338,13 +346,14 @@ auto find_result = std::find(multicast_groups_.begin(), multicast_groups_.end(), normalized_address); if (find_result == multicast_groups_.end()) { - callback.Run(net::ERR_ADDRESS_INVALID); + std::move(callback).Run(net::ERR_ADDRESS_INVALID); return; } socket_->LeaveGroup( - ip, base::BindOnce(&UDPSocket::OnLeaveGroupCompleted, - base::Unretained(this), callback, normalized_address)); + ip, + base::BindOnce(&UDPSocket::OnLeaveGroupCompleted, base::Unretained(this), + std::move(callback), normalized_address)); } int UDPSocket::SetMulticastTimeToLive(int ttl) { @@ -364,12 +373,12 @@ } void UDPSocket::SetBroadcast(bool enabled, - const net::CompletionCallback& callback) { + net::CompletionOnceCallback callback) { if (!is_bound_) { - callback.Run(net::ERR_SOCKET_NOT_CONNECTED); + std::move(callback).Run(net::ERR_SOCKET_NOT_CONNECTED); return; } - socket_->SetBroadcast(enabled, callback); + socket_->SetBroadcast(enabled, std::move(callback)); } const std::vector<std::string>& UDPSocket::GetJoinedGroups() const {
diff --git a/extensions/browser/api/socket/udp_socket.h b/extensions/browser/api/socket/udp_socket.h index 9c4fdfc..f323d51 100644 --- a/extensions/browser/api/socket/udp_socket.h +++ b/extensions/browser/api/socket/udp_socket.h
@@ -32,13 +32,13 @@ void Disconnect(bool socket_destroying) override; void Bind(const std::string& address, uint16_t port, - const CompletionCallback& callback) override; + net::CompletionOnceCallback callback) override; void Read(int count, ReadCompletionCallback callback) override; - void RecvFrom(int count, const RecvFromCompletionCallback& callback) override; + void RecvFrom(int count, RecvFromCompletionCallback callback) override; void SendTo(scoped_refptr<net::IOBuffer> io_buffer, int byte_count, const net::IPEndPoint& address, - const CompletionCallback& callback) override; + net::CompletionOnceCallback callback) override; bool IsConnected() override; bool GetPeerAddress(net::IPEndPoint* address) override; bool GetLocalAddress(net::IPEndPoint* address) override; @@ -46,17 +46,17 @@ // Joins a multicast group. Can only be called after a successful Bind(). void JoinGroup(const std::string& address, - const net::CompletionCallback& callback); + net::CompletionOnceCallback callback); // Leaves a multicast group. Can only be called after a successful Bind(). void LeaveGroup(const std::string& address, - const net::CompletionCallback& callback); + net::CompletionOnceCallback callback); // Multicast options must be set before Bind()/Connect() is called. int SetMulticastTimeToLive(int ttl); int SetMulticastLoopbackMode(bool loopback); // Sets broadcast to |enabled|. Can only be called after a successful Bind(). - void SetBroadcast(bool enabled, const net::CompletionCallback& callback); + void SetBroadcast(bool enabled, net::CompletionOnceCallback callback); const std::vector<std::string>& GetJoinedGroups() const; @@ -80,16 +80,19 @@ const net::IPEndPoint& remote_addr, int result, const base::Optional<net::IPEndPoint>& local_addr); - void OnBindCompleted(const net::CompletionCallback& user_callback, + void OnBindCompleted(net::CompletionOnceCallback user_callback, int result, const base::Optional<net::IPEndPoint>& local_addr); - void OnWriteOrSendToCompleted(const net::CompletionCallback& user_callback, - size_t byte_count, - int result); - void OnJoinGroupCompleted(const net::CompletionCallback& user_callback, + void OnSendToCompleted(net::CompletionOnceCallback user_callback, + size_t byte_count, + int result); + void OnWriteCompleted(const net::CompletionCallback& user_callback, + size_t byte_count, + int result); + void OnJoinGroupCompleted(net::CompletionOnceCallback user_callback, const std::string& normalized_address, int result); - void OnLeaveGroupCompleted(const net::CompletionCallback& user_callback, + void OnLeaveGroupCompleted(net::CompletionOnceCallback user_callback, const std::string& normalized_address, int result);
diff --git a/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc b/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc index d673dd7..a3799aa 100644 --- a/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc +++ b/extensions/browser/api/sockets_tcp/sockets_tcp_api.cc
@@ -321,8 +321,9 @@ return; } - socket->Connect(addresses_, - base::Bind(&SocketsTcpConnectFunction::OnCompleted, this)); + socket->Connect( + addresses_, + base::BindOnce(&SocketsTcpConnectFunction::OnCompleted, this)); } void SocketsTcpConnectFunction::OnCompleted(int net_result) {
diff --git a/extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc b/extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc index ca3191f..76fbfcb 100644 --- a/extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc +++ b/extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc
@@ -114,7 +114,7 @@ if (buffer_size <= 0) buffer_size = kDefaultBufferSize; socket->Read(buffer_size, - base::Bind(&TCPSocketEventDispatcher::ReadCallback, params)); + base::BindOnce(&TCPSocketEventDispatcher::ReadCallback, params)); } // static
diff --git a/extensions/browser/api/sockets_udp/sockets_udp_api.cc b/extensions/browser/api/sockets_udp/sockets_udp_api.cc index 86606494a..7b23e937 100644 --- a/extensions/browser/api/sockets_udp/sockets_udp_api.cc +++ b/extensions/browser/api/sockets_udp/sockets_udp_api.cc
@@ -210,7 +210,7 @@ return; } socket->Bind(params_->address, params_->port, - base::BindRepeating(&SocketsUdpBindFunction::OnCompleted, this)); + base::BindOnce(&SocketsUdpBindFunction::OnCompleted, this)); } void SocketsUdpBindFunction::OnCompleted(int net_result) { @@ -404,7 +404,7 @@ socket->JoinGroup( params_->address, - base::BindRepeating(&SocketsUdpJoinGroupFunction::OnCompleted, this)); + base::BindOnce(&SocketsUdpJoinGroupFunction::OnCompleted, this)); } void SocketsUdpJoinGroupFunction::OnCompleted(int net_result) { @@ -443,7 +443,7 @@ } socket->LeaveGroup( params_->address, - base::BindRepeating(&SocketsUdpLeaveGroupFunction::OnCompleted, this)); + base::BindOnce(&SocketsUdpLeaveGroupFunction::OnCompleted, this)); } void SocketsUdpLeaveGroupFunction::OnCompleted(int result) { @@ -555,7 +555,7 @@ socket->SetBroadcast( params_->enabled, - base::BindRepeating(&SocketsUdpSetBroadcastFunction::OnCompleted, this)); + base::BindOnce(&SocketsUdpSetBroadcastFunction::OnCompleted, this)); } void SocketsUdpSetBroadcastFunction::OnCompleted(int net_result) {
diff --git a/extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.cc b/extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.cc index daba597..e4c2ef3 100644 --- a/extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.cc +++ b/extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.cc
@@ -99,7 +99,7 @@ int buffer_size = (socket->buffer_size() <= 0 ? 4096 : socket->buffer_size()); socket->RecvFrom( buffer_size, - base::Bind(&UDPSocketEventDispatcher::ReceiveCallback, params)); + base::BindOnce(&UDPSocketEventDispatcher::ReceiveCallback, params)); } /* static */
diff --git a/fuchsia/engine/context_provider_impl.cc b/fuchsia/engine/context_provider_impl.cc index deb06da..b1c5597 100644 --- a/fuchsia/engine/context_provider_impl.cc +++ b/fuchsia/engine/context_provider_impl.cc
@@ -7,7 +7,6 @@ #include <fuchsia/sys/cpp/fidl.h> #include <lib/async/default.h> #include <lib/fdio/io.h> -#include <lib/fdio/util.h> #include <lib/zx/job.h> #include <stdio.h> #include <zircon/processargs.h>
diff --git a/fuchsia/engine/context_provider_impl_unittest.cc b/fuchsia/engine/context_provider_impl_unittest.cc index 961e1af..f9ac8e2 100644 --- a/fuchsia/engine/context_provider_impl_unittest.cc +++ b/fuchsia/engine/context_provider_impl_unittest.cc
@@ -4,7 +4,7 @@ #include "fuchsia/engine/context_provider_impl.h" -#include <lib/fdio/util.h> +#include <lib/fdio/directory.h> #include <lib/fidl/cpp/binding.h> #include <zircon/processargs.h> #include <zircon/types.h> @@ -273,7 +273,10 @@ // Pass a handle data dir to the context. create_params.set_data_directory( - base::fuchsia::OpenDirectory(profile_temp_dir.GetPath())); + fidl::InterfaceHandle<fuchsia::io::Directory>( + zx::channel(base::fuchsia::GetHandleFromFile( + base::File(profile_temp_dir.GetPath(), + base::File::FLAG_OPEN | base::File::FLAG_READ))))); provider_ptr_->Create(std::move(create_params), context.NewRequest()); @@ -302,7 +305,10 @@ // Pass a handle data dir to the context. create_params.set_data_directory( - base::fuchsia::OpenDirectory(profile_temp_dir.GetPath())); + fidl::InterfaceHandle<fuchsia::io::Directory>( + zx::channel(base::fuchsia::GetHandleFromFile( + base::File(profile_temp_dir.GetPath(), + base::File::FLAG_OPEN | base::File::FLAG_READ))))); provider_ptr_->Create2(std::move(create_params), context.NewRequest()); @@ -323,7 +329,10 @@ // Pass in a handle to a file instead of a directory. CHECK(base::CreateTemporaryFile(&temp_file_path)); create_params.set_data_directory( - base::fuchsia::OpenDirectory(temp_file_path)); + fidl::InterfaceHandle<fuchsia::io::Directory>( + zx::channel(base::fuchsia::GetHandleFromFile( + base::File(temp_file_path, + base::File::FLAG_OPEN | base::File::FLAG_READ))))); provider_ptr_->Create(std::move(create_params), context.NewRequest());
diff --git a/fuchsia/runners/common/web_content_runner.cc b/fuchsia/runners/common/web_content_runner.cc index 961d50f..f5889f0 100644 --- a/fuchsia/runners/common/web_content_runner.cc +++ b/fuchsia/runners/common/web_content_runner.cc
@@ -5,7 +5,6 @@ #include "fuchsia/runners/common/web_content_runner.h" #include <fuchsia/sys/cpp/fidl.h> -#include <lib/fdio/util.h> #include <lib/fidl/cpp/binding_set.h> #include <utility> @@ -24,9 +23,11 @@ namespace { -fidl::InterfaceHandle<fuchsia::io::Directory> OpenDirectoryOrFail( +fidl::InterfaceHandle<fuchsia::io::Directory> OpenDirectory( const base::FilePath& path) { - auto directory = base::fuchsia::OpenDirectory(path); + fidl::InterfaceHandle<fuchsia::io::Directory> directory( + zx::channel(base::fuchsia::GetHandleFromFile( + base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ)))); CHECK(directory) << "Failed to open " << path; return directory; } @@ -40,8 +41,8 @@ chromium::web::CreateContextParams2 create_params; // Pass /svc and /data to the context. - create_params.set_service_directory(OpenDirectoryOrFail( - base::FilePath(base::fuchsia::kServiceDirectoryPath))); + create_params.set_service_directory( + OpenDirectory(base::FilePath(base::fuchsia::kServiceDirectoryPath))); if (data_directory) create_params.set_data_directory(std::move(data_directory)); @@ -61,8 +62,8 @@ // static chromium::web::ContextPtr WebContentRunner::CreateDefaultWebContext() { - return CreateWebContextWithDataDirectory(OpenDirectoryOrFail( - base::FilePath(base::fuchsia::kPersistedDataDirectoryPath))); + return CreateWebContextWithDataDirectory( + OpenDirectory(base::FilePath("/data"))); } // static
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc b/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc index 897a674..76d6df45 100644 --- a/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc +++ b/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc
@@ -96,7 +96,7 @@ RegisterBrowserStatePrefs(pref_registry_.get()); BrowserStateDependencyManager::GetInstance() - ->RegisterBrowserStatePrefsForServices(this, pref_registry_.get()); + ->RegisterBrowserStatePrefsForServices(pref_registry_.get()); prefs_ = CreateBrowserStatePrefs(state_path_, GetIOTaskRunner().get(), pref_registry_);
diff --git a/ios/chrome/browser/browser_state/test_chrome_browser_state.mm b/ios/chrome/browser/browser_state/test_chrome_browser_state.mm index 3de87eb..9cec5c60 100644 --- a/ios/chrome/browser/browser_state/test_chrome_browser_state.mm +++ b/ios/chrome/browser/browser_state/test_chrome_browser_state.mm
@@ -207,7 +207,7 @@ static_cast<user_prefs::PrefRegistrySyncable*>( prefs_->DeprecatedGetPrefRegistry()); BrowserStateDependencyManager::GetInstance() - ->RegisterBrowserStatePrefsForServices(this, pref_registry); + ->RegisterBrowserStatePrefsForServices(pref_registry); } BrowserStateDependencyManager::GetInstance()
diff --git a/ios/chrome/browser/infobars/infobar_badge_tab_helper.mm b/ios/chrome/browser/infobars/infobar_badge_tab_helper.mm index a76c0d7..8f7e4f4 100644 --- a/ios/chrome/browser/infobars/infobar_badge_tab_helper.mm +++ b/ios/chrome/browser/infobars/infobar_badge_tab_helper.mm
@@ -64,6 +64,7 @@ void InfobarBadgeTabHelper::OnInfoBarAdded(infobars::InfoBar* infobar) { this->UpdateBadgeForInfobar(infobar, true); + delegate_.badgeState = InfobarBadgeStateNone; } void InfobarBadgeTabHelper::OnInfoBarRemoved(infobars::InfoBar* infobar,
diff --git a/ios/chrome/browser/overscroll_actions/BUILD.gn b/ios/chrome/browser/overscroll_actions/BUILD.gn new file mode 100644 index 0000000..3184f6e9 --- /dev/null +++ b/ios/chrome/browser/overscroll_actions/BUILD.gn
@@ -0,0 +1,42 @@ +# 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. + +source_set("overscroll_actions") { + sources = [ + "overscroll_actions_tab_helper.h", + "overscroll_actions_tab_helper.mm", + ] + deps = [ + "//base", + "//components/keyed_service/ios", + "//ios/chrome/browser", + "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/ui/overscroll_actions", + "//ios/web/public", + ] + + configs += [ "//build/config/compiler:enable_arc" ] +} + +source_set("unit_tests") { + testonly = true + sources = [ + "overscroll_actions_tab_helper_unittest.mm", + ] + deps = [ + ":overscroll_actions", + "//base", + "//base/test:test_support", + "//ios/chrome/browser/browser_state:test_support", + "//ios/chrome/browser/ui/overscroll_actions", + "//ios/chrome/test/fakes", + "//ios/web/public", + "//ios/web/public/test", + "//ios/web/public/test/fakes", + "//testing/gmock", + "//testing/gtest", + "//third_party/ocmock", + ] + configs += [ "//build/config/compiler:enable_arc" ] +}
diff --git a/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper.h b/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper.h new file mode 100644 index 0000000..d100b59a --- /dev/null +++ b/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper.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_OVERSCROLL_ACTIONS_OVERSCROLL_ACTIONS_TAB_HELPER_H_ +#define IOS_CHROME_BROWSER_OVERSCROLL_ACTIONS_OVERSCROLL_ACTIONS_TAB_HELPER_H_ + +#include "base/macros.h" +#import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h" +#include "ios/web/public/web_state/web_state_observer.h" +#import "ios/web/public/web_state/web_state_user_data.h" + +@protocol OverscrollActionsControllerDelegate; + +namespace web { +class WebState; +} + +// OverscrollActionsTabHelper is a Web state observer that owns the +// OverscrollActionsController. +class OverscrollActionsTabHelper + : public web::WebStateObserver, + public web::WebStateUserData<OverscrollActionsTabHelper> { + public: + ~OverscrollActionsTabHelper() override; + + // Sets the delegate. The delegate is not owned by the tab helper. + void SetDelegate(id<OverscrollActionsControllerDelegate> delegate); + + // Returns a pointer for the currently used OverscrollActionsController. + OverscrollActionsController* GetOverscrollActionsController(); + + // Forces the the controller to switch to NO_PULL_STARTED state. + void Clear(); + + private: + friend class web::WebStateUserData<OverscrollActionsTabHelper>; + + OverscrollActionsTabHelper(web::WebState* web_state); + + // web::WebStateObserver override. + void WebStateDestroyed(web::WebState* web_state) override; + + // The Overscroll controller responsible for displaying the + // overscrollActionsView above the toolbar. + OverscrollActionsController* overscroll_actions_controller_ = nil; + + // A weak pointer to the OverscrollActionsControllerDelegate object. + __weak id<OverscrollActionsControllerDelegate> + overscroll_actions_controller_delegate_ = nil; + + // The WebState that is observer by the tab helper. + web::WebState* web_state_ = nullptr; + + WEB_STATE_USER_DATA_KEY_DECL(); + + DISALLOW_COPY_AND_ASSIGN(OverscrollActionsTabHelper); +}; + +#endif // IOS_CHROME_BROWSER_OVERSCROLL_ACTIONS_OVERSCROLL_ACTIONS_TAB_HELPER_H_
diff --git a/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper.mm b/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper.mm new file mode 100644 index 0000000..3cc5a855 --- /dev/null +++ b/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper.mm
@@ -0,0 +1,68 @@ +// 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/overscroll_actions/overscroll_actions_tab_helper.h" + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h" +#import "ios/web/public/web_state/web_state.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +OverscrollActionsTabHelper::~OverscrollActionsTabHelper() {} + +void OverscrollActionsTabHelper::SetDelegate( + id<OverscrollActionsControllerDelegate> delegate) { + // The check for overscrollActionsControllerDelegate is necessary to avoid + // recreating a OverscrollActionsController during teardown. + if (overscroll_actions_controller_.delegate == delegate) { + return; + } + + // Lazily create a OverscrollActionsController when setting the delegate. + // OverscrollTabHelper can't be used without a delegate so if it's not set, + // there is no point of having a controller. + if (!overscroll_actions_controller_) { + overscroll_actions_controller_ = [[OverscrollActionsController alloc] + initWithWebViewProxy:web_state_->GetWebViewProxy()]; + } + ios::ChromeBrowserState* browser_state = + ios::ChromeBrowserState::FromBrowserState(web_state_->GetBrowserState()); + overscroll_actions_controller_.style = + browser_state->IsOffTheRecord() + ? OverscrollStyle::REGULAR_PAGE_INCOGNITO + : OverscrollStyle::REGULAR_PAGE_NON_INCOGNITO; + overscroll_actions_controller_.delegate = delegate; + overscroll_actions_controller_.browserState = browser_state; +} + +OverscrollActionsTabHelper::OverscrollActionsTabHelper(web::WebState* web_state) + : web_state_(web_state) { + web_state_->AddObserver(this); +} + +OverscrollActionsController* +OverscrollActionsTabHelper::GetOverscrollActionsController() { + return overscroll_actions_controller_; +} + +// web::WebStateObserver implementation. +void OverscrollActionsTabHelper::WebStateDestroyed(web::WebState* web_state) { + DCHECK_EQ(web_state_, web_state); + web_state_->RemoveObserver(this); + web_state_ = nullptr; + overscroll_actions_controller_delegate_ = nil; + [overscroll_actions_controller_ invalidate]; + overscroll_actions_controller_ = nil; +} + +void OverscrollActionsTabHelper::Clear() { + [overscroll_actions_controller_ clear]; +} + +WEB_STATE_USER_DATA_KEY_IMPL(OverscrollActionsTabHelper)
diff --git a/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper_unittest.mm b/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper_unittest.mm new file mode 100644 index 0000000..8fd7642 --- /dev/null +++ b/ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper_unittest.mm
@@ -0,0 +1,135 @@ +// 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/overscroll_actions/overscroll_actions_tab_helper.h" + +#import <UIKit/UIKit.h> + +#import "base/test/ios/wait_util.h" +#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" +#import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h" +#import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h" +#import "ios/chrome/test/fakes/fake_overscroll_actions_controller_delegate.h" +#import "ios/web/public/test/fakes/test_web_state.h" +#include "ios/web/public/test/test_web_thread_bundle.h" +#import "ios/web/public/web_state/ui/crw_web_view_proxy.h" +#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h" +#include "testing/gtest/include/gtest/gtest.h" +#import "testing/gtest_mac.h" +#include "testing/platform_test.h" +#import "third_party/ocmock/OCMock/OCMock.h" +#include "third_party/ocmock/gtest_support.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +// Test fixture for OverscrollActionsTabHelper class. +class OverscrollActionsTabHelperTest : public PlatformTest { + protected: + OverscrollActionsTabHelperTest() + : browser_state_(TestChromeBrowserState::Builder().Build()), + overscroll_delegate_( + [[FakeOverscrollActionsControllerDelegate alloc] init]), + scroll_view_proxy_([[CRWWebViewScrollViewProxy alloc] init]), + ui_scroll_view_([[UIScrollView alloc] init]) { + OverscrollActionsTabHelper::CreateForWebState(&web_state_); + [scroll_view_proxy_ setScrollView:ui_scroll_view_]; + id web_view_proxy_mock = OCMProtocolMock(@protocol(CRWWebViewProxy)); + [[[web_view_proxy_mock stub] andReturn:scroll_view_proxy_] scrollViewProxy]; + web_state_.SetWebViewProxy(web_view_proxy_mock); + // Setting insets to imitate having omnibox & toolbar. + scroll_view_proxy_.contentInset = UIEdgeInsetsMake(40, 0, 82, 0); + } + + OverscrollActionsTabHelper* overscroll_tab_helper() { + return OverscrollActionsTabHelper::FromWebState(&web_state_); + } + + UIView* action_view() { + return overscroll_delegate_.headerView.subviews.firstObject; + } + + // Simulates scroll on the |scroll_view_proxy_| view, which should trigger + // page refresh action. + void SimulatePullForRefreshAction() { + [scroll_view_proxy_ scrollViewWillBeginDragging:ui_scroll_view_]; + // Wait until scroll action is allowed. There is no condition to wait, just + // a time period. + base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD( + kMinimumPullDurationToTransitionToReadyInSeconds)); + [scroll_view_proxy_ scrollViewDidScroll:ui_scroll_view_]; + scroll_view_proxy_.contentOffset = CGPointMake(0, -293); + CGPoint target_offset = CGPointMake(0, -92); + [scroll_view_proxy_ scrollViewWillEndDragging:ui_scroll_view_ + withVelocity:CGPointMake(0, -1.5) + targetContentOffset:&target_offset]; + [overscroll_delegate_.headerView layoutIfNeeded]; + [scroll_view_proxy_ scrollViewDidEndDragging:ui_scroll_view_ + willDecelerate:NO]; + } + + web::TestWebThreadBundle thread_bundle_; + std::unique_ptr<ios::ChromeBrowserState> browser_state_; + web::TestWebState web_state_; + FakeOverscrollActionsControllerDelegate* overscroll_delegate_; + CRWWebViewScrollViewProxy* scroll_view_proxy_; + UIScrollView* ui_scroll_view_; +}; + +// Tests that OverscrollActionsControllerDelegate is set correctly and triggered +// When there is a view pull. +TEST_F(OverscrollActionsTabHelperTest, TestDelegateTrigger) { + web_state_.SetBrowserState(browser_state_.get()); + overscroll_tab_helper()->SetDelegate(overscroll_delegate_); + // Start pull for page refresh action. + SimulatePullForRefreshAction(); + + // Wait for the layout calls and the delegate call. + using base::test::ios::WaitUntilConditionOrTimeout; + using base::test::ios::kWaitForUIElementTimeout; + EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^{ + return overscroll_delegate_.selectedAction == OverscrollAction::REFRESH; + })); +} + +// Tests that overscrolls actions view style is set correctly, for regular +// browsing browser state. +TEST_F(OverscrollActionsTabHelperTest, TestRegularBrowserStateStyle) { + web_state_.SetBrowserState(browser_state_.get()); + overscroll_tab_helper()->SetDelegate(overscroll_delegate_); + SimulatePullForRefreshAction(); + UIColor* expected_color = + [UIColor colorWithWhite:kActionViewBackgroundColorBrightnessNonIncognito + alpha:1.0]; + EXPECT_TRUE(action_view()); + EXPECT_NSEQ(expected_color, action_view().backgroundColor); +} + +// Tests that overscrolls actions view style is set correctly, for off the +// record browser state. +TEST_F(OverscrollActionsTabHelperTest, TestOffTheRecordBrowserStateStyle) { + web_state_.SetBrowserState( + browser_state_->GetOffTheRecordChromeBrowserState()); + overscroll_tab_helper()->SetDelegate(overscroll_delegate_); + SimulatePullForRefreshAction(); + UIColor* expected_color = + [UIColor colorWithWhite:kActionViewBackgroundColorBrightnessIncognito + alpha:1.0]; + EXPECT_TRUE(action_view()); + EXPECT_NSEQ(expected_color, action_view().backgroundColor); +} + +// Tests that overscroll state is reset when Clear() is called. +TEST_F(OverscrollActionsTabHelperTest, TestClear) { + web_state_.SetBrowserState(browser_state_.get()); + overscroll_tab_helper()->SetDelegate(overscroll_delegate_); + OverscrollActionsController* controller = + overscroll_tab_helper()->GetOverscrollActionsController(); + EXPECT_EQ(OverscrollState::NO_PULL_STARTED, controller.overscrollState); + SimulatePullForRefreshAction(); + EXPECT_EQ(OverscrollState::ACTION_READY, controller.overscrollState); + overscroll_tab_helper()->Clear(); + EXPECT_EQ(OverscrollState::NO_PULL_STARTED, controller.overscrollState); +}
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_driver.h b/ios/chrome/browser/passwords/ios_chrome_password_manager_driver.h index 5b5235d..64c07e7 100644 --- a/ios/chrome/browser/passwords/ios_chrome_password_manager_driver.h +++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_driver.h
@@ -18,7 +18,6 @@ namespace password_manager { class PasswordAutofillManager; class PasswordManager; -class PasswordGenerationManager; } // namespace password_manager // Defines the interface the driver needs to the controller. @@ -38,8 +37,8 @@ // Informs delegate that there are no saved credentials for the current page. - (void)onNoSavedCredentials; -// Gets the PasswordGenerationManager owned by this delegate. -- (password_manager::PasswordGenerationManager*)passwordGenerationManager; +// Gets the PasswordGenerationFrameHelper owned by this delegate. +- (password_manager::PasswordGenerationFrameHelper*)passwordGenerationHelper; // Informs delegate of form for password generation found. - (void)formEligibleForGenerationFound: @@ -73,7 +72,7 @@ void ShowInitialPasswordAccountSuggestions( const autofill::PasswordFormFillData& form_data) override; void ClearPreviewedForm() override; - password_manager::PasswordGenerationManager* GetPasswordGenerationManager() + password_manager::PasswordGenerationFrameHelper* GetPasswordGenerationHelper() override; password_manager::PasswordManager* GetPasswordManager() override; password_manager::PasswordAutofillManager* GetPasswordAutofillManager()
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_driver.mm b/ios/chrome/browser/passwords/ios_chrome_password_manager_driver.mm index 491a238..3c4c7c8 100644 --- a/ios/chrome/browser/passwords/ios_chrome_password_manager_driver.mm +++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_driver.mm
@@ -14,7 +14,6 @@ #endif using password_manager::PasswordAutofillManager; -using password_manager::PasswordGenerationManager; using password_manager::PasswordManager; IOSChromePasswordManagerDriver::IOSChromePasswordManagerDriver( @@ -67,9 +66,9 @@ NOTIMPLEMENTED(); } -PasswordGenerationManager* -IOSChromePasswordManagerDriver::GetPasswordGenerationManager() { - return [delegate_ passwordGenerationManager]; +password_manager::PasswordGenerationFrameHelper* +IOSChromePasswordManagerDriver::GetPasswordGenerationHelper() { + return [delegate_ passwordGenerationHelper]; } PasswordManager* IOSChromePasswordManagerDriver::GetPasswordManager() {
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm index 5cfbbe7d2..d79b88f9 100644 --- a/ios/chrome/browser/passwords/password_controller.mm +++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -32,7 +32,7 @@ #include "components/infobars/core/infobar_manager.h" #include "components/password_manager/core/browser/form_parsing/ios_form_parser.h" #include "components/password_manager/core/browser/password_bubble_experiment.h" -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/password_manager/core/browser/password_generation_frame_helper.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_driver.h" @@ -81,7 +81,7 @@ using password_manager::FillData; using password_manager::GetPageURLAndCheckTrustLevel; using password_manager::PasswordFormManagerForUI; -using password_manager::PasswordGenerationManager; +using password_manager::PasswordGenerationFrameHelper; using password_manager::PasswordManager; using password_manager::PasswordManagerClient; using password_manager::PasswordManagerDriver; @@ -172,7 +172,7 @@ @implementation PasswordController { std::unique_ptr<PasswordManager> _passwordManager; - std::unique_ptr<PasswordGenerationManager> _passwordGenerationManager; + std::unique_ptr<PasswordGenerationFrameHelper> _passwordGenerationHelper; std::unique_ptr<PasswordManagerClient> _passwordManagerClient; std::unique_ptr<PasswordManagerDriver> _passwordManagerDriver; std::unique_ptr<CredentialManager> _credentialManager; @@ -224,7 +224,7 @@ if (features::IsAutomaticPasswordGenerationEnabled() && !_passwordManagerClient->IsIncognito()) { - _passwordGenerationManager.reset(new PasswordGenerationManager( + _passwordGenerationHelper.reset(new PasswordGenerationFrameHelper( _passwordManagerClient.get(), _passwordManagerDriver.get())); } @@ -581,8 +581,8 @@ [self.suggestionHelper processWithNoSavedCredentials]; } -- (PasswordGenerationManager*)passwordGenerationManager { - return _passwordGenerationManager.get(); +- (PasswordGenerationFrameHelper*)passwordGenerationHelper { + return _passwordGenerationHelper.get(); } - (void)formEligibleForGenerationFound: @@ -740,8 +740,8 @@ // spec_priority in PGM::GeneratePassword are being refactored, passing 0 for // now to get a generic random password. base::string16 generatedPassword = - _passwordGenerationManager->GeneratePassword([self lastCommittedURL], 0, - 0, 0, nullptr); + _passwordGenerationHelper->GeneratePassword([self lastCommittedURL], 0, 0, + 0, nullptr); NSString* title = GetNSStringF(IDS_IOS_SUGGESTED_PASSWORD, generatedPassword); NSString* message = GetNSString(IDS_IOS_SUGGESTED_PASSWORD_HINT);
diff --git a/ios/chrome/browser/passwords/password_tab_helper.h b/ios/chrome/browser/passwords/password_tab_helper.h index 02d5f9d3..c5e518c 100644 --- a/ios/chrome/browser/passwords/password_tab_helper.h +++ b/ios/chrome/browser/passwords/password_tab_helper.h
@@ -18,7 +18,7 @@ @class UIViewController; namespace password_manager { -class PasswordGenerationManager; +class PasswordGenerationFrameHelper; class PasswordManager; } @@ -53,8 +53,8 @@ // Returns the PasswordFormFiller from the PasswordController. id<PasswordFormFiller> GetPasswordFormFiller(); - // Returns the PasswordGenerationManager owned by the PasswordController. - password_manager::PasswordGenerationManager* GetPasswordGenerationManager(); + // Returns the PasswordGenerationFrameHelper owned by the PasswordController. + password_manager::PasswordGenerationFrameHelper* GetGenerationHelper(); // Returns the PasswordManager owned by the PasswordController. password_manager::PasswordManager* GetPasswordManager();
diff --git a/ios/chrome/browser/passwords/password_tab_helper.mm b/ios/chrome/browser/passwords/password_tab_helper.mm index 11f0355..bc4913a 100644 --- a/ios/chrome/browser/passwords/password_tab_helper.mm +++ b/ios/chrome/browser/passwords/password_tab_helper.mm
@@ -55,9 +55,9 @@ return controller_.passwordFormFiller; } -password_manager::PasswordGenerationManager* -PasswordTabHelper::GetPasswordGenerationManager() { - return controller_.passwordGenerationManager; +password_manager::PasswordGenerationFrameHelper* +PasswordTabHelper::GetGenerationHelper() { + return controller_.passwordGenerationHelper; } password_manager::PasswordManager* PasswordTabHelper::GetPasswordManager() {
diff --git a/ios/chrome/browser/tabs/BUILD.gn b/ios/chrome/browser/tabs/BUILD.gn index 957d779..1ca033f 100644 --- a/ios/chrome/browser/tabs/BUILD.gn +++ b/ios/chrome/browser/tabs/BUILD.gn
@@ -106,6 +106,7 @@ "//ios/chrome/browser/language", "//ios/chrome/browser/metrics", "//ios/chrome/browser/metrics:metrics_internal", + "//ios/chrome/browser/overscroll_actions", "//ios/chrome/browser/passwords", "//ios/chrome/browser/prerender", "//ios/chrome/browser/reading_list",
diff --git a/ios/chrome/browser/tabs/tab.h b/ios/chrome/browser/tabs/tab.h index 4a3c9d3..1148a85 100644 --- a/ios/chrome/browser/tabs/tab.h +++ b/ios/chrome/browser/tabs/tab.h
@@ -18,8 +18,6 @@ @class CastController; class GURL; @class OpenInController; -@class OverscrollActionsController; -@protocol OverscrollActionsControllerDelegate; @class PasswordController; @class SnapshotManager; @class FormSuggestionController; @@ -67,11 +65,6 @@ // The Webstate associated with this Tab. @property(nonatomic, readonly) web::WebState* webState; -@property(nonatomic, readonly) - OverscrollActionsController* overscrollActionsController; -@property(nonatomic, weak) id<OverscrollActionsControllerDelegate> - overscrollActionsControllerDelegate; - // Delegate used to show HTTP Authentication dialogs. @property(nonatomic, weak) id<TabDialogDelegate> dialogDelegate; @@ -92,9 +85,6 @@ // Dismisses all modals owned by the tab. - (void)dismissModals; -// Called before capturing a snapshot for Tab. -- (void)willUpdateSnapshot; - // Sends a notification to indicate that |url| is going to start loading. - (void)notifyTabOfUrlMayStartLoading:(const GURL&)url;
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm index 919a94df..64141bc 100644 --- a/ios/chrome/browser/tabs/tab.mm +++ b/ios/chrome/browser/tabs/tab.mm
@@ -63,7 +63,6 @@ #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/commands/show_signin_command.h" #import "ios/chrome/browser/ui/open_in_controller.h" -#import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h" #include "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/web/page_placeholder_tab_helper.h" #import "ios/chrome/browser/web/tab_id_tab_helper.h" @@ -121,10 +120,6 @@ OpenInController* _openInController; - // The Overscroll controller responsible for displaying the - // overscrollActionsView above the toolbar. - OverscrollActionsController* _overscrollActionsController; - // WebStateImpl for this tab. web::WebStateImpl* _webStateImpl; @@ -143,9 +138,6 @@ @implementation Tab -@synthesize overscrollActionsController = _overscrollActionsController; -@synthesize overscrollActionsControllerDelegate = - overscrollActionsControllerDelegate_; @synthesize dialogDelegate = dialogDelegate_; #pragma mark - Initializers @@ -186,31 +178,6 @@ return _webStateImpl; } -- (void)setOverscrollActionsControllerDelegate: - (id<OverscrollActionsControllerDelegate>) - overscrollActionsControllerDelegate { - if (overscrollActionsControllerDelegate_ == - overscrollActionsControllerDelegate) { - return; - } - - // Lazily create a OverscrollActionsController. - // The check for overscrollActionsControllerDelegate is necessary to avoid - // recreating a OverscrollActionsController during teardown. - if (!_overscrollActionsController) { - _overscrollActionsController = [[OverscrollActionsController alloc] - initWithWebViewProxy:self.webState->GetWebViewProxy()]; - } - OverscrollStyle style = OverscrollStyle::REGULAR_PAGE_NON_INCOGNITO; - if (_browserState->IsOffTheRecord()) - style = OverscrollStyle::REGULAR_PAGE_INCOGNITO; - [_overscrollActionsController setStyle:style]; - [_overscrollActionsController - setDelegate:overscrollActionsControllerDelegate]; - [_overscrollActionsController setBrowserState:_browserState]; - overscrollActionsControllerDelegate_ = overscrollActionsControllerDelegate; -} - #pragma mark - Public API - (UIView*)viewForPrinting { @@ -227,10 +194,6 @@ [self.webController dismissModals]; } -- (void)willUpdateSnapshot { - [_overscrollActionsController clear]; -} - - (void)notifyTabOfUrlMayStartLoading:(const GURL&)url { NSString* urlString = base::SysUTF8ToNSString(url.spec()); if ([urlString length]) { @@ -276,12 +239,9 @@ - (void)webStateDestroyed:(web::WebState*)webState { DCHECK_EQ(_webStateImpl, webState); - self.overscrollActionsControllerDelegate = nil; [_openInController detachFromWebController]; _openInController = nil; - [_overscrollActionsController invalidate]; - _overscrollActionsController = nil; // Cancel any queued dialogs. [self.dialogDelegate cancelDialogForTab:self];
diff --git a/ios/chrome/browser/tabs/tab_helper_util.mm b/ios/chrome/browser/tabs/tab_helper_util.mm index e23b5874..2a73c7d 100644 --- a/ios/chrome/browser/tabs/tab_helper_util.mm +++ b/ios/chrome/browser/tabs/tab_helper_util.mm
@@ -28,6 +28,7 @@ #import "ios/chrome/browser/infobars/infobar_manager_impl.h" #import "ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.h" #import "ios/chrome/browser/metrics/ukm_url_recorder.h" +#import "ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper.h" #import "ios/chrome/browser/passwords/password_tab_helper.h" #include "ios/chrome/browser/reading_list/features.h" #include "ios/chrome/browser/reading_list/reading_list_model_factory.h" @@ -92,6 +93,7 @@ ITunesUrlsHandlerTabHelper::CreateForWebState(web_state); HistoryTabHelper::CreateForWebState(web_state); LoadTimingTabHelper::CreateForWebState(web_state); + OverscrollActionsTabHelper::CreateForWebState(web_state); if (base::FeatureList::IsEnabled(kCaptivePortalMetrics)) { CaptivePortalMetricsTabHelper::CreateForWebState(web_state);
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn index d67d5bc..50de8e3 100644 --- a/ios/chrome/browser/ui/BUILD.gn +++ b/ios/chrome/browser/ui/BUILD.gn
@@ -287,6 +287,7 @@ "//ios/chrome/browser/metrics:metrics_internal", "//ios/chrome/browser/net", "//ios/chrome/browser/ntp", + "//ios/chrome/browser/overscroll_actions", "//ios/chrome/browser/passwords", "//ios/chrome/browser/prefs", "//ios/chrome/browser/prerender", @@ -323,7 +324,7 @@ "//ios/chrome/browser/ui/fullscreen:feature_flags", "//ios/chrome/browser/ui/fullscreen:ui", "//ios/chrome/browser/ui/history", - "//ios/chrome/browser/ui/image_util", + "//ios/chrome/browser/ui/image_util:web", "//ios/chrome/browser/ui/infobars", "//ios/chrome/browser/ui/infobars:public", "//ios/chrome/browser/ui/keyboard",
diff --git a/ios/chrome/browser/ui/authentication/cells/BUILD.gn b/ios/chrome/browser/ui/authentication/cells/BUILD.gn index f6fd043..7286007 100644 --- a/ios/chrome/browser/ui/authentication/cells/BUILD.gn +++ b/ios/chrome/browser/ui/authentication/cells/BUILD.gn
@@ -32,7 +32,7 @@ "//ios/chrome/browser/ui/collection_view/cells", "//ios/chrome/browser/ui/colors", "//ios/chrome/browser/ui/commands", - "//ios/chrome/browser/ui/settings/cells", + "//ios/chrome/browser/ui/settings/cells:public", "//ios/chrome/browser/ui/table_view:styler", "//ios/chrome/browser/ui/table_view/cells", "//ios/public/provider/chrome/browser",
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 901b1e2..4ac43485 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -46,6 +46,7 @@ #include "ios/chrome/browser/metrics/tab_usage_recorder.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper_delegate.h" +#import "ios/chrome/browser/overscroll_actions/overscroll_actions_tab_helper.h" #import "ios/chrome/browser/passwords/password_controller.h" #include "ios/chrome/browser/passwords/password_tab_helper.h" #import "ios/chrome/browser/prerender/preload_controller_delegate.h" @@ -2719,7 +2720,7 @@ tab.dialogDelegate = self; if (!IsIPadIdiom()) { - tab.overscrollActionsControllerDelegate = self; + OverscrollActionsTabHelper::FromWebState(tab.webState)->SetDelegate(self); } // Install the proper CRWWebController delegates. tab.webController.nativeProvider = self; @@ -2777,7 +2778,7 @@ tab.dialogDelegate = nil; if (!IsIPadIdiom()) { - tab.overscrollActionsControllerDelegate = nil; + OverscrollActionsTabHelper::FromWebState(tab.webState)->SetDelegate(nil); } tab.webController.nativeProvider = nil; tab.webController.swipeRecognizerProvider = nil; @@ -2977,7 +2978,7 @@ if ([nativeController respondsToSelector:@selector(willUpdateSnapshot)]) { [nativeController willUpdateSnapshot]; } - [tab willUpdateSnapshot]; + OverscrollActionsTabHelper::FromWebState(webState)->Clear(); } - (UIView*)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator @@ -3595,8 +3596,9 @@ - (CGFloat)overscrollActionsControllerHeaderInset: (OverscrollActionsController*)controller { - if (controller == - [[[self tabModel] currentTab] overscrollActionsController]) { + OverscrollActionsTabHelper* activeTabHelper = + OverscrollActionsTabHelper::FromWebState(self.currentWebState); + if (controller == activeTabHelper->GetOverscrollActionsController()) { if (!base::ios::IsRunningOnIOS12OrLater() && self.currentWebState->GetContentsMimeType() == "application/pdf") { return self.headerHeight - self.view.safeAreaInsets.top;
diff --git a/ios/chrome/browser/ui/image_util/BUILD.gn b/ios/chrome/browser/ui/image_util/BUILD.gn index 3fb922a..032c38a 100644 --- a/ios/chrome/browser/ui/image_util/BUILD.gn +++ b/ios/chrome/browser/ui/image_util/BUILD.gn
@@ -4,14 +4,25 @@ source_set("image_util") { sources = [ - "image_copier.h", - "image_copier.mm", - "image_saver.h", - "image_saver.mm", "image_util.h", "image_util.mm", ] deps = [ + "//third_party/google_toolbox_for_mac", + "//ui/base", + ] + configs += [ "//build/config/compiler:enable_arc" ] +} + +source_set("web") { + sources = [ + "image_copier.h", + "image_copier.mm", + "image_saver.h", + "image_saver.mm", + ] + deps = [ + ":image_util", "//base", "//components/image_fetcher/core", "//components/image_fetcher/ios", @@ -20,8 +31,6 @@ "//ios/chrome/browser/ui/alert_coordinator", "//ios/chrome/browser/web", "//ios/web", - "//net", - "//third_party/google_toolbox_for_mac", "//ui/base", ] configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_consumer.h b/ios/chrome/browser/ui/location_bar/location_bar_consumer.h index 47f89b4..d206951 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_consumer.h +++ b/ios/chrome/browser/ui/location_bar/location_bar_consumer.h
@@ -35,6 +35,16 @@ // Infobar redesign. - (void)displayInfobarBadge:(BOOL)display; +// Notifies the consumer that the InfobarBadge select state has changed. +// TODO(crbug.com/935804): This method is currently only being used in the +// Infobar redesign. +- (void)selectInfobarBadge:(BOOL)select; + +// Notifies the consumer that the InfobarBadge active state has changed. +// TODO(crbug.com/935804): This method is currently only being used in the +// Infobar redesign. +- (void)activeInfobarBadge:(BOOL)active; + @end #endif // IOS_CHROME_BROWSER_UI_LOCATION_BAR_LOCATION_BAR_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm index 74d83953..7e3dd78 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
@@ -380,6 +380,14 @@ [self.viewController displayInfobarButton:display]; } +- (void)selectInfobarBadge:(BOOL)select { + [self.viewController setInfobarButtonStyleSelected:select]; +} + +- (void)activeInfobarBadge:(BOOL)active { + [self.viewController setInfobarButtonStyleActive:active]; +} + #pragma mark - private // Returns a dictionary with variation headers for qualified URLs. Can be empty.
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm b/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm index aaed2008..8e4ba749 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm
@@ -166,6 +166,12 @@ [self.consumer displayInfobarBadge:display]; } +- (void)setBadgeState:(InfobarBadgeState)badgeState { + _badgeState = badgeState; + [self.consumer selectInfobarBadge:_badgeState & InfobarBadgeStateSelected]; + [self.consumer activeInfobarBadge:_badgeState & InfobarBadgeStateAccepted]; +} + #pragma mark - Setters - (void)setWebState:(web::WebState*)webState {
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_steady_view.mm b/ios/chrome/browser/ui/location_bar/location_bar_steady_view.mm index 684c109..5cca7773 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_steady_view.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_steady_view.mm
@@ -234,15 +234,18 @@ _leadingButton = [ExtendedTouchTargetButton buttonWithType:UIButtonTypeSystem]; _leadingButton.translatesAutoresizingMaskIntoConstraints = NO; + // TODO(crbug.com/935804): Create constants variables for the magic + // numbers being used here if/when this stops being temporary. + _leadingButton.layer.cornerRadius = 15; [_locationButton addSubview:_leadingButton]; // Setup and activate the leading button constraints. [NSLayoutConstraint activateConstraints:@[ - [_leadingButton.widthAnchor constraintEqualToConstant:kButtonSize], - [_leadingButton.heightAnchor constraintEqualToConstant:kButtonSize], + [_leadingButton.widthAnchor constraintEqualToConstant:35], + [_leadingButton.topAnchor constraintEqualToAnchor:self.topAnchor], + [_leadingButton.bottomAnchor constraintEqualToAnchor:self.bottomAnchor], [_leadingButton.leadingAnchor - constraintEqualToAnchor:self.leadingAnchor - constant:kButtonTrailingSpacing], + constraintEqualToAnchor:self.leadingAnchor], [_leadingButton.centerYAnchor constraintEqualToAnchor:self.centerYAnchor], ]];
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_view_controller.h b/ios/chrome/browser/ui/location_bar/location_bar_view_controller.h index aec3d7c..01f09556 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_view_controller.h +++ b/ios/chrome/browser/ui/location_bar/location_bar_view_controller.h
@@ -77,6 +77,16 @@ // TODO(crbug.com/935804): This method is currently only being used in the // Infobar redesign. - (void)displayInfobarButton:(BOOL)display; +// If |selected| is YES applies the selected styling to the InfobarButton, if NO +// it removes it. +// TODO(crbug.com/935804): This method is currently only being used in the +// Infobar redesign. +- (void)setInfobarButtonStyleSelected:(BOOL)selected; +// If |active| is YES applies the active styling to the InfobarButton, if NO it +// removes it. +// TODO(crbug.com/935804): This method is currently only being used in the +// Infobar redesign. +- (void)setInfobarButtonStyleActive:(BOOL)active; // Displays the voice search button instead of the share button in steady state, // and adds the voice search button to the empty textfield.
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm b/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm index 9a3c432..d9dba5d 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm
@@ -430,23 +430,37 @@ base::RecordAction(base::UserMetricsAction("MobileToolbarShareMenu")); } -// TODO(crbug.com/935804): This method is currently only being used in the -// Infobar redesign. +// TODO(crbug.com/935804): Create constants variables for the magic numbers +// being used here if/when this stops being temporary. - (void)updateInfobarButton { DCHECK(IsInfobarUIRebootEnabled()); [self.locationBarSteadyView.leadingButton setImage:[[UIImage imageNamed:@"infobar_passwords_icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal]; + self.locationBarSteadyView.leadingButton.imageView.contentMode = + UIViewContentModeScaleToFill; + self.locationBarSteadyView.leadingButton.imageEdgeInsets = + UIEdgeInsetsMake(6, 6, 6, 6); + [self.locationBarSteadyView.leadingButton addTarget:self.dispatcher action:@selector(displayModalInfobar) forControlEvents:UIControlEventTouchUpInside]; - self.locationBarSteadyView.leadingButton.tintColor = [UIColor lightGrayColor]; // Set as hidden as it should only be shown by |displayInfobarButton:| self.locationBarSteadyView.leadingButton.hidden = YES; } +- (void)setInfobarButtonStyleSelected:(BOOL)selected { + self.locationBarSteadyView.leadingButton.backgroundColor = + selected ? [UIColor colorWithWhite:0.80 alpha:1.0] : [UIColor clearColor]; +} + +- (void)setInfobarButtonStyleActive:(BOOL)active { + self.locationBarSteadyView.leadingButton.tintColor = + active ? self.locationBarSteadyView.tintColor : [UIColor lightGrayColor]; +} + #pragma mark - UIMenu - (void)showLongPressMenu:(UILongPressGestureRecognizer*)sender {
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h index 0c83606..32db654 100644 --- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h +++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h
@@ -23,6 +23,15 @@ REGULAR_PAGE_INCOGNITO // UI to fit regular pages in incognito. }; +// Minimum delay for the view to perform the transition to the ready state. +extern const CFTimeInterval kMinimumPullDurationToTransitionToReadyInSeconds; + +// The brightness of the actions view background color for non incognito mode. +extern const CGFloat kActionViewBackgroundColorBrightnessNonIncognito; + +// The brightness of the actions view background color for incognito mode. +extern const CGFloat kActionViewBackgroundColorBrightnessIncognito; + @class OverscrollActionsView; @protocol OverscrollActionsViewDelegate
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm index fa6bc97..714fec1 100644 --- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm +++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm
@@ -80,8 +80,6 @@ CGFloat KBezierPathBackDeformation = 2.5; // Controls the amount of points the bezier path is made of. int kBezierPathPointCount = 40; -// Minimum delay to perform the transition to the ready state. -const CFTimeInterval kMinimumPullDurationToTransitionToReadyInSeconds = 0.25; // Value in point to which the action icon frame will be expanded to detect user // direct touches. const CGFloat kDirectTouchFrameExpansion = 20; @@ -121,6 +119,13 @@ }; } // namespace +// Minimum delay to perform the transition to the ready state. +const CFTimeInterval kMinimumPullDurationToTransitionToReadyInSeconds = 0.25; +// The brightness of the actions view background color for non incognito mode. +const CGFloat kActionViewBackgroundColorBrightnessNonIncognito = 242.0 / 256.0; +// The brightness of the actions view background color for incognito mode. +const CGFloat kActionViewBackgroundColorBrightnessIncognito = 80.0 / 256.0; + @interface OverscrollActionsView ()<UIGestureRecognizerDelegate> { // True when the first layout has been done. BOOL _initialLayoutDone; @@ -945,16 +950,14 @@ self.backgroundColor = [UIColor colorWithWhite:0 alpha:0]; break; case OverscrollStyle::REGULAR_PAGE_NON_INCOGNITO: - self.backgroundColor = [UIColor colorWithRed:242.0 / 256 - green:242.0 / 256 - blue:242.0 / 256 - alpha:1.0]; + self.backgroundColor = [UIColor + colorWithWhite:kActionViewBackgroundColorBrightnessNonIncognito + alpha:1.0]; break; case OverscrollStyle::REGULAR_PAGE_INCOGNITO: - self.backgroundColor = [UIColor colorWithRed:80.0 / 256 - green:80.0 / 256 - blue:80.0 / 256 - alpha:1.0]; + self.backgroundColor = + [UIColor colorWithWhite:kActionViewBackgroundColorBrightnessIncognito + alpha:1.0]; break; }
diff --git a/ios/chrome/browser/ui/qr_scanner/camera_controller.mm b/ios/chrome/browser/ui/qr_scanner/camera_controller.mm index a9ab367..bcc0227 100644 --- a/ios/chrome/browser/ui/qr_scanner/camera_controller.mm +++ b/ios/chrome/browser/ui/qr_scanner/camera_controller.mm
@@ -310,6 +310,10 @@ } - (void)stopReceivingNotifications { + // We only start receiving notifications if the camera is available. + if (!self.isCameraAvailable) { + return; + } [[NSNotificationCenter defaultCenter] removeObserver:self]; AVCaptureDevice* camera = [self getCamera]; [camera removeObserver:self forKeyPath:@"hasTorch"];
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm b/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm index 663d272..37ec6770 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm
@@ -524,7 +524,7 @@ // Tests that sharing a web page to the Reading List results in a snackbar // appearing, and that the Reading List entry is present in the Reading List. // Loads offline version via context menu. -- (void)testSavingToReadingListAndLoadDistilled { +- (void)DISABLED_testSavingToReadingListAndLoadDistilled { auto network_change_disabler = std::make_unique<net::NetworkChangeNotifier::DisableForTest>(); auto wifi_network = std::make_unique<WifiNetworkChangeNotifier>(); @@ -606,7 +606,7 @@ // Tests that sharing a web page to the Reading List results in a snackbar // appearing, and that the Reading List entry is present in the Reading List. // Loads offline version by tapping on entry without web server. -- (void)testSavingToReadingListAndLoadNoNetwork { +- (void)DISABLED_testSavingToReadingListAndLoadNoNetwork { auto network_change_disabler = std::make_unique<net::NetworkChangeNotifier::DisableForTest>(); auto wifi_network = std::make_unique<WifiNetworkChangeNotifier>(); @@ -653,7 +653,7 @@ // Tests that sharing a web page to the Reading List results in a snackbar // appearing, and that the Reading List entry is present in the Reading List. // Loads offline version by tapping on entry with delayed web server. -- (void)testSavingToReadingListAndLoadBadNetwork { +- (void)DISABLED_testSavingToReadingListAndLoadBadNetwork { auto network_change_disabler = std::make_unique<net::NetworkChangeNotifier::DisableForTest>(); auto wifi_network = std::make_unique<WifiNetworkChangeNotifier>();
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn index 79918c6..10e3cf2 100644 --- a/ios/chrome/browser/ui/settings/BUILD.gn +++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -24,6 +24,7 @@ "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/material_components", "//ios/chrome/browser/ui/settings/cells", + "//ios/chrome/browser/ui/settings/cells:public", "//ios/chrome/browser/ui/table_view", "//ios/chrome/browser/ui/table_view:styler", "//ios/chrome/browser/ui/table_view/cells", @@ -153,6 +154,7 @@ "//ios/chrome/browser/ui/payments/cells", "//ios/chrome/browser/ui/settings/autofill", "//ios/chrome/browser/ui/settings/cells", + "//ios/chrome/browser/ui/settings/cells:public", "//ios/chrome/browser/ui/settings/clear_browsing_data", "//ios/chrome/browser/ui/settings/google_services", "//ios/chrome/browser/ui/settings/password",
diff --git a/ios/chrome/browser/ui/settings/bandwidth_management_table_view_controller.mm b/ios/chrome/browser/ui/settings/bandwidth_management_table_view_controller.mm index 12627d4..81e194d 100644 --- a/ios/chrome/browser/ui/settings/bandwidth_management_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/bandwidth_management_table_view_controller.mm
@@ -10,9 +10,9 @@ #include "components/prefs/pref_service.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/pref_names.h" -#import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h" #import "ios/chrome/browser/ui/settings/dataplan_usage_table_view_controller.h" #import "ios/chrome/browser/ui/settings/utils/settings_utils.h" +#import "ios/chrome/browser/ui/table_view/cells/settings_detail_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_link_header_footer_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h"
diff --git a/ios/chrome/browser/ui/settings/cells/BUILD.gn b/ios/chrome/browser/ui/settings/cells/BUILD.gn index d40ada1..b9ebeb3 100644 --- a/ios/chrome/browser/ui/settings/cells/BUILD.gn +++ b/ios/chrome/browser/ui/settings/cells/BUILD.gn
@@ -18,10 +18,6 @@ "copied_to_chrome_item.mm", "passphrase_error_item.h", "passphrase_error_item.mm", - "settings_cells_constants.h", - "settings_cells_constants.mm", - "settings_detail_item.h", - "settings_detail_item.mm", "settings_image_detail_text_cell.h", "settings_image_detail_text_cell.mm", "settings_image_detail_text_item.h", @@ -43,6 +39,7 @@ ] deps = [ + ":public", "//components/autofill/core/browser", "//components/strings", "//ios/chrome/app/strings", @@ -66,6 +63,14 @@ configs += [ "//build/config/compiler:enable_arc" ] } +source_set("public") { + sources = [ + "settings_cells_constants.h", + "settings_cells_constants.mm", + ] + configs += [ "//build/config/compiler:enable_arc" ] +} + source_set("unit_tests") { testonly = true sources = [
diff --git a/ios/chrome/browser/ui/settings/content_settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/content_settings_table_view_controller.mm index 5660461..5619d88 100644 --- a/ios/chrome/browser/ui/settings/content_settings_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/content_settings_table_view_controller.mm
@@ -17,10 +17,10 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/content_settings/host_content_settings_map_factory.h" #import "ios/chrome/browser/ui/settings/block_popups_table_view_controller.h" -#import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/settings/translate_table_view_controller.h" #import "ios/chrome/browser/ui/settings/utils/content_setting_backed_boolean.h" +#import "ios/chrome/browser/ui/table_view/cells/settings_detail_item.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/grit/ios_strings.h" #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
diff --git a/ios/chrome/browser/ui/settings/password/BUILD.gn b/ios/chrome/browser/ui/settings/password/BUILD.gn index c71b6f7..2af89f3f 100644 --- a/ios/chrome/browser/ui/settings/password/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/BUILD.gn
@@ -34,6 +34,7 @@ "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/settings:settings_root", "//ios/chrome/browser/ui/settings/cells", + "//ios/chrome/browser/ui/settings/cells:public", "//ios/chrome/browser/ui/settings/utils", "//ios/chrome/browser/ui/table_view", "//ios/chrome/browser/ui/table_view/cells",
diff --git a/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm b/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm index cfa78c37..1b512c6 100644 --- a/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm
@@ -25,7 +25,6 @@ #include "ios/chrome/browser/system_flags.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/settings/cells/settings_cells_constants.h" -#import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h" #import "ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_collection_view_controller.h" @@ -37,6 +36,7 @@ #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/settings/utils/pref_backed_boolean.h" #import "ios/chrome/browser/ui/settings/utils/settings_utils.h" +#import "ios/chrome/browser/ui/table_view/cells/settings_detail_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_link_header_footer_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h"
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm index 6ffee46..2076a38 100644 --- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -44,7 +44,6 @@ #import "ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller.h" #import "ios/chrome/browser/ui/settings/bandwidth_management_table_view_controller.h" #import "ios/chrome/browser/ui/settings/cells/account_sign_in_item.h" -#import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h" #import "ios/chrome/browser/ui/settings/content_settings_table_view_controller.h" @@ -60,6 +59,7 @@ #import "ios/chrome/browser/ui/settings/voice_search_table_view_controller.h" #import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h" #import "ios/chrome/browser/ui/signin_interaction/signin_interaction_coordinator.h" +#import "ios/chrome/browser/ui/table_view/cells/settings_detail_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_image_item.h" #import "ios/chrome/browser/ui/table_view/table_view_model.h"
diff --git a/ios/chrome/browser/ui/settings/sync/sync_settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/sync/sync_settings_table_view_controller.mm index 4c135746..c86d7b37 100644 --- a/ios/chrome/browser/ui/settings/sync/sync_settings_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/sync/sync_settings_table_view_controller.mm
@@ -32,13 +32,13 @@ #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/commands/show_signin_command.h" -#import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h" #import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.h" #import "ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.h" #import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h" +#import "ios/chrome/browser/ui/table_view/cells/settings_detail_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_image_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h"
diff --git a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm index 80c8e370..96be5bc7 100644 --- a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm +++ b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
@@ -13,10 +13,10 @@ #import "ios/chrome/browser/ui/settings/cells/account_sign_in_item.h" #import "ios/chrome/browser/ui/settings/cells/autofill_data_item.h" #import "ios/chrome/browser/ui/settings/cells/copied_to_chrome_item.h" -#import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h" #import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" +#import "ios/chrome/browser/ui/table_view/cells/settings_detail_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_image_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_link_header_footer_item.h" @@ -174,26 +174,26 @@ [model addItem:noDetailTextItem toSectionWithIdentifier:SectionIdentifierText]; - // SectionIdentifierSettings. - TableViewTextHeaderFooterItem* settingsHeader = - [[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeTextHeader]; - settingsHeader.text = @"Settings"; - [model setHeader:settingsHeader - forSectionWithIdentifier:SectionIdentifierSettings]; - SettingsDetailItem* settingsDetailItem = [[SettingsDetailItem alloc] initWithType:ItemTypeTextSettingsDetail]; settingsDetailItem.text = @"Settings cells"; settingsDetailItem.detailText = @"Short"; [model addItem:settingsDetailItem - toSectionWithIdentifier:SectionIdentifierSettings]; + toSectionWithIdentifier:SectionIdentifierText]; SettingsDetailItem* settingsDetailItemLong = [[SettingsDetailItem alloc] initWithType:ItemTypeTextSettingsDetail]; settingsDetailItemLong.text = @"Very long text eating the other detail label"; settingsDetailItemLong.detailText = @"A bit less short"; [model addItem:settingsDetailItemLong - toSectionWithIdentifier:SectionIdentifierSettings]; + toSectionWithIdentifier:SectionIdentifierText]; + + // SectionIdentifierSettings. + TableViewTextHeaderFooterItem* settingsHeader = + [[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeTextHeader]; + settingsHeader.text = @"Settings"; + [model setHeader:settingsHeader + forSectionWithIdentifier:SectionIdentifierSettings]; AccountSignInItem* accountSignInItem = [[AccountSignInItem alloc] initWithType:ItemTypeAccountSignInItem];
diff --git a/ios/chrome/browser/ui/table_view/cells/BUILD.gn b/ios/chrome/browser/ui/table_view/cells/BUILD.gn index 30d47cb..6e16fed 100644 --- a/ios/chrome/browser/ui/table_view/cells/BUILD.gn +++ b/ios/chrome/browser/ui/table_view/cells/BUILD.gn
@@ -4,6 +4,8 @@ source_set("cells") { sources = [ + "settings_detail_item.h", + "settings_detail_item.mm", "table_view_activity_indicator_header_footer_item.h", "table_view_activity_indicator_header_footer_item.mm", "table_view_cell.h", @@ -44,9 +46,9 @@ "//ios/chrome/app/strings", "//ios/chrome/browser/ui/colors:colors", "//ios/chrome/browser/ui/list_model", + "//ios/chrome/browser/ui/settings/cells:public", "//ios/chrome/browser/ui/table_view:styler", "//ios/chrome/browser/ui/util", - "//ios/chrome/browser/ui/util", "//ios/chrome/common", "//ios/chrome/common/favicon", "//ios/chrome/common/ui_util",
diff --git a/ios/chrome/browser/ui/settings/cells/settings_detail_item.h b/ios/chrome/browser/ui/table_view/cells/settings_detail_item.h similarity index 92% rename from ios/chrome/browser/ui/settings/cells/settings_detail_item.h rename to ios/chrome/browser/ui/table_view/cells/settings_detail_item.h index 3d5fe5e..233957e 100644 --- a/ios/chrome/browser/ui/settings/cells/settings_detail_item.h +++ b/ios/chrome/browser/ui/table_view/cells/settings_detail_item.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_SETTINGS_DETAIL_ITEM_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_SETTINGS_DETAIL_ITEM_H_ +#ifndef IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_SETTINGS_DETAIL_ITEM_H_ +#define IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_SETTINGS_DETAIL_ITEM_H_ #import <UIKit/UIKit.h> @@ -64,4 +64,4 @@ @end -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_SETTINGS_DETAIL_ITEM_H_ +#endif // IOS_CHROME_BROWSER_UI_TABLE_VIEW_CELLS_SETTINGS_DETAIL_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/settings_detail_item.mm b/ios/chrome/browser/ui/table_view/cells/settings_detail_item.mm similarity index 99% rename from ios/chrome/browser/ui/settings/cells/settings_detail_item.mm rename to ios/chrome/browser/ui/table_view/cells/settings_detail_item.mm index 42bd261..e0ee57bc 100644 --- a/ios/chrome/browser/ui/settings/cells/settings_detail_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/settings_detail_item.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h" +#import "ios/chrome/browser/ui/table_view/cells/settings_detail_item.h" #include <algorithm>
diff --git a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm index d3adf3b..3d0bd06 100644 --- a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm +++ b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm
@@ -135,8 +135,9 @@ // Move the tools menu button such as it looks visually balanced with the // button on the other side of the toolbar. + NSInteger textDirection = base::i18n::IsRTL() ? -1 : 1; self.toolsMenuButton.transform = - CGAffineTransformMakeTranslation(kToolsMenuOffset, 0); + CGAffineTransformMakeTranslation(textDirection * kToolsMenuOffset, 0); self.allButtons = @[ self.backButton, self.forwardButton, self.omniboxButton, self.tabGridButton,
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 393f666..b2b6352b 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -147,6 +147,7 @@ "//ios/chrome/browser/net:unit_tests", "//ios/chrome/browser/ntp:unit_tests", "//ios/chrome/browser/omaha:unit_tests", + "//ios/chrome/browser/overscroll_actions:unit_tests", "//ios/chrome/browser/passwords:unit_tests", "//ios/chrome/browser/payments:unit_tests", "//ios/chrome/browser/prerender:unit_tests",
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm index a34536f..bd169d8 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -225,27 +225,22 @@ + (void)waitForMainTabCount:(NSUInteger)count { // Allow the UI to become idle, in case any tabs are being opened or closed. [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; - GREYCondition* condition = [GREYCondition - conditionWithName:@"Wait for main tab count" - block:^BOOL { - return chrome_test_util::GetMainTabCount() == count; - }]; - GREYAssert( - [condition waitWithTimeout:base::test::ios::kWaitForUIElementTimeout], - @"Failed waiting for main tab count to become %" PRIuNS, count); + bool success = WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^bool { + return chrome_test_util::GetMainTabCount() == count; + }); + GREYAssert(success, @"Failed waiting for main tab count to become %" PRIuNS, + count); } + (void)waitForIncognitoTabCount:(NSUInteger)count { // Allow the UI to become idle, in case any tabs are being opened or closed. [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; - GREYCondition* condition = [GREYCondition - conditionWithName:@"Wait for incognito tab count" - block:^BOOL { - return chrome_test_util::GetIncognitoTabCount() == count; - }]; - GREYAssert( - [condition waitWithTimeout:base::test::ios::kWaitForUIElementTimeout], - @"Failed waiting for incognito tab count to become %" PRIuNS, count); + bool success = WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^bool { + return chrome_test_util::GetIncognitoTabCount() == count; + }); + GREYAssert(success, + @"Failed waiting for incognito tab count to become %" PRIuNS, + count); } + (void)waitForWebViewContainingBlockedImageElementWithID:(std::string)imageID { @@ -272,18 +267,16 @@ } + (void)waitForElementWithMatcherSufficientlyVisible:(id<GREYMatcher>)matcher { - GREYCondition* condition = [GREYCondition - conditionWithName:@"Wait for element with matcher sufficiently visible" - block:^BOOL { - NSError* error = nil; - [[EarlGrey selectElementWithMatcher:matcher] - assertWithMatcher:grey_sufficientlyVisible() - error:&error]; - return error == nil; - }]; - GREYAssert( - [condition waitWithTimeout:base::test::ios::kWaitForUIElementTimeout], - @"Failed waiting for element with matcher %@ to become visible", matcher); + bool success = WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^bool { + NSError* error = nil; + [[EarlGrey selectElementWithMatcher:matcher] + assertWithMatcher:grey_sufficientlyVisible() + error:&error]; + return error == nil; + }); + GREYAssert(success, + @"Failed waiting for element with matcher %@ to become visible", + matcher); } @end
diff --git a/ios/chrome/test/fakes/BUILD.gn b/ios/chrome/test/fakes/BUILD.gn index 5eec4dc..263af59 100644 --- a/ios/chrome/test/fakes/BUILD.gn +++ b/ios/chrome/test/fakes/BUILD.gn
@@ -19,6 +19,8 @@ "fake_download_manager_tab_helper_delegate.mm", "fake_java_script_console_tab_helper_delegate.cc", "fake_java_script_console_tab_helper_delegate.h", + "fake_overscroll_actions_controller_delegate.h", + "fake_overscroll_actions_controller_delegate.mm", "fake_pass_kit_tab_helper_delegate.h", "fake_pass_kit_tab_helper_delegate.mm", "fake_store_kit_launcher.h", @@ -36,6 +38,7 @@ "//ios/chrome/browser/ui", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/download", + "//ios/chrome/browser/ui/overscroll_actions", "//ios/chrome/browser/ui/presenters", "//ios/chrome/browser/web:web_internal", "//ios/web/public",
diff --git a/ios/chrome/test/fakes/fake_overscroll_actions_controller_delegate.h b/ios/chrome/test/fakes/fake_overscroll_actions_controller_delegate.h new file mode 100644 index 0000000..d22b223 --- /dev/null +++ b/ios/chrome/test/fakes/fake_overscroll_actions_controller_delegate.h
@@ -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. + +#ifndef IOS_CHROME_TEST_FAKES_FAKE_OVERSCROLL_ACTIONS_CONTROLLER_DELEGATE_H_ +#define IOS_CHROME_TEST_FAKES_FAKE_OVERSCROLL_ACTIONS_CONTROLLER_DELEGATE_H_ + +#import <Foundation/Foundation.h> + +#import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h" +#import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h" + +// Fake OverscrollActionsControllerDelegate used for testing. +// The delegate saves the last triggered action, and provide a view to be used +// as a parent to the OverscrollActionsView. +@interface FakeOverscrollActionsControllerDelegate + : NSObject <OverscrollActionsControllerDelegate> + +// The OverscrollAction parameter that was used to call +// |overscrollActionsController:didTriggerAction:| with. +@property(nonatomic, assign) OverscrollAction selectedAction; + +// The header view, acts as the superview for overscrollActionsView. +@property(nonatomic, strong) UIView* headerView; + +@end + +#endif // IOS_CHROME_TEST_FAKES_FAKE_OVERSCROLL_ACTIONS_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/test/fakes/fake_overscroll_actions_controller_delegate.mm b/ios/chrome/test/fakes/fake_overscroll_actions_controller_delegate.mm new file mode 100644 index 0000000..d8e299c --- /dev/null +++ b/ios/chrome/test/fakes/fake_overscroll_actions_controller_delegate.mm
@@ -0,0 +1,47 @@ +// 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/test/fakes/fake_overscroll_actions_controller_delegate.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation FakeOverscrollActionsControllerDelegate + +- (instancetype)init { + self = [super init]; + if (self) { + _headerView = [[UIView alloc] init]; + } + return self; +} + +- (void)overscrollActionsController:(OverscrollActionsController*)controller + didTriggerAction:(OverscrollAction)action { + _selectedAction = action; +} + +- (BOOL)shouldAllowOverscrollActions { + return YES; +} + +- (UIView*)toolbarSnapshotView { + return nil; +} + +- (UIView*)headerView { + return _headerView; +} + +- (CGFloat)overscrollActionsControllerHeaderInset: + (OverscrollActionsController*)controller { + return 0; +} + +- (CGFloat)overscrollHeaderHeight { + return 0; +} + +@end
diff --git a/ios/web/navigation/legacy_navigation_manager_impl.mm b/ios/web/navigation/legacy_navigation_manager_impl.mm index a51f21c..0fd6212 100644 --- a/ios/web/navigation/legacy_navigation_manager_impl.mm +++ b/ios/web/navigation/legacy_navigation_manager_impl.mm
@@ -112,10 +112,8 @@ void LegacyNavigationManagerImpl::CommitPendingItem( std::unique_ptr<NavigationItemImpl> item) { - // TODO(crbug.com/665189): NavigationManager::GetPendingItemIndex returns - // incorrect value, so CRWSessionController.pendingItemIndex is used instead. if (web::features::StorePendingItemInContext() && - session_controller_.pendingItemIndex == -1) { + GetPendingItemIndex() == -1) { [session_controller_ commitPendingItem:std::move(item)]; } else { CommitPendingItem();
diff --git a/ios/web/navigation/navigation_manager_delegate.h b/ios/web/navigation/navigation_manager_delegate.h index f855e8f..0653bfb 100644 --- a/ios/web/navigation/navigation_manager_delegate.h +++ b/ios/web/navigation/navigation_manager_delegate.h
@@ -15,6 +15,7 @@ enum class NavigationInitiationType; class NavigationItem; +class NavigationItemImpl; class WebState; // Delegate for NavigationManager to hand off parts of the navigation flow. @@ -74,6 +75,9 @@ // currently is to clear back-forward history in web view before restoring // session history. virtual void RemoveWebView() = 0; + + // Used to access pending item stored in NavigationContext. + virtual NavigationItemImpl* GetPendingItem() = 0; }; } // namespace web
diff --git a/ios/web/navigation/navigation_manager_impl_unittest.mm b/ios/web/navigation/navigation_manager_impl_unittest.mm index 34a226f..d7ab19a 100644 --- a/ios/web/navigation/navigation_manager_impl_unittest.mm +++ b/ios/web/navigation/navigation_manager_impl_unittest.mm
@@ -96,6 +96,7 @@ NavigationItem*, NavigationInitiationType, bool)); + MOCK_METHOD0(GetPendingItem, NavigationItemImpl*()); private: WebState* GetWebState() override { return nullptr; } @@ -179,9 +180,8 @@ if (GetParam() == TEST_LEGACY_NAVIGATION_MANAGER) { session_controller_delegate_.pendingItem = item; } else { - // TODO(crbug.com/899827): Allow the delegate to provide pending item when - // slim-navigation-manager is enabled. - NOTREACHED(); + EXPECT_CALL(navigation_manager_delegate(), GetPendingItem()) + .WillOnce(testing::Return(item)); } }
diff --git a/ios/web/navigation/wk_based_navigation_manager_impl.mm b/ios/web/navigation/wk_based_navigation_manager_impl.mm index 1910fa6..0904eb61 100644 --- a/ios/web/navigation/wk_based_navigation_manager_impl.mm +++ b/ios/web/navigation/wk_based_navigation_manager_impl.mm
@@ -693,9 +693,13 @@ NavigationItemImpl* WKBasedNavigationManagerImpl::GetPendingItemInCurrentOrRestoredSession() const { - return (pending_item_index_ == -1) - ? pending_item_.get() - : GetNavigationItemImplAtIndex(pending_item_index_); + if (pending_item_index_ == -1) { + if (features::StorePendingItemInContext() && !pending_item_) { + return delegate_->GetPendingItem(); + } + return pending_item_.get(); + } + return GetNavigationItemImplAtIndex(pending_item_index_); } NavigationItemImpl* WKBasedNavigationManagerImpl::GetTransientItemImpl() const {
diff --git a/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm b/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm index fae6bea..66cc553 100644 --- a/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm +++ b/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm
@@ -84,6 +84,7 @@ NavigationItem*, NavigationInitiationType, bool)); + MOCK_METHOD0(GetPendingItem, NavigationItemImpl*()); private: WebState* GetWebState() override { return nullptr; }
diff --git a/ios/web/test/fakes/fake_navigation_manager_delegate.h b/ios/web/test/fakes/fake_navigation_manager_delegate.h index 4d3370f..d3d311a4 100644 --- a/ios/web/test/fakes/fake_navigation_manager_delegate.h +++ b/ios/web/test/fakes/fake_navigation_manager_delegate.h
@@ -30,6 +30,7 @@ NavigationInitiationType type, bool has_user_gesture) override; void RemoveWebView() override; + NavigationItemImpl* GetPendingItem() override; // Setters for tests to inject dependencies. void SetWebViewNavigationProxy(id test_web_view);
diff --git a/ios/web/test/fakes/fake_navigation_manager_delegate.mm b/ios/web/test/fakes/fake_navigation_manager_delegate.mm index ae0f1493..2220cd3 100644 --- a/ios/web/test/fakes/fake_navigation_manager_delegate.mm +++ b/ios/web/test/fakes/fake_navigation_manager_delegate.mm
@@ -40,6 +40,10 @@ bool has_user_gesture) {} void FakeNavigationManagerDelegate::RemoveWebView() {} +NavigationItemImpl* FakeNavigationManagerDelegate::GetPendingItem() { + return nullptr; +} + void FakeNavigationManagerDelegate::SetWebViewNavigationProxy(id web_view) { test_web_view_ = web_view; }
diff --git a/ios/web/web_state/ui/crw_web_controller.h b/ios/web/web_state/ui/crw_web_controller.h index 1acaa6b7..d0ec0ca 100644 --- a/ios/web/web_state/ui/crw_web_controller.h +++ b/ios/web/web_state/ui/crw_web_controller.h
@@ -106,6 +106,10 @@ // calling code must retain the ownership of |webState|. - (instancetype)initWithWebState:(web::WebStateImpl*)webState; +// Returns the latest navigation item created for new navigation, which is +// stored in navigation context. +- (web::NavigationItemImpl*)lastPendingItemForNewNavigation; + // Replaces the currently displayed content with |contentView|. The content // view will be dismissed for the next navigation. - (void)showTransientContentView:(CRWContentView*)contentView;
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 6c97832..27dfc4732 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -1057,6 +1057,16 @@ #pragma mark - Header public methods +- (web::NavigationItemImpl*)lastPendingItemForNewNavigation { + WKNavigation* navigation = + [_navigationStates lastNavigationWithPendingItemInNavigationContext]; + if (!navigation) + return nullptr; + web::NavigationContextImpl* context = + [_navigationStates contextForNavigation:navigation]; + return context->GetItem(); +} + - (void)showTransientContentView:(CRWContentView*)contentView { DCHECK(contentView); DCHECK(contentView.scrollView); @@ -1642,11 +1652,7 @@ - (web::NavigationItemImpl*)pendingItemForSessionController: (CRWSessionController*)sessionController { - WKNavigation* navigation = - [_navigationStates lastNavigationWithPendingItemInNavigationContext]; - if (!navigation) - return nullptr; - return [_navigationStates contextForNavigation:navigation] -> GetItem(); + return [self lastPendingItemForNewNavigation]; } #pragma mark - CRWTouchTrackingDelegate (Public) @@ -1904,10 +1910,7 @@ if (![_nativeProvider hasControllerForURL:context->GetUrl()] && !(_webUIManager && web::GetWebClient()->IsAppSpecificURL(context->GetUrl()))) { - // TODO(crbug.com/665189): NavigationManager::GetPendingItemIndex returns - // incorrect value, so CRWSessionController.pendingItemIndex is used - // instead. - if ([self.sessionController pendingItemIndex] == -1) { + if (self.navigationManagerImpl->GetPendingItemIndex() == -1) { context->SetItem([self.sessionController releasePendingItem]); } } @@ -2181,16 +2184,14 @@ } - (void)reportBackForwardNavigationTypeForFastNavigation:(BOOL)isFast { - // TODO(crbug.com/665189): Use NavigationManager::GetPendingItemIndex() once - // it returns correct result. - int pendingIndex = self.sessionController.pendingItemIndex; + NavigationManager* navigationManager = self.navigationManagerImpl; + int pendingIndex = navigationManager->GetPendingItemIndex(); if (pendingIndex == -1) { // Pending navigation is not a back forward navigation. return; } - BOOL isBack = - pendingIndex < self.navigationManagerImpl->GetLastCommittedItemIndex(); + BOOL isBack = pendingIndex < navigationManager->GetLastCommittedItemIndex(); BackForwardNavigationType type = BackForwardNavigationType::FAST_BACK; if (isBack) { type = isFast ? BackForwardNavigationType::FAST_BACK @@ -4957,7 +4958,9 @@ BOOL isLastNavigation = !navigation || [[_navigationStates lastAddedNavigation] isEqual:navigation]; - if (isLastNavigation) { + if (isLastNavigation || + (web::features::StorePendingItemInContext() && + self.webState->GetNavigationManager()->GetPendingItemIndex() == -1)) { [self webPageChangedWithContext:context]; } else if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) { // WKWebView has more than one in progress navigation, and committed @@ -5219,8 +5222,6 @@ // we should be distinguishing better, and be clear about the expected // WebDelegate and WCO callbacks in each case. - (void)webPageChangedWithContext:(web::NavigationContextImpl*)context { - DCHECK_EQ(_loadPhase, web::LOAD_REQUESTED); - web::Referrer referrer = [self currentReferrer]; // If no referrer was known in advance, record it now. (If there was one, // keep it since it will have a more accurate URL and policy than what can
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm index e197420..70f41df 100644 --- a/ios/web/web_state/ui/crw_web_controller_unittest.mm +++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -325,6 +325,30 @@ EXPECT_FALSE(observer.did_finish_navigation_info()); } +// Tests returning pending item stored in navigation context. +TEST_P(CRWWebControllerTest, TestPendingItem) { + if (!web::features::StorePendingItemInContext()) + return; + + ASSERT_FALSE([web_controller() pendingItemForSessionController:nil]); + ASSERT_FALSE([web_controller() lastPendingItemForNewNavigation]); + ASSERT_FALSE(web_controller().webStateImpl->GetPendingItem()); + + // Create pending item by simulating a renderer-initiated navigation. + [navigation_delegate_ webView:mock_web_view_ + didStartProvisionalNavigation:nil]; + + NavigationItemImpl* item = [web_controller() lastPendingItemForNewNavigation]; + + // Verify that the same item is returned by NavigationManagerDelegate, + // CRWSessionControllerDelegate and CRWWebController. + ASSERT_TRUE(item); + EXPECT_EQ(item, [web_controller() pendingItemForSessionController:nil]); + EXPECT_EQ(item, web_controller().webStateImpl->GetPendingItem()); + + EXPECT_EQ(kTestURLString, item->GetURL()); +} + // Tests allowsBackForwardNavigationGestures default value and negating this // property. TEST_P(CRWWebControllerTest, SetAllowsBackForwardNavigationGestures) {
diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h index 0171a9c..187d8de 100644 --- a/ios/web/web_state/web_state_impl.h +++ b/ios/web/web_state/web_state_impl.h
@@ -295,6 +295,7 @@ NavigationInitiationType type, bool has_user_gesture) override; void RemoveWebView() override; + NavigationItemImpl* GetPendingItem() override; protected: void AddPolicyDecider(WebStatePolicyDecider* decider) override;
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm index 6266f24..11754b2 100644 --- a/ios/web/web_state/web_state_impl.mm +++ b/ios/web/web_state/web_state_impl.mm
@@ -897,6 +897,10 @@ return [web_controller_ removeWebView]; } +NavigationItemImpl* WebStateImpl::GetPendingItem() { + return [web_controller_ lastPendingItemForNewNavigation]; +} + void WebStateImpl::RestoreSessionStorage(CRWSessionStorage* session_storage) { // Session storage restore is asynchronous with WKBasedNavigationManager // because it involves a page load in WKWebView. Temporarily cache the
diff --git a/ios/web_view/internal/cwv_preferences.mm b/ios/web_view/internal/cwv_preferences.mm index e1c6443..3b052af0 100644 --- a/ios/web_view/internal/cwv_preferences.mm +++ b/ios/web_view/internal/cwv_preferences.mm
@@ -4,11 +4,11 @@ #import "ios/web_view/internal/cwv_preferences_internal.h" +#include "components/language/core/browser/pref_names.h" #include "components/prefs/pref_service.h" #include "components/translate/core/browser/translate_pref_names.h" #include "components/translate/core/browser/translate_prefs.h" #include "ios/web_view/cwv_web_view_buildflags.h" -#include "ios/web_view/internal/pref_names.h" #if BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL) #include "components/autofill/core/common/autofill_prefs.h" @@ -43,7 +43,7 @@ - (void)resetTranslationSettings { translate::TranslatePrefs translatePrefs( - _prefService, prefs::kAcceptLanguages, + _prefService, language::prefs::kAcceptLanguages, /*preferred_languages_pref=*/nullptr); translatePrefs.ResetToDefaults(); }
diff --git a/ios/web_view/internal/language/web_view_language_model_manager_factory.mm b/ios/web_view/internal/language/web_view_language_model_manager_factory.mm index e01324f..8534fc4 100644 --- a/ios/web_view/internal/language/web_view_language_model_manager_factory.mm +++ b/ios/web_view/internal/language/web_view_language_model_manager_factory.mm
@@ -17,7 +17,6 @@ #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "ios/web_view/internal/app/application_context.h" -#include "ios/web_view/internal/pref_names.h" #include "ios/web_view/internal/web_view_browser_state.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -41,7 +40,8 @@ std::make_unique<language::HeuristicLanguageModel>( web_view_browser_state->GetPrefs(), ApplicationContext::GetInstance()->GetApplicationLocale(), - prefs::kAcceptLanguages, language::prefs::kUserLanguageProfile)); + language::prefs::kAcceptLanguages, + language::prefs::kUserLanguageProfile)); } // language::OverrideLanguageModel::GEO is not supported on iOS yet. @@ -52,7 +52,7 @@ std::make_unique<language::BaselineLanguageModel>( web_view_browser_state->GetPrefs(), ApplicationContext::GetInstance()->GetApplicationLocale(), - prefs::kAcceptLanguages)); + language::prefs::kAcceptLanguages)); } // Set the primary Language Model to use based on the state of experiments.
diff --git a/ios/web_view/internal/passwords/web_view_password_manager_driver.h b/ios/web_view/internal/passwords/web_view_password_manager_driver.h index 5b6baf6..fb5fd72 100644 --- a/ios/web_view/internal/passwords/web_view_password_manager_driver.h +++ b/ios/web_view/internal/passwords/web_view_password_manager_driver.h
@@ -61,7 +61,7 @@ void ShowInitialPasswordAccountSuggestions( const autofill::PasswordFormFillData& form_data) override; void ClearPreviewedForm() override; - password_manager::PasswordGenerationManager* GetPasswordGenerationManager() + password_manager::PasswordGenerationFrameHelper* GetPasswordGenerationHelper() override; password_manager::PasswordManager* GetPasswordManager() override; password_manager::PasswordAutofillManager* GetPasswordAutofillManager()
diff --git a/ios/web_view/internal/passwords/web_view_password_manager_driver.mm b/ios/web_view/internal/passwords/web_view_password_manager_driver.mm index 7c5f17b..44dbf0a0 100644 --- a/ios/web_view/internal/passwords/web_view_password_manager_driver.mm +++ b/ios/web_view/internal/passwords/web_view_password_manager_driver.mm
@@ -14,7 +14,6 @@ #endif using password_manager::PasswordAutofillManager; -using password_manager::PasswordGenerationManager; using password_manager::PasswordManager; namespace ios_web_view { @@ -62,8 +61,8 @@ NOTIMPLEMENTED(); } -PasswordGenerationManager* -WebViewPasswordManagerDriver::GetPasswordGenerationManager() { +password_manager::PasswordGenerationFrameHelper* +WebViewPasswordManagerDriver::GetPasswordGenerationHelper() { return nullptr; }
diff --git a/ios/web_view/internal/pref_names.h b/ios/web_view/internal/pref_names.h index 89eee32..589f456 100644 --- a/ios/web_view/internal/pref_names.h +++ b/ios/web_view/internal/pref_names.h
@@ -7,10 +7,6 @@ namespace prefs { -// The value to use for Accept-Languages HTTP header when making an HTTP -// request. Currently only used for Translate related requests. -extern const char kAcceptLanguages[]; - // Boolean controlling whether history saving is disabled. extern const char kSavingBrowserHistoryDisabled[];
diff --git a/ios/web_view/internal/pref_names.mm b/ios/web_view/internal/pref_names.mm index 41a44ac..0364ec0 100644 --- a/ios/web_view/internal/pref_names.mm +++ b/ios/web_view/internal/pref_names.mm
@@ -10,8 +10,6 @@ namespace prefs { -const char kAcceptLanguages[] = "intl.accept_languages"; - const char kSavingBrowserHistoryDisabled[] = "history.saving_disabled"; } // namespace prefs
diff --git a/ios/web_view/internal/translate/web_view_translate_accept_languages_factory.mm b/ios/web_view/internal/translate/web_view_translate_accept_languages_factory.mm index 5f65856..a36a003 100644 --- a/ios/web_view/internal/translate/web_view_translate_accept_languages_factory.mm +++ b/ios/web_view/internal/translate/web_view_translate_accept_languages_factory.mm
@@ -7,9 +7,9 @@ #include "base/no_destructor.h" #include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" +#include "components/language/core/browser/pref_names.h" #include "components/prefs/pref_service.h" #include "components/translate/core/browser/translate_accept_languages.h" -#include "ios/web_view/internal/pref_names.h" #include "ios/web_view/internal/web_view_browser_state.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -38,7 +38,7 @@ TranslateAcceptLanguagesService::TranslateAcceptLanguagesService( PrefService* prefs) - : accept_languages_(prefs, prefs::kAcceptLanguages) {} + : accept_languages_(prefs, language::prefs::kAcceptLanguages) {} TranslateAcceptLanguagesService::~TranslateAcceptLanguagesService() = default;
diff --git a/ios/web_view/internal/translate/web_view_translate_client.mm b/ios/web_view/internal/translate/web_view_translate_client.mm index c2e4d1e..6fab396 100644 --- a/ios/web_view/internal/translate/web_view_translate_client.mm +++ b/ios/web_view/internal/translate/web_view_translate_client.mm
@@ -9,6 +9,7 @@ #include "base/logging.h" #include "components/infobars/core/infobar.h" #include "components/language/core/browser/language_model_manager.h" +#include "components/language/core/browser/pref_names.h" #include "components/prefs/pref_service.h" #include "components/translate/core/browser/page_translated_details.h" #include "components/translate/core/browser/translate_accept_languages.h" @@ -21,7 +22,6 @@ #import "ios/web/public/web_state/web_state.h" #include "ios/web_view/internal/language/web_view_language_model_manager_factory.h" #import "ios/web_view/internal/language/web_view_url_language_histogram_factory.h" -#include "ios/web_view/internal/pref_names.h" #import "ios/web_view/internal/translate/cwv_translation_controller_internal.h" #include "ios/web_view/internal/translate/web_view_translate_accept_languages_factory.h" #include "ios/web_view/internal/translate/web_view_translate_ranker_factory.h" @@ -102,7 +102,7 @@ std::unique_ptr<translate::TranslatePrefs> WebViewTranslateClient::GetTranslatePrefs() { return std::make_unique<translate::TranslatePrefs>( - GetPrefs(), prefs::kAcceptLanguages, nullptr); + GetPrefs(), language::prefs::kAcceptLanguages, nullptr); } translate::TranslateAcceptLanguages*
diff --git a/ios/web_view/internal/web_view_browser_state.mm b/ios/web_view/internal/web_view_browser_state.mm index 6eb13da..fa0e21a 100644 --- a/ios/web_view/internal/web_view_browser_state.mm +++ b/ios/web_view/internal/web_view_browser_state.mm
@@ -16,6 +16,7 @@ #include "components/gcm_driver/gcm_channel_status_syncer.h" #include "components/history/core/common/pref_names.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" +#include "components/language/core/browser/language_prefs.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/in_memory_pref_store.h" @@ -38,7 +39,6 @@ #include "ios/web_view/internal/language/web_view_url_language_histogram_factory.h" #import "ios/web_view/internal/passwords/web_view_password_manager_internals_service_factory.h" #include "ios/web_view/internal/passwords/web_view_password_store_factory.h" -#include "ios/web_view/internal/pref_names.h" #include "ios/web_view/internal/signin/web_view_account_fetcher_service_factory.h" #include "ios/web_view/internal/signin/web_view_identity_manager_factory.h" #include "ios/web_view/internal/signin/web_view_signin_client_factory.h" @@ -161,11 +161,7 @@ void WebViewBrowserState::RegisterPrefs( user_prefs::PrefRegistrySyncable* pref_registry) { - // TODO(crbug.com/679895): Find a good value for the kAcceptLanguages pref. - // TODO(crbug.com/679895): Pass this value to the network stack somehow, for - // the HTTP header. - pref_registry->RegisterStringPref(prefs::kAcceptLanguages, - l10n_util::GetLocaleOverride()); + language::RegisterProfilePrefs(pref_registry); pref_registry->RegisterBooleanPref(prefs::kOfferTranslateEnabled, true); pref_registry->RegisterBooleanPref(prefs::kSavingBrowserHistoryDisabled, true); @@ -209,7 +205,7 @@ #endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_SYNC) BrowserStateDependencyManager::GetInstance() - ->RegisterBrowserStatePrefsForServices(this, pref_registry); + ->RegisterBrowserStatePrefsForServices(pref_registry); } } // namespace ios_web_view
diff --git a/ios/web_view/test/web_view_autofill_inttest.mm b/ios/web_view/test/web_view_autofill_inttest.mm index 2d58b3e..f6acfb1 100644 --- a/ios/web_view/test/web_view_autofill_inttest.mm +++ b/ios/web_view/test/web_view_autofill_inttest.mm
@@ -75,7 +75,12 @@ std::string html = base::SysNSStringToUTF8(kTestFormHtml); main_frame_id_ = nil; GURL url = GetUrlForPageWithHtmlBody(html); - return test::LoadUrl(web_view_, net::NSURLWithGURL(url)); + if (!test::LoadUrl(web_view_, net::NSURLWithGURL(url))) { + return false; + } + return WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^bool { + return !!GetMainFrameId(); + }); } bool SubmitForm() WARN_UNUSED_RESULT {
diff --git a/media/blink/cache_util_unittest.cc b/media/blink/cache_util_unittest.cc index ef5953c..ecd47f2 100644 --- a/media/blink/cache_util_unittest.cc +++ b/media/blink/cache_util_unittest.cc
@@ -35,7 +35,7 @@ // Create a new WebURLResponse object. static WebURLResponse CreateResponse(const GRFUTestCase& test) { WebURLResponse response; - response.SetHTTPVersion(test.version); + response.SetHttpVersion(test.version); response.SetHttpStatusCode(test.status_code); for (const std::string& line : base::SplitString(test.headers, "\n", base::KEEP_WHITESPACE,
diff --git a/net/dns/dns_test_util.cc b/net/dns/dns_test_util.cc index c428f52..eab0df0 100644 --- a/net/dns/dns_test_util.cc +++ b/net/dns/dns_test_util.cc
@@ -334,9 +334,10 @@ std::vector<DnsResourceRecord>() /* additional_records */, query); } -std::unique_ptr<DnsResponse> BuildTestDnsResponse(std::string name, - const IPAddress& ip, - std::string cannonname) { +std::unique_ptr<DnsResponse> BuildTestDnsResponseWithCname( + std::string name, + const IPAddress& ip, + std::string cannonname) { DCHECK(ip.IsValid()); DCHECK(!cannonname.empty()); @@ -354,7 +355,7 @@ std::vector<DnsResourceRecord>() /* additional_records */, query); } -std::unique_ptr<DnsResponse> BuildTestDnsResponse( +std::unique_ptr<DnsResponse> BuildTestDnsTextResponse( std::string name, std::vector<std::vector<std::string>> text_records, std::string answer_name) { @@ -400,7 +401,7 @@ std::vector<DnsResourceRecord>() /* additional_records */, query); } -std::unique_ptr<DnsResponse> BuildTestDnsResponse( +std::unique_ptr<DnsResponse> BuildTestDnsServiceResponse( std::string name, std::vector<TestServiceRecord> service_records, std::string answer_name) {
diff --git a/net/dns/dns_test_util.h b/net/dns/dns_test_util.h index f8a990b..95617c7 100644 --- a/net/dns/dns_test_util.h +++ b/net/dns/dns_test_util.h
@@ -161,14 +161,17 @@ class DnsClient; class IPAddress; +// Build a DNS response that includes address records. std::unique_ptr<DnsResponse> BuildTestDnsResponse(std::string name, const IPAddress& ip); -std::unique_ptr<DnsResponse> BuildTestDnsResponse(std::string name, - const IPAddress& ip, - std::string cannonname); +std::unique_ptr<DnsResponse> BuildTestDnsResponseWithCname( + std::string name, + const IPAddress& ip, + std::string cannonname); + // If |answer_name| is empty, |name| will be used for all answer records, as is // the normal behavior. -std::unique_ptr<DnsResponse> BuildTestDnsResponse( +std::unique_ptr<DnsResponse> BuildTestDnsTextResponse( std::string name, std::vector<std::vector<std::string>> text_records, std::string answer_name = ""); @@ -184,7 +187,7 @@ std::string target; }; -std::unique_ptr<DnsResponse> BuildTestDnsResponse( +std::unique_ptr<DnsResponse> BuildTestDnsServiceResponse( std::string name, std::vector<TestServiceRecord> service_records, std::string answer_name = "");
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc index 5a0110a..70f8a6d6 100644 --- a/net/dns/host_resolver_manager_unittest.cc +++ b/net/dns/host_resolver_manager_unittest.cc
@@ -3072,7 +3072,7 @@ bool delay) { rules->emplace_back( prefix, qtype, SecureDnsMode::AUTOMATIC, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsResponseWithCname( prefix, std::move(result_ip), std::move(cannonname))), delay); } @@ -5140,8 +5140,8 @@ MockDnsClientRuleList rules; rules.emplace_back("host", dns_protocol::kTypeTXT, SecureDnsMode::AUTOMATIC, - MockDnsClientRule::Result( - BuildTestDnsResponse("host", std::move(text_records))), + MockDnsClientRule::Result(BuildTestDnsTextResponse( + "host", std::move(text_records))), false /* delay */); CreateResolver(); @@ -5298,7 +5298,7 @@ std::vector<std::vector<std::string>> text_records = {{"text"}}; MockDnsClientRuleList rules; rules.emplace_back("host", dns_protocol::kTypeTXT, SecureDnsMode::AUTOMATIC, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsTextResponse( "host", std::move(text_records), "not.host")), false /* delay */); @@ -5352,8 +5352,8 @@ MockDnsClientRuleList rules; rules.emplace_back("host", dns_protocol::kTypeTXT, SecureDnsMode::AUTOMATIC, - MockDnsClientRule::Result( - BuildTestDnsResponse("host", std::move(text_records))), + MockDnsClientRule::Result(BuildTestDnsTextResponse( + "host", std::move(text_records))), false /* delay */); CreateResolver(); @@ -5640,7 +5640,7 @@ const TestServiceRecord kRecord4 = {2, 100, 12345, "chromium.org"}; MockDnsClientRuleList rules; rules.emplace_back("host", dns_protocol::kTypeSRV, SecureDnsMode::AUTOMATIC, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsServiceResponse( "host", {kRecord1, kRecord2, kRecord3, kRecord4})), false /* delay */); @@ -5683,8 +5683,8 @@ const TestServiceRecord kRecord2 = {5, 0, 5, "google.com"}; MockDnsClientRuleList rules; rules.emplace_back("host", dns_protocol::kTypeSRV, SecureDnsMode::AUTOMATIC, - MockDnsClientRule::Result( - BuildTestDnsResponse("host", {kRecord1, kRecord2})), + MockDnsClientRule::Result(BuildTestDnsServiceResponse( + "host", {kRecord1, kRecord2})), false /* delay */); CreateResolver(); @@ -5834,7 +5834,7 @@ std::vector<TestServiceRecord> srv_records = {{1, 2, 3, "foo.com"}}; MockDnsClientRuleList rules; rules.emplace_back("host", dns_protocol::kTypeSRV, SecureDnsMode::AUTOMATIC, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsServiceResponse( "host", std::move(srv_records), "not.host")), false /* delay */); @@ -5886,7 +5886,7 @@ const TestServiceRecord kRecord4 = {2, 100, 12345, "chromium.org"}; MockDnsClientRuleList rules; rules.emplace_back("host", dns_protocol::kTypeSRV, SecureDnsMode::AUTOMATIC, - MockDnsClientRule::Result(BuildTestDnsResponse( + MockDnsClientRule::Result(BuildTestDnsServiceResponse( "host", {kRecord1, kRecord2, kRecord3, kRecord4})), false /* delay */);
diff --git a/net/ssl/ssl_platform_key_mac.cc b/net/ssl/ssl_platform_key_mac.cc index 4a2fc356..b08e4d1 100644 --- a/net/ssl/ssl_platform_key_mac.cc +++ b/net/ssl/ssl_platform_key_mac.cc
@@ -52,21 +52,6 @@ namespace { -// TODO(davidben): Remove this when we switch to building to the 10.13 -// SDK. https://crbug.com/780980 -#if !defined(MAC_OS_X_VERSION_10_13) || \ - MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_13 -API_AVAILABLE(macosx(10.13)) -const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA256 = - CFSTR("algid:sign:RSA:digest-PSS:SHA256:SHA256:32"); -API_AVAILABLE(macosx(10.13)) -const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA384 = - CFSTR("algid:sign:RSA:digest-PSS:SHA384:SHA384:48"); -API_AVAILABLE(macosx(10.13)) -const SecKeyAlgorithm kSecKeyAlgorithmRSASignatureDigestPSSSHA512 = - CFSTR("algid:sign:RSA:digest-PSS:SHA512:SHA512:64"); -#endif - base::Optional<std::vector<uint8_t>> AddPSSPadding( EVP_PKEY* pubkey, const EVP_MD* md,
diff --git a/services/device/generic_sensor/platform_sensor_and_provider_unittest_linux.cc b/services/device/generic_sensor/platform_sensor_and_provider_unittest_linux.cc index baceb52..60747bf 100644 --- a/services/device/generic_sensor/platform_sensor_and_provider_unittest_linux.cc +++ b/services/device/generic_sensor/platform_sensor_and_provider_unittest_linux.cc
@@ -7,10 +7,10 @@ #include "base/bind.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "services/device/generic_sensor/generic_sensor_consts.h" @@ -143,7 +143,8 @@ public: void SetUp() override { provider_ = PlatformSensorProviderLinux::GetInstance(); - provider_->SetFileTaskRunnerForTesting(message_loop_.task_runner()); + provider_->SetFileTaskRunnerForTesting( + scoped_task_environment_.GetMainThreadTaskRunner()); auto manager = std::make_unique<NiceMock<MockSensorDeviceManager>>(); manager_ = manager.get(); @@ -302,9 +303,10 @@ ASSERT_TRUE(success); } + base::test::ScopedTaskEnvironment scoped_task_environment_; + MockSensorDeviceManager* manager_; scoped_refptr<PlatformSensor> platform_sensor_; - base::MessageLoop message_loop_; std::unique_ptr<base::RunLoop> run_loop_; PlatformSensorProviderLinux* provider_; // Holds base dir where a sensor dir is located.
diff --git a/services/network/host_resolver_unittest.cc b/services/network/host_resolver_unittest.cc index 430f357..4b920d05 100644 --- a/services/network/host_resolver_unittest.cc +++ b/services/network/host_resolver_unittest.cc
@@ -1137,7 +1137,7 @@ net::MockDnsClientRuleList rules; rules.emplace_back( "example.com", net::dns_protocol::kTypeTXT, net::SecureDnsMode::AUTOMATIC, - net::MockDnsClientRule::Result(net::BuildTestDnsResponse( + net::MockDnsClientRule::Result(net::BuildTestDnsTextResponse( "example.com", {std::vector<std::string>(std::begin(kTextRecords), std::end(kTextRecords))})), false /* delay */);
diff --git a/services/network/network_service_proxy_delegate.cc b/services/network/network_service_proxy_delegate.cc index 9bb15f7..9b4afc2 100644 --- a/services/network/network_service_proxy_delegate.cc +++ b/services/network/network_service_proxy_delegate.cc
@@ -21,28 +21,6 @@ // The maximum number of previous configs to keep. constexpr size_t kMaxPreviousConfigs = 2; -void GetAlternativeProxy(const GURL& url, - const net::ProxyRetryInfoMap& proxy_retry_info, - net::ProxyInfo* result) { - net::ProxyServer resolved_proxy_server = result->proxy_server(); - DCHECK(resolved_proxy_server.is_valid()); - - // Right now, HTTPS proxies are assumed to support quic. If this needs to - // change, add a setting in CustomProxyConfig to control this behavior. - if (!resolved_proxy_server.is_https()) - return; - - net::ProxyInfo alternative_proxy_info; - alternative_proxy_info.UseProxyServer(net::ProxyServer( - net::ProxyServer::SCHEME_QUIC, resolved_proxy_server.host_port_pair())); - alternative_proxy_info.DeprioritizeBadProxies(proxy_retry_info); - - if (alternative_proxy_info.is_empty()) - return; - - result->SetAlternativeProxy(alternative_proxy_info.proxy_server()); -} - bool ApplyProxyConfigToProxyInfo(const net::ProxyConfig::ProxyRules& rules, const net::ProxyRetryInfoMap& proxy_retry_info, const GURL& url, @@ -205,7 +183,7 @@ url, &proxy_info)) { DCHECK(!proxy_info.is_empty() && !proxy_info.is_direct()); result->OverrideProxyList(proxy_info.proxy_list()); - GetAlternativeProxy(url, proxy_retry_info, result); + GetAlternativeProxy(proxy_retry_info, result); } } @@ -320,4 +298,26 @@ : proxy_config_->rules; } +void NetworkServiceProxyDelegate::GetAlternativeProxy( + const net::ProxyRetryInfoMap& proxy_retry_info, + net::ProxyInfo* result) { + net::ProxyServer resolved_proxy_server = result->proxy_server(); + DCHECK(resolved_proxy_server.is_valid()); + + if (!resolved_proxy_server.is_https() || + !proxy_config_->assume_https_proxies_support_quic) { + return; + } + + net::ProxyInfo alternative_proxy_info; + alternative_proxy_info.UseProxyServer(net::ProxyServer( + net::ProxyServer::SCHEME_QUIC, resolved_proxy_server.host_port_pair())); + alternative_proxy_info.DeprioritizeBadProxies(proxy_retry_info); + + if (alternative_proxy_info.is_empty()) + return; + + result->SetAlternativeProxy(alternative_proxy_info.proxy_server()); +} + } // namespace network
diff --git a/services/network/network_service_proxy_delegate.h b/services/network/network_service_proxy_delegate.h index a14abdc0..4e9e74e 100644 --- a/services/network/network_service_proxy_delegate.h +++ b/services/network/network_service_proxy_delegate.h
@@ -78,6 +78,10 @@ // Get the proxy rules that apply to |url|. net::ProxyConfig::ProxyRules GetProxyRulesForURL(const GURL& url) const; + // Fills the alternative proxy config in |result| if applicable. + void GetAlternativeProxy(const net::ProxyRetryInfoMap& proxy_retry_info, + net::ProxyInfo* result); + // mojom::CustomProxyConfigClient implementation: void OnCustomProxyConfigUpdated( mojom::CustomProxyConfigPtr proxy_config) override;
diff --git a/services/network/network_service_proxy_delegate_unittest.cc b/services/network/network_service_proxy_delegate_unittest.cc index 404028f0..5a30ebd 100644 --- a/services/network/network_service_proxy_delegate_unittest.cc +++ b/services/network/network_service_proxy_delegate_unittest.cc
@@ -336,6 +336,7 @@ TEST_F(NetworkServiceProxyDelegateTest, OnResolveProxySuccessHttpsProxy) { auto config = mojom::CustomProxyConfig::New(); config->rules.ParseFromString("http=https://foo"); + config->assume_https_proxies_support_quic = true; auto delegate = CreateDelegate(std::move(config)); net::ProxyInfo result; @@ -351,6 +352,20 @@ net::ProxyServer::FromPacString("QUIC foo")); } +TEST_F(NetworkServiceProxyDelegateTest, OnResolveProxySuccessHttpsProxyNoQuic) { + auto config = mojom::CustomProxyConfig::New(); + config->rules.ParseFromString("http=https://foo"); + config->assume_https_proxies_support_quic = false; + auto delegate = CreateDelegate(std::move(config)); + + net::ProxyInfo result; + result.UseDirect(); + delegate->OnResolveProxy(GURL(kHttpUrl), "GET", net::ProxyRetryInfoMap(), + &result); + + EXPECT_FALSE(result.alternative_proxy().is_valid()); +} + TEST_F(NetworkServiceProxyDelegateTest, OnResolveProxySuccessHttpsUrl) { auto config = mojom::CustomProxyConfig::New(); config->rules.ParseFromString("https://foo");
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 8ad776b..49057dc 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -67,6 +67,12 @@ // case properly. bool allow_non_idempotent_methods = false; + // Whether every HTTPS proxy in the custom proxy config can be assumed to + // also support QUIC. If this is true, the network service will try to + // establish an alternative QUIC stream to the proxy in parallel to the HTTPS + // stream in an attempt to use QUIC if possible. + bool assume_https_proxies_support_quic = false; + // The custom proxy can set these headers in this config which will be added // to all requests using the proxy. This allows setting headers that may be // privacy/security sensitive which we don't want to send to the renderer.
diff --git a/services/shape_detection/android/java/src/org/chromium/shape_detection/BarcodeDetectionImpl.java b/services/shape_detection/android/java/src/org/chromium/shape_detection/BarcodeDetectionImpl.java index 2d34df7..5d7a90e 100644 --- a/services/shape_detection/android/java/src/org/chromium/shape_detection/BarcodeDetectionImpl.java +++ b/services/shape_detection/android/java/src/org/chromium/shape_detection/BarcodeDetectionImpl.java
@@ -20,6 +20,7 @@ import org.chromium.shape_detection.mojom.BarcodeDetection; import org.chromium.shape_detection.mojom.BarcodeDetectionResult; import org.chromium.shape_detection.mojom.BarcodeDetectorOptions; +import org.chromium.shape_detection.mojom.BarcodeFormat; /** * Implementation of mojo BarcodeDetection, using Google Play Services vision package. @@ -76,6 +77,7 @@ barcodeArray[i].cornerPoints[j].x = corners[j].x; barcodeArray[i].cornerPoints[j].y = corners[j].y; } + barcodeArray[i].format = toBarcodeFormat(barcode.format); } callback.call(barcodeArray); } @@ -89,4 +91,36 @@ public void onConnectionError(MojoException e) { close(); } + + private int toBarcodeFormat(int format) { + switch (format) { + case Barcode.CODE_128: + return BarcodeFormat.CODE_128; + case Barcode.CODE_39: + return BarcodeFormat.CODE_39; + case Barcode.CODE_93: + return BarcodeFormat.CODE_93; + case Barcode.CODABAR: + return BarcodeFormat.CODABAR; + case Barcode.DATA_MATRIX: + return BarcodeFormat.DATA_MATRIX; + case Barcode.EAN_13: + return BarcodeFormat.EAN_13; + case Barcode.EAN_8: + return BarcodeFormat.CODE_128; + case Barcode.ITF: + return BarcodeFormat.EAN_8; + case Barcode.QR_CODE: + return BarcodeFormat.QR_CODE; + case Barcode.UPC_A: + return BarcodeFormat.UPC_A; + case Barcode.UPC_E: + return BarcodeFormat.UPC_E; + case Barcode.PDF417: + return BarcodeFormat.PDF417; + case Barcode.AZTEC: + return BarcodeFormat.AZTEC; + } + return BarcodeFormat.UNKNOWN; + } }
diff --git a/services/shape_detection/android/javatests/src/org/chromium/shape_detection/BarcodeDetectionImplTest.java b/services/shape_detection/android/javatests/src/org/chromium/shape_detection/BarcodeDetectionImplTest.java index 5b21176..19708ad 100644 --- a/services/shape_detection/android/javatests/src/org/chromium/shape_detection/BarcodeDetectionImplTest.java +++ b/services/shape_detection/android/javatests/src/org/chromium/shape_detection/BarcodeDetectionImplTest.java
@@ -101,5 +101,6 @@ Assert.assertEquals(40.0, results[0].boundingBox.y, 0.0); Assert.assertEquals(250.0, results[0].boundingBox.width, 0.0); Assert.assertEquals(250.0, results[0].boundingBox.height, 0.0); + Assert.assertEquals(BarcodeFormat.QR_CODE, results[0].format); } }
diff --git a/services/shape_detection/barcode_detection_impl_mac.mm b/services/shape_detection/barcode_detection_impl_mac.mm index f5d764d4c..7a85af56 100644 --- a/services/shape_detection/barcode_detection_impl_mac.mm +++ b/services/shape_detection/barcode_detection_impl_mac.mm
@@ -47,6 +47,7 @@ result->corner_points.emplace_back(f.bottomLeft.x, height - f.bottomLeft.y); result->raw_value = base::SysNSStringToUTF8(f.messageString); + result->format = mojom::BarcodeFormat::QR_CODE; results.push_back(std::move(result)); } std::move(callback).Run(std::move(results));
diff --git a/services/shape_detection/barcode_detection_impl_mac_unittest.mm b/services/shape_detection/barcode_detection_impl_mac_unittest.mm index de36065d..9420444d 100644 --- a/services/shape_detection/barcode_detection_impl_mac_unittest.mm +++ b/services/shape_detection/barcode_detection_impl_mac_unittest.mm
@@ -71,24 +71,26 @@ struct TestParams { size_t num_barcodes; + mojom::BarcodeFormat symbology; LibraryLoadCB library_load_callback; BarcodeDetectorFactory factory; NSString* test_code_generator; } kTestParams[] = { // CoreImage only supports QR Codes. - {1, base::BindRepeating([]() { return static_cast<void*>(nullptr); }), + {1, mojom::BarcodeFormat::QR_CODE, + base::BindRepeating([]() { return static_cast<void*>(nullptr); }), base::BindRepeating(&CreateBarcodeDetectorImplMacCoreImage), @"CIQRCodeGenerator"}, // Vision only supports a number of 1D/2D codes. Not all of them are // available for generation, though, only a few. - {1, base::BindRepeating(&LoadVisionLibrary), + {1, mojom::BarcodeFormat::PDF417, base::BindRepeating(&LoadVisionLibrary), base::BindRepeating(&CreateBarcodeDetectorImplMacVision), @"CIPDF417BarcodeGenerator"}, - {1, base::BindRepeating(&LoadVisionLibrary), + {1, mojom::BarcodeFormat::QR_CODE, base::BindRepeating(&LoadVisionLibrary), base::BindRepeating(&CreateBarcodeDetectorImplMacVision), @"CIQRCodeGenerator"}, {6 /* 1D barcode makes the detector find the same code several times. */, - base::BindRepeating(&LoadVisionLibrary), + mojom::BarcodeFormat::CODE_128, base::BindRepeating(&LoadVisionLibrary), base::BindRepeating(&CreateBarcodeDetectorImplMacVision), @"CICode128BarcodeGenerator"}}; } @@ -107,11 +109,14 @@ } void DetectCallback(size_t num_barcodes, + mojom::BarcodeFormat symbology, const std::string& barcode_value, std::vector<mojom::BarcodeDetectionResultPtr> results) { EXPECT_EQ(num_barcodes, results.size()); - for (const auto& barcode : results) + for (const auto& barcode : results) { EXPECT_EQ(barcode_value, barcode->raw_value); + EXPECT_EQ(symbology, barcode->format); + } Detection(); } @@ -141,7 +146,7 @@ } } -// This test generates a single QR code and scans it back. +// This test generates a single barcode and scans it back. TEST_P(BarcodeDetectionImplMacTest, ScanOneBarcode) { // Barcode detection needs at least MAC OS X 10.10, and GPU infrastructure. if (!base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -156,7 +161,7 @@ return; } - // Generate a QR code image as a CIImage by using |qr_code_generator|. + // Generate a barcode image as a CIImage by using |qr_code_generator|. NSData* const qr_code_data = [[NSString stringWithUTF8String:kInfoString.c_str()] dataUsingEncoding:NSISOLatin1StringEncoding]; @@ -188,10 +193,11 @@ base::Closure quit_closure = run_loop.QuitClosure(); // Send the image Detect() and expect the response in callback. EXPECT_CALL(*this, Detection()).WillOnce(RunClosure(quit_closure)); + // TODO(crbug.com/938663): expect detected symbology. impl_->Detect(bitmap, base::BindOnce(&BarcodeDetectionImplMacTest::DetectCallback, base::Unretained(this), GetParam().num_barcodes, - kInfoString)); + GetParam().symbology, kInfoString)); run_loop.Run(); }
diff --git a/services/shape_detection/barcode_detection_impl_mac_vision.mm b/services/shape_detection/barcode_detection_impl_mac_vision.mm index 4cee365..d6c5f68 100644 --- a/services/shape_detection/barcode_detection_impl_mac_vision.mm +++ b/services/shape_detection/barcode_detection_impl_mac_vision.mm
@@ -15,6 +15,36 @@ namespace shape_detection { +namespace { + +mojom::BarcodeFormat ToBarcodeFormat(NSString* symbology) { + if ([symbology isEqual:@"VNBarcodeSymbologyAztec"]) + return mojom::BarcodeFormat::AZTEC; + if ([symbology isEqual:@"VNBarcodeSymbologyCode128"]) + return mojom::BarcodeFormat::CODE_128; + if ([symbology isEqual:@"VNBarcodeSymbologyCode39"]) + return mojom::BarcodeFormat::CODE_39; + if ([symbology isEqual:@"VNBarcodeSymbologyCode93"]) + return mojom::BarcodeFormat::CODE_93; + if ([symbology isEqual:@"VNBarcodeSymbologyDataMatrix"]) + return mojom::BarcodeFormat::DATA_MATRIX; + if ([symbology isEqual:@"VNBarcodeSymbologyEAN13"]) + return mojom::BarcodeFormat::EAN_13; + if ([symbology isEqual:@"VNBarcodeSymbologyEAN8"]) + return mojom::BarcodeFormat::EAN_8; + if ([symbology isEqual:@"VNBarcodeSymbologyITF14"]) + return mojom::BarcodeFormat::ITF; + if ([symbology isEqual:@"VNBarcodeSymbologyPDF417"]) + return mojom::BarcodeFormat::PDF417; + if ([symbology isEqual:@"VNBarcodeSymbologyQR"]) + return mojom::BarcodeFormat::QR_CODE; + if ([symbology isEqual:@"VNBarcodeSymbologyUPCE"]) + return mojom::BarcodeFormat::UPC_E; + return mojom::BarcodeFormat::UNKNOWN; +} + +} // unnamed namespace + BarcodeDetectionImplMacVision::BarcodeDetectionImplMacVision( mojom::BarcodeDetectorOptionsPtr options) : weak_factory_(this) { @@ -91,6 +121,8 @@ barcode->raw_value = base::SysNSStringToUTF8(observation.payloadStringValue); + barcode->format = ToBarcodeFormat(observation.symbology); + results.push_back(std::move(barcode)); } std::move(detected_callback_).Run(std::move(results));
diff --git a/services/shape_detection/public/mojom/barcodedetection.mojom b/services/shape_detection/public/mojom/barcodedetection.mojom index 5ae9aef5..3d72a11 100644 --- a/services/shape_detection/public/mojom/barcodedetection.mojom +++ b/services/shape_detection/public/mojom/barcodedetection.mojom
@@ -9,11 +9,30 @@ import "skia/public/interfaces/bitmap.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; +// https://wicg.github.io/shape-detection-api/#barcodeformat-section +enum BarcodeFormat { + AZTEC, + CODE_128, + CODE_39, + CODE_93, + CODABAR, + DATA_MATRIX, + EAN_13, + EAN_8, + ITF, + PDF417, + QR_CODE, + UNKNOWN, + UPC_A, + UPC_E +}; + struct BarcodeDetectionResult { // Barcode or QR extracted contents (see e.g. // https://github.com/zxing/zxing/wiki/Barcode-Contents). string raw_value; gfx.mojom.RectF bounding_box; + BarcodeFormat format; array<gfx.mojom.PointF> corner_points; };
diff --git a/services/shape_detection/public/mojom/barcodedetection_provider.mojom b/services/shape_detection/public/mojom/barcodedetection_provider.mojom index 20c57e5b..65937d3 100644 --- a/services/shape_detection/public/mojom/barcodedetection_provider.mojom +++ b/services/shape_detection/public/mojom/barcodedetection_provider.mojom
@@ -8,24 +8,6 @@ import "services/shape_detection/public/mojom/barcodedetection.mojom"; -// https://wicg.github.io/shape-detection-api/#barcodeformat-section -enum BarcodeFormat { - AZTEC, - CODE_128, - CODE_39, - CODE_93, - CODABAR, - DATA_MATRIX, - EAN_13, - EAN_8, - ITF, - PDF417, - QR_CODE, - UNKNOWN, - UPC_A, - UPC_E -}; - // https://wicg.github.io/shape-detection-api/#barcodedetectoroptions-section struct BarcodeDetectorOptions { array<BarcodeFormat> formats;
diff --git a/services/ws/client_root.cc b/services/ws/client_root.cc index 26431c5..aa31543 100644 --- a/services/ws/client_root.cc +++ b/services/ws/client_root.cc
@@ -173,7 +173,10 @@ UpdateLocalSurfaceIdAndClientSurfaceEmbedder(); const bool succeeded = bounds == GetBoundsToSend(window_); - if (!succeeded) + // The bounds and id form a unique pair, so that if either differ from what + // the client requested, the client needs to be notified by way of + // NotifyClientOfNewBounds(). + if (!succeeded || needs_new_surface_id) NotifyClientOfNewBounds(); return succeeded; }
diff --git a/services/ws/window_tree_unittest.cc b/services/ws/window_tree_unittest.cc index fc0a0665..a6f09aec 100644 --- a/services/ws/window_tree_unittest.cc +++ b/services/ws/window_tree_unittest.cc
@@ -383,7 +383,15 @@ // from the client. EXPECT_TRUE( setup.window_tree_test_helper()->SetWindowBounds(top_level, bounds)); - EXPECT_TRUE(setup.changes()->empty()); + // The server always responds with a bounds change when the client changes the + // bounds and does not supply a LocalSurfaceId. + ASSERT_FALSE(setup.changes()->empty()); + const auto& change = (*setup.changes())[0]; + EXPECT_EQ(CHANGE_TYPE_NODE_BOUNDS_CHANGED, change.type); + EXPECT_EQ(setup.window_tree_test_helper()->TransportIdForWindow(top_level), + change.window_id); + EXPECT_TRUE(change.local_surface_id_allocation); + EXPECT_EQ(bounds, change.bounds); } TEST(WindowTreeTest, SetChildWindowBounds) {
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 63b40c7..22faeb31 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -699,7 +699,7 @@ { "cipd_package": "chromium/android_webview/tools/cts_archive", "location": "android_webview/tools/cts_archive", - "revision": "version:1.1" + "revision": "version:1.4" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 433b169..5d31a8f 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -544,17 +544,33 @@ ] }, "Android WebView L (dbg)": { - "isolated_scripts": [ + "gtest_tests": [ { - "isolate_name": "webview_cts_tests", - "name": "webview_cts_tests", + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "webview_cts_tests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/android_webview/tools/cts_archive", "location": "android_webview/tools/cts_archive", - "revision": "version:1.1" + "revision": "version:1.4" + }, + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" } ], "dimension_sets": [ @@ -564,8 +580,19 @@ "os": "Android" } ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], "shards": 3 - } + }, + "test": "webview_cts_tests" } ] },
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 4df045a8..432616c 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -288,33 +288,6 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d11 --use-cmd-decoder=validating", - "--webgl-conformance-version=2.0.1", - "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl2_conformance_d3d11_validating_tests", - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:5912-24.20.100.6286", - "os": "Windows-10", - "pool": "Chrome-GPU" - } - ], - "idempotent": false, - "shards": 20 - } - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=release", - "--passthrough", - "-v", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough", "--webgl-conformance-version=2.0.1", "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" @@ -369,31 +342,6 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=d3d11 --use-cmd-decoder=validating" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl_conformance_d3d11_validating_tests", - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:5912-24.20.100.6286", - "os": "Windows-10", - "pool": "Chrome-GPU" - } - ], - "idempotent": false, - "shards": 6 - } - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=release", - "--passthrough", - "-v", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9 --use-cmd-decoder=passthrough" ], "isolate_name": "telemetry_gpu_integration_test", @@ -419,10 +367,10 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=d3d9 --use-cmd-decoder=validating" + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough" ], "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl_conformance_d3d9_validating_tests", + "name": "webgl_conformance_gl_passthrough_tests", "should_retry_with_patch": false, "swarming": { "can_use_on_swarming_builders": true, @@ -434,7 +382,7 @@ } ], "idempotent": false, - "shards": 6 + "shards": 2 } }, { @@ -444,10 +392,10 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough" + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl_conformance_gl_passthrough_tests", + "name": "webgl_conformance_tests", "should_retry_with_patch": false, "swarming": { "can_use_on_swarming_builders": true, @@ -17177,31 +17125,6 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d11 --use-cmd-decoder=validating" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl_conformance_d3d11_validating_tests", - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:5912-24.20.100.6286", - "os": "Windows-10", - "pool": "Chrome-GPU" - } - ], - "idempotent": false, - "shards": 2 - } - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=release", - "--passthrough", - "-v", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9 --use-cmd-decoder=passthrough" ], "isolate_name": "telemetry_gpu_integration_test", @@ -17227,10 +17150,10 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=d3d9 --use-cmd-decoder=validating" + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough" ], "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl_conformance_d3d9_validating_tests", + "name": "webgl_conformance_gl_passthrough_tests", "should_retry_with_patch": false, "swarming": { "can_use_on_swarming_builders": true, @@ -17242,7 +17165,7 @@ } ], "idempotent": false, - "shards": 6 + "shards": 2 } }, { @@ -17252,10 +17175,10 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough" + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl_conformance_gl_passthrough_tests", + "name": "webgl_conformance_tests", "should_retry_with_patch": false, "swarming": { "can_use_on_swarming_builders": true, @@ -19273,34 +19196,6 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d11 --use-cmd-decoder=validating", - "--webgl-conformance-version=2.0.1", - "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl2_conformance_d3d11_validating_tests", - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:5912-24.20.100.6286", - "os": "Windows-10", - "pool": "Chrome-GPU" - } - ], - "expiration": 21600, - "idempotent": false, - "shards": 20 - } - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=release", - "--passthrough", - "-v", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough", "--webgl-conformance-version=2.0.1", "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" @@ -19357,32 +19252,6 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d11 --use-cmd-decoder=validating" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl_conformance_d3d11_validating_tests", - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:5912-24.20.100.6286", - "os": "Windows-10", - "pool": "Chrome-GPU" - } - ], - "expiration": 21600, - "idempotent": false, - "shards": 2 - } - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=release", - "--passthrough", - "-v", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9 --use-cmd-decoder=passthrough" ], "isolate_name": "telemetry_gpu_integration_test", @@ -19409,32 +19278,6 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=d3d9 --use-cmd-decoder=validating" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl_conformance_d3d9_validating_tests", - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:5912-24.20.100.6286", - "os": "Windows-10", - "pool": "Chrome-GPU" - } - ], - "expiration": 21600, - "idempotent": false, - "shards": 6 - } - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=release", - "--passthrough", - "-v", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough" ], "isolate_name": "telemetry_gpu_integration_test", @@ -20130,33 +19973,6 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d11 --use-cmd-decoder=validating", - "--webgl-conformance-version=2.0.1", - "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl2_conformance_d3d11_validating_tests", - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:5912-24.20.100.6286", - "os": "Windows-10", - "pool": "Chrome-GPU" - } - ], - "idempotent": false, - "shards": 20 - } - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=release", - "--passthrough", - "-v", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough", "--webgl-conformance-version=2.0.1", "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" @@ -20211,31 +20027,6 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d11 --use-cmd-decoder=validating" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl_conformance_d3d11_validating_tests", - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:5912-24.20.100.6286", - "os": "Windows-10", - "pool": "Chrome-GPU" - } - ], - "idempotent": false, - "shards": 2 - } - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=release", - "--passthrough", - "-v", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9 --use-cmd-decoder=passthrough" ], "isolate_name": "telemetry_gpu_integration_test", @@ -20261,31 +20052,6 @@ "--browser=release", "--passthrough", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=d3d9 --use-cmd-decoder=validating" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl_conformance_d3d9_validating_tests", - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:5912-24.20.100.6286", - "os": "Windows-10", - "pool": "Chrome-GPU" - } - ], - "idempotent": false, - "shards": 6 - } - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=release", - "--passthrough", - "-v", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough" ], "isolate_name": "telemetry_gpu_integration_test",
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 71c39200..64f7b38 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -3261,6 +3261,27 @@ }, }, + 'gpu_fyi_and_optional_win_intel_specific_gpu_telemetry_tests': { + 'webgl_conformance_d3d9_passthrough': { + 'telemetry_test_name': 'webgl_conformance', + 'args': [ + '--extra-browser-args=--use-angle=d3d9 --use-cmd-decoder=passthrough', + ], + 'swarming': { + 'shards': 2, + }, + }, + 'webgl_conformance_vulkan_passthrough': { + 'telemetry_test_name': 'webgl_conformance', + 'args': [ + '--extra-browser-args=--use-angle=vulkan --use-cmd-decoder=passthrough', + ], + 'swarming': { + 'shards': 2, + }, + }, + }, + 'gpu_fyi_and_optional_win_specific_gtests': { 'angle_gles1_conformance_tests': { 'args': ['--use-gpu-in-tests'] @@ -3326,25 +3347,6 @@ }, }, - 'gpu_fyi_only_win_intel_and_nvidia_release_specific_telemetry_tests': { - 'webgl2_conformance_d3d11_validating_tests': { - 'args': [ - '--webgl-conformance-version=2.0.1', - # The current working directory when run via isolate is - # out/Debug or out/Release. Reference this file relatively to - # it. - '--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json', - '--extra-browser-args=--use-angle=d3d11 --use-cmd-decoder=validating', - ], - 'telemetry_test_name': 'webgl_conformance', - 'swarming': { - # These tests currently take about an hour and fifteen minutes - # to run. Split them into roughly 5-minute shards. - 'shards': 20, - }, - }, - }, - 'gpu_fyi_only_win_linux_intel_nvidia_specific_telemetry_tests': { 'webgl2_conformance_gl_passthrough_tests': { 'telemetry_test_name': 'webgl_conformance', @@ -3364,6 +3366,25 @@ }, }, + 'gpu_fyi_only_win_nvidia_release_specific_telemetry_tests': { + 'webgl2_conformance_d3d11_validating_tests': { + 'args': [ + '--webgl-conformance-version=2.0.1', + # The current working directory when run via isolate is + # out/Debug or out/Release. Reference this file relatively to + # it. + '--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json', + '--extra-browser-args=--use-angle=d3d11 --use-cmd-decoder=validating', + ], + 'telemetry_test_name': 'webgl_conformance', + 'swarming': { + # These tests currently take about an hour and fifteen minutes + # to run. Split them into roughly 5-minute shards. + 'shards': 20, + }, + }, + }, + 'gpu_fyi_optional_and_v8_desktop_release_specific_telemetry_tests': { 'webgl2_conformance_tests': { 'telemetry_test_name': 'webgl_conformance', @@ -3434,6 +3455,14 @@ } }, + 'gpu_optional_and_angle_win_intel_specific_gpu_telemetry_tests': { + 'webgl_conformance': { + 'swarming': { + 'shards': 2, + }, + }, + }, + 'gpu_telemetry_tests': { 'context_lost': {}, 'depth_capture': {}, @@ -4434,24 +4463,7 @@ { "cipd_package": 'chromium/android_webview/tools/cts_archive', 'location': 'android_webview/tools/cts_archive', - 'revision': 'version:1.1', - } - ] - }, - }, - }, - - # TODO(crbug.com/907899): Migrate all uses of the isolated_script version - # of the CTS test suite to the gtest version. - 'webview_cts_tests_isolated_scripts': { - 'webview_cts_tests': { - 'swarming': { - 'shards': 3, - 'cipd_packages': [ - { - "cipd_package": 'chromium/android_webview/tools/cts_archive', - 'location': 'android_webview/tools/cts_archive', - 'revision': 'version:1.1', + 'revision': 'version:1.4', } ] }, @@ -4746,11 +4758,20 @@ 'gpu_win_specific_gtests', ], - 'gpu_angle_win_intel_and_nvidia_telemetry_tests': [ + 'gpu_angle_win_intel_telemetry_tests': [ + 'gpu_common_and_optional_telemetry_tests', + 'gpu_fyi_and_optional_win_intel_specific_gpu_telemetry_tests', + 'gpu_fyi_and_optional_win_and_linux_specific_telemetry_tests', + 'gpu_fyi_only_win_linux_intel_nvidia_specific_telemetry_tests', + 'gpu_fyi_optional_and_v8_desktop_release_specific_telemetry_tests', + 'gpu_optional_and_angle_win_intel_specific_gpu_telemetry_tests', + ], + + 'gpu_angle_win_nvidia_telemetry_tests': [ 'gpu_common_and_optional_telemetry_tests', 'gpu_fyi_and_optional_and_win_angle_amd_win_specific_gpu_telemetry_tests', 'gpu_fyi_and_optional_win_and_linux_specific_telemetry_tests', - 'gpu_fyi_only_win_intel_and_nvidia_release_specific_telemetry_tests', + 'gpu_fyi_only_win_nvidia_release_specific_telemetry_tests', 'gpu_fyi_only_win_linux_intel_nvidia_specific_telemetry_tests', 'gpu_fyi_optional_and_v8_desktop_release_specific_telemetry_tests', 'gpu_webgl_conformance_d3d11_validating_tests', @@ -4932,13 +4953,11 @@ 'gpu_fyi_win_intel_release_telemetry_tests': [ 'gpu_common_and_optional_telemetry_tests', - 'gpu_fyi_and_optional_and_win_angle_amd_win_specific_gpu_telemetry_tests', + 'gpu_fyi_and_optional_win_intel_specific_gpu_telemetry_tests', 'gpu_fyi_and_optional_win_and_linux_specific_telemetry_tests', - 'gpu_fyi_only_win_intel_and_nvidia_release_specific_telemetry_tests', 'gpu_fyi_only_win_linux_intel_nvidia_specific_telemetry_tests', 'gpu_fyi_optional_and_v8_desktop_release_specific_telemetry_tests', 'gpu_telemetry_tests', - 'gpu_webgl_conformance_d3d9_validating_tests', 'gpu_win_intel_specific_telemetry_tests', ], @@ -4956,7 +4975,7 @@ 'gpu_common_and_optional_telemetry_tests', 'gpu_fyi_and_optional_and_win_angle_amd_win_specific_gpu_telemetry_tests', 'gpu_fyi_and_optional_win_and_linux_specific_telemetry_tests', - 'gpu_fyi_only_win_intel_and_nvidia_release_specific_telemetry_tests', + 'gpu_fyi_only_win_nvidia_release_specific_telemetry_tests', 'gpu_fyi_only_win_linux_intel_nvidia_specific_telemetry_tests', 'gpu_fyi_optional_and_v8_desktop_release_specific_telemetry_tests', 'gpu_telemetry_tests', @@ -4971,11 +4990,11 @@ 'gpu_optional_win_intel_telemetry_tests': [ 'gpu_common_and_optional_telemetry_tests', - 'gpu_fyi_and_optional_and_win_angle_amd_win_specific_gpu_telemetry_tests', + 'gpu_fyi_and_optional_win_intel_specific_gpu_telemetry_tests', 'gpu_fyi_and_optional_win_and_linux_specific_telemetry_tests', 'gpu_fyi_optional_and_v8_desktop_release_specific_telemetry_tests', - 'gpu_webgl_conformance_d3d9_validating_tests', 'gpu_win_intel_specific_telemetry_tests', + 'gpu_optional_and_angle_win_intel_specific_gpu_telemetry_tests', ], 'gpu_optional_win_telemetry_tests': [
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 8547461..f8c703b 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -141,7 +141,7 @@ }, 'Android WebView L (dbg)': { 'test_suites': { - 'isolated_scripts': 'webview_cts_tests_isolated_scripts', + 'gtest_tests': 'webview_cts_tests_gtest', }, 'swarming': { 'dimension_sets': [ @@ -1901,7 +1901,7 @@ 'test_suites': { 'gtest_tests': 'gpu_angle_win_gtests', 'isolated_scripts': 'gpu_angle_perftests', - 'gpu_telemetry_tests': 'gpu_angle_win_intel_and_nvidia_telemetry_tests', + 'gpu_telemetry_tests': 'gpu_angle_win_intel_telemetry_tests', }, }, 'ANGLE GPU Win10 Release (NVIDIA)': { @@ -1913,7 +1913,7 @@ 'test_suites': { 'gtest_tests': 'gpu_angle_win_gtests', 'isolated_scripts': 'gpu_angle_fyi_win_optional_isolated_scripts', - 'gpu_telemetry_tests': 'gpu_angle_win_intel_and_nvidia_telemetry_tests', + 'gpu_telemetry_tests': 'gpu_angle_win_nvidia_telemetry_tests', }, }, # END Fake builder used as mirror targets for ANGLE's GPU tryservers
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 37b6b0b..59462e4 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -208,7 +208,6 @@ "platform/web_canvas_capture_handler.h", "platform/web_client_hints_type.h", "platform/web_coalesced_input_event.h", - "platform/web_color_scheme.h", "platform/web_common.h", "platform/web_computed_ax_tree.h", "platform/web_connection_type.h",
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index d45c565..35d9a79 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -39,6 +39,7 @@ "cache_storage/cache_storage_utils.h", "client_hints/client_hints.h", "common_export.h", + "css/preferred_color_scheme.h", "device_memory/approximated_device_memory.h", "dom_storage/session_storage_namespace_id.h", "download/download_stats.h",
diff --git a/third_party/blink/public/common/css/OWNERS b/third_party/blink/public/common/css/OWNERS new file mode 100644 index 0000000..b5ccf8dc --- /dev/null +++ b/third_party/blink/public/common/css/OWNERS
@@ -0,0 +1,4 @@ +file://third_party/blink/renderer/core/css/OWNERS + +# COMPONENT: Blink>CSS +
diff --git a/third_party/blink/public/platform/web_color_scheme.h b/third_party/blink/public/common/css/preferred_color_scheme.h similarity index 65% rename from third_party/blink/public/platform/web_color_scheme.h rename to third_party/blink/public/common/css/preferred_color_scheme.h index f125105..b86c667e 100644 --- a/third_party/blink/public/platform/web_color_scheme.h +++ b/third_party/blink/public/common/css/preferred_color_scheme.h
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_COLOR_SCHEME_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_COLOR_SCHEME_H_ +#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_CSS_PREFERRED_COLOR_SCHEME_H_ +#define THIRD_PARTY_BLINK_PUBLIC_COMMON_CSS_PREFERRED_COLOR_SCHEME_H_ namespace blink { // Use for passing preferred color scheme from the OS to the renderer. -enum class WebColorScheme { +enum class PreferredColorScheme { kNoPreference, kDark, kLight,
diff --git a/third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom b/third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom index 500a16a..e24f864 100644 --- a/third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom +++ b/third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom
@@ -18,6 +18,10 @@ [Sync] AllowIndexedDB() => (bool result); + // Returns whether the worker is allowed access to CacheStorage. + [Sync] + AllowCacheStorage() => (bool result); + // Returns whether the worker is allowed access to the file system. [Sync] RequestFileSystemAccessSync() => (bool result);
diff --git a/third_party/blink/public/platform/web_application_cache_host.h b/third_party/blink/public/platform/web_application_cache_host.h index d6aa1da..5576c57 100644 --- a/third_party/blink/public/platform/web_application_cache_host.h +++ b/third_party/blink/public/platform/web_application_cache_host.h
@@ -83,12 +83,12 @@ WebURL manifest_url; // Empty if there is no associated cache. double creation_time; double update_time; - long long total_size; + int64_t total_size; CacheInfo() : creation_time(0), update_time(0), total_size(0) {} }; struct ResourceInfo { WebURL url; - long long size; + int64_t size; bool is_master; bool is_manifest; bool is_explicit;
diff --git a/third_party/blink/public/platform/web_content_settings_client.h b/third_party/blink/public/platform/web_content_settings_client.h index d7da22c..39d76ac 100644 --- a/third_party/blink/public/platform/web_content_settings_client.h +++ b/third_party/blink/public/platform/web_content_settings_client.h
@@ -45,6 +45,9 @@ // Controls whether access to Indexed DB are allowed for this frame. virtual bool AllowIndexedDB(const WebSecurityOrigin&) { return true; } + // Controls whether access to CacheStorage is allowed for this frame. + virtual bool AllowCacheStorage(const WebSecurityOrigin&) { return true; } + // Controls whether scripts are allowed to execute for this frame. virtual bool AllowScript(bool enabled_per_settings) { return enabled_per_settings;
diff --git a/third_party/blink/public/platform/web_url_response.h b/third_party/blink/public/platform/web_url_response.h index 55b4cea..00f6bc1 100644 --- a/third_party/blink/public/platform/web_url_response.h +++ b/third_party/blink/public/platform/web_url_response.h
@@ -183,7 +183,7 @@ BLINK_PLATFORM_EXPORT void SetTextEncodingName(const WebString&); BLINK_PLATFORM_EXPORT HTTPVersion HttpVersion() const; - BLINK_PLATFORM_EXPORT void SetHTTPVersion(HTTPVersion); + BLINK_PLATFORM_EXPORT void SetHttpVersion(HTTPVersion); BLINK_PLATFORM_EXPORT int RequestId() const; BLINK_PLATFORM_EXPORT void SetRequestId(int);
diff --git a/third_party/blink/public/web/web_settings.h b/third_party/blink/public/web/web_settings.h index b28241e..66467d9 100644 --- a/third_party/blink/public/web/web_settings.h +++ b/third_party/blink/public/web/web_settings.h
@@ -33,6 +33,7 @@ #include <unicode/uscript.h> +#include "third_party/blink/public/common/css/preferred_color_scheme.h" #include "third_party/blink/public/platform/pointer_properties.h" #include "third_party/blink/public/platform/web_common.h" #include "third_party/blink/public/platform/web_effective_connection_type.h" @@ -288,6 +289,7 @@ virtual void SetLazyImageLoadingDistanceThresholdPx3G(int) = 0; virtual void SetLazyImageLoadingDistanceThresholdPx4G(int) = 0; virtual void SetForceDarkModeEnabled(bool) = 0; + virtual void SetPreferredColorScheme(PreferredColorScheme) = 0; protected: ~WebSettings() = default;
diff --git a/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc b/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc index b9a08e0..129882af 100644 --- a/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc
@@ -112,9 +112,10 @@ retrieved_worlds.clear(); // Start a worker thread and create worlds on that. - std::unique_ptr<WorkerBackingThread> thread = WorkerBackingThread::Create( - ThreadCreationParams(WebThreadType::kTestThread) - .SetThreadNameForTest("DOMWrapperWorld test thread")); + std::unique_ptr<WorkerBackingThread> thread = + std::make_unique<WorkerBackingThread>( + ThreadCreationParams(WebThreadType::kTestThread) + .SetThreadNameForTest("DOMWrapperWorld test thread")); scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner = Thread::Current()->GetTaskRunner(); thread->BackingThread().PostTask(
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h b/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h index f65a8add..34015ea8 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h +++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
@@ -98,7 +98,8 @@ // pemCertificate:WebCoreString kDetectedBarcodeTag = 'B', // raw_value:WebCoreString, bounding_box:DOMRectReadOnly, - // corner_points:Point2D[length] -> DetectedBarcode (ref) + // format:String, corner_points:Point2D[length] -> + // DetectedBarcode (ref) kDetectedFaceTag = 'F', // raw_value:WebCoreString, bounding_box:DOMRectReadOnly, // corner_points:Point2D[length] -> DetectedText (ref)
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc index 91e65bb..dd35f5c 100644 --- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc +++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
@@ -68,6 +68,9 @@ DOMRectReadOnly* bounding_box = ReadDOMRectReadOnly(); if (!bounding_box) return nullptr; + // TODO(crbug.com/938663): add deserialization for |format|. + shape_detection::mojom::BarcodeFormat format = + shape_detection::mojom::BarcodeFormat::UNKNOWN; uint32_t corner_points_length; if (!ReadUint32(&corner_points_length)) return nullptr; @@ -78,7 +81,8 @@ return nullptr; corner_points.push_back(point); } - return DetectedBarcode::Create(raw_value, bounding_box, corner_points); + return DetectedBarcode::Create(raw_value, bounding_box, format, + corner_points); } case kDetectedFaceTag: { DOMRectReadOnly* bounding_box = ReadDOMRectReadOnly();
diff --git a/third_party/blink/renderer/core/css/media_query_evaluator.cc b/third_party/blink/renderer/core/css/media_query_evaluator.cc index e78a42f..11c1ba1 100644 --- a/third_party/blink/renderer/core/css/media_query_evaluator.cc +++ b/third_party/blink/renderer/core/css/media_query_evaluator.cc
@@ -29,10 +29,10 @@ #include "third_party/blink/renderer/core/css/media_query_evaluator.h" +#include "third_party/blink/public/common/css/preferred_color_scheme.h" #include "third_party/blink/public/common/manifest/web_display_mode.h" #include "third_party/blink/public/platform/pointer_properties.h" #include "third_party/blink/public/platform/shape_properties.h" -#include "third_party/blink/public/platform/web_color_scheme.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_resolution_units.h" #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h" @@ -830,19 +830,20 @@ const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& media_values) { - WebColorScheme preferred_scheme = media_values.PreferredColorScheme(); + PreferredColorScheme preferred_scheme = + media_values.GetPreferredColorScheme(); if (!value.IsValid()) - return preferred_scheme != WebColorScheme::kNoPreference; + return preferred_scheme != PreferredColorScheme::kNoPreference; if (!value.is_id) return false; - return (preferred_scheme == WebColorScheme::kNoPreference && + return (preferred_scheme == PreferredColorScheme::kNoPreference && value.id == CSSValueNoPreference) || - (preferred_scheme == WebColorScheme::kDark && + (preferred_scheme == PreferredColorScheme::kDark && value.id == CSSValueDark) || - (preferred_scheme == WebColorScheme::kLight && + (preferred_scheme == PreferredColorScheme::kLight && value.id == CSSValueLight); }
diff --git a/third_party/blink/renderer/core/css/media_values.cc b/third_party/blink/renderer/core/css/media_values.cc index 3dd82185..e84723a 100644 --- a/third_party/blink/renderer/core/css/media_values.cc +++ b/third_party/blink/renderer/core/css/media_values.cc
@@ -176,7 +176,8 @@ frame->GetPage()->GetChromeClient().GetScreenInfo()); } -WebColorScheme MediaValues::CalculatePreferredColorScheme(LocalFrame* frame) { +PreferredColorScheme MediaValues::CalculatePreferredColorScheme( + LocalFrame* frame) { DCHECK(frame); DCHECK(frame->GetSettings()); return frame->GetSettings()->GetPreferredColorScheme();
diff --git a/third_party/blink/renderer/core/css/media_values.h b/third_party/blink/renderer/core/css/media_values.h index b95315b2..6920db0e 100644 --- a/third_party/blink/renderer/core/css/media_values.h +++ b/third_party/blink/renderer/core/css/media_values.h
@@ -18,7 +18,7 @@ class CSSPrimitiveValue; class LocalFrame; enum class ColorSpaceGamut; -enum class WebColorScheme; +enum class PreferredColorScheme; class CORE_EXPORT MediaValues : public GarbageCollectedFinalized<MediaValues> { public: @@ -77,7 +77,7 @@ virtual void OverrideViewportDimensions(double width, double height) = 0; virtual DisplayShape GetDisplayShape() const = 0; virtual ColorSpaceGamut ColorGamut() const = 0; - virtual WebColorScheme PreferredColorScheme() const = 0; + virtual PreferredColorScheme GetPreferredColorScheme() const = 0; virtual bool PrefersReducedMotion() const = 0; protected: @@ -100,7 +100,7 @@ static int CalculateAvailableHoverTypes(LocalFrame*); static DisplayShape CalculateDisplayShape(LocalFrame*); static ColorSpaceGamut CalculateColorGamut(LocalFrame*); - static WebColorScheme CalculatePreferredColorScheme(LocalFrame*); + static PreferredColorScheme CalculatePreferredColorScheme(LocalFrame*); static bool CalculatePrefersReducedMotion(LocalFrame*); };
diff --git a/third_party/blink/renderer/core/css/media_values_cached.cc b/third_party/blink/renderer/core/css/media_values_cached.cc index 6538504..557335a 100644 --- a/third_party/blink/renderer/core/css/media_values_cached.cc +++ b/third_party/blink/renderer/core/css/media_values_cached.cc
@@ -4,7 +4,7 @@ #include "third_party/blink/renderer/core/css/media_values_cached.h" -#include "third_party/blink/public/platform/web_color_scheme.h" +#include "third_party/blink/public/common/css/preferred_color_scheme.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -32,7 +32,7 @@ display_mode(kWebDisplayModeBrowser), display_shape(kDisplayShapeRect), color_gamut(ColorSpaceGamut::kUnknown), - preferred_color_scheme(WebColorScheme::kNoPreference), + preferred_color_scheme(PreferredColorScheme::kNoPreference), prefers_reduced_motion(false) {} MediaValuesCached::MediaValuesCachedData::MediaValuesCachedData( @@ -197,7 +197,7 @@ return data_.color_gamut; } -WebColorScheme MediaValuesCached::PreferredColorScheme() const { +PreferredColorScheme MediaValuesCached::GetPreferredColorScheme() const { return data_.preferred_color_scheme; }
diff --git a/third_party/blink/renderer/core/css/media_values_cached.h b/third_party/blink/renderer/core/css/media_values_cached.h index aad52e0..e93baff 100644 --- a/third_party/blink/renderer/core/css/media_values_cached.h +++ b/third_party/blink/renderer/core/css/media_values_cached.h
@@ -36,7 +36,7 @@ WebDisplayMode display_mode; DisplayShape display_shape; ColorSpaceGamut color_gamut; - WebColorScheme preferred_color_scheme; + PreferredColorScheme preferred_color_scheme; bool prefers_reduced_motion; MediaValuesCachedData(); @@ -104,7 +104,7 @@ WebDisplayMode DisplayMode() const override; DisplayShape GetDisplayShape() const override; ColorSpaceGamut ColorGamut() const override; - WebColorScheme PreferredColorScheme() const override; + PreferredColorScheme GetPreferredColorScheme() const override; bool PrefersReducedMotion() const override; void OverrideViewportDimensions(double width, double height) override;
diff --git a/third_party/blink/renderer/core/css/media_values_dynamic.cc b/third_party/blink/renderer/core/css/media_values_dynamic.cc index bb31bc4..b1979d3 100644 --- a/third_party/blink/renderer/core/css/media_values_dynamic.cc +++ b/third_party/blink/renderer/core/css/media_values_dynamic.cc
@@ -4,7 +4,7 @@ #include "third_party/blink/renderer/core/css/media_values_dynamic.h" -#include "third_party/blink/public/platform/web_color_scheme.h" +#include "third_party/blink/public/common/css/preferred_color_scheme.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_resolution_units.h" #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h" @@ -142,7 +142,7 @@ return CalculateColorGamut(frame_); } -WebColorScheme MediaValuesDynamic::PreferredColorScheme() const { +PreferredColorScheme MediaValuesDynamic::GetPreferredColorScheme() const { return CalculatePreferredColorScheme(frame_); }
diff --git a/third_party/blink/renderer/core/css/media_values_dynamic.h b/third_party/blink/renderer/core/css/media_values_dynamic.h index dae64dc..5bdddf7 100644 --- a/third_party/blink/renderer/core/css/media_values_dynamic.h +++ b/third_party/blink/renderer/core/css/media_values_dynamic.h
@@ -48,7 +48,7 @@ WebDisplayMode DisplayMode() const override; DisplayShape GetDisplayShape() const override; ColorSpaceGamut ColorGamut() const override; - WebColorScheme PreferredColorScheme() const override; + PreferredColorScheme GetPreferredColorScheme() const override; bool PrefersReducedMotion() const override; Document* GetDocument() const override; bool HasValues() const override;
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index f5c1c91..2c04450e 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -6,7 +6,7 @@ #include <memory> #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/platform/web_color_scheme.h" +#include "third_party/blink/public/common/css/preferred_color_scheme.h" #include "third_party/blink/public/platform/web_float_rect.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/core/css/css_font_selector.h" @@ -1502,7 +1502,8 @@ GetDocument().body()->GetComputedStyle()->VisitedDependentColor( GetCSSPropertyColor())); - GetDocument().GetSettings()->SetPreferredColorScheme(WebColorScheme::kDark); + GetDocument().GetSettings()->SetPreferredColorScheme( + PreferredColorScheme::kDark); UpdateAllLifecyclePhases(); EXPECT_EQ(MakeRGB(0, 128, 0), GetDocument().body()->GetComputedStyle()->VisitedDependentColor(
diff --git a/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc b/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc index e2463b8..7a7205a 100644 --- a/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc +++ b/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc
@@ -122,7 +122,7 @@ CallbackId id = NextCallbackId(); idle_tasks_.Set(id, idle_task); - long long timeout_millis = options->timeout(); + uint32_t timeout_millis = options->timeout(); probe::AsyncTaskScheduled(GetExecutionContext(), "requestIdleCallback", idle_task); @@ -139,7 +139,7 @@ void ScriptedIdleTaskController::ScheduleCallback( scoped_refptr<internal::IdleRequestCallbackWrapper> callback_wrapper, - long long timeout_millis) { + uint32_t timeout_millis) { scheduler_->PostIdleTask( FROM_HERE, WTF::Bind(&internal::IdleRequestCallbackWrapper::IdleTaskFired, callback_wrapper));
diff --git a/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h b/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h index 78cdd3e5..cdfccc3aa 100644 --- a/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h +++ b/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h
@@ -93,7 +93,7 @@ void ContextPaused(); void ContextUnpaused(); void ScheduleCallback(scoped_refptr<internal::IdleRequestCallbackWrapper>, - long long timeout_millis); + uint32_t timeout_millis); int NextCallbackId();
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.cc b/third_party/blink/renderer/core/exported/web_settings_impl.cc index 8dcd68c9..5a628417 100644 --- a/third_party/blink/renderer/core/exported/web_settings_impl.cc +++ b/third_party/blink/renderer/core/exported/web_settings_impl.cc
@@ -754,6 +754,11 @@ settings_->SetForceDarkModeEnabled(enabled); } +void WebSettingsImpl::SetPreferredColorScheme( + PreferredColorScheme color_scheme) { + settings_->SetPreferredColorScheme(color_scheme); +} + STATIC_ASSERT_ENUM(WebSettings::ImageAnimationPolicy::kAllowed, kImageAnimationPolicyAllowed); STATIC_ASSERT_ENUM(WebSettings::ImageAnimationPolicy::kAnimateOnce,
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.h b/third_party/blink/renderer/core/exported/web_settings_impl.h index aa6503a0..6ec55866 100644 --- a/third_party/blink/renderer/core/exported/web_settings_impl.h +++ b/third_party/blink/renderer/core/exported/web_settings_impl.h
@@ -217,6 +217,7 @@ void SetLazyImageLoadingDistanceThresholdPx4G(int) override; void SetForceDarkModeEnabled(bool) override; + void SetPreferredColorScheme(PreferredColorScheme) override; bool RenderVSyncNotificationEnabled() const { return render_v_sync_notification_enabled_;
diff --git a/third_party/blink/renderer/core/frame/settings.h b/third_party/blink/renderer/core/frame/settings.h index d1e46f6..ccba230 100644 --- a/third_party/blink/renderer/core/frame/settings.h +++ b/third_party/blink/renderer/core/frame/settings.h
@@ -31,9 +31,9 @@ #include <memory> #include "base/macros.h" +#include "third_party/blink/public/common/css/preferred_color_scheme.h" #include "third_party/blink/public/common/manifest/web_display_mode.h" #include "third_party/blink/public/platform/pointer_properties.h" -#include "third_party/blink/public/platform/web_color_scheme.h" #include "third_party/blink/public/platform/web_effective_connection_type.h" #include "third_party/blink/public/platform/web_viewport_style.h" #include "third_party/blink/renderer/bindings/core/v8/v8_cache_options.h"
diff --git a/third_party/blink/renderer/core/frame/settings.json5 b/third_party/blink/renderer/core/frame/settings.json5 index acd64b60..a30d822 100644 --- a/third_party/blink/renderer/core/frame/settings.json5 +++ b/third_party/blink/renderer/core/frame/settings.json5
@@ -1006,9 +1006,9 @@ // evaluating the prefers-color-scheme media query. { name: "preferredColorScheme", - initial: "WebColorScheme::kNoPreference", + initial: "PreferredColorScheme::kNoPreference", invalidate: "MediaQuery", - type: "WebColorScheme", + type: "PreferredColorScheme", }, // Preferred motion-reduction setting from the OS/application passed to the
diff --git a/third_party/blink/renderer/core/html/parser/xss_auditor_delegate.cc b/third_party/blink/renderer/core/html/parser/xss_auditor_delegate.cc index 4cf4f30..b20e636 100644 --- a/third_party/blink/renderer/core/html/parser/xss_auditor_delegate.cc +++ b/third_party/blink/renderer/core/html/parser/xss_auditor_delegate.cc
@@ -124,8 +124,8 @@ } if (xss_info.did_block_entire_page_) { - local_frame->GetNavigationScheduler().SchedulePageBlock( - document_, ResourceError::BlockedByXSSAuditorErrorCode()); + local_frame->Client()->LoadErrorPage( + ResourceError::BlockedByXSSAuditorErrorCode()); } }
diff --git a/third_party/blink/renderer/core/layout/layout_frame_set.cc b/third_party/blink/renderer/core/layout/layout_frame_set.cc index 75dbe63..37f8fb6f 100644 --- a/third_party/blink/renderer/core/layout/layout_frame_set.cc +++ b/third_party/blink/renderer/core/layout/layout_frame_set.cc
@@ -37,6 +37,15 @@ namespace blink { +// Adjusts proportionally the size with remaining size. +static int AdjustSizeToRemainingSize(int current, int remaining, int total) { + // Performs the math operations step by step to avoid the overflow. + base::CheckedNumeric<int64_t> temp_product = current; + temp_product *= remaining; + temp_product /= total; + return base::checked_cast<int>(temp_product.ValueOrDie()); +} + LayoutFrameSet::LayoutFrameSet(HTMLFrameSetElement* frame_set) : LayoutBox(frame_set), is_resizing_(false), is_child_resizing_(false) { SetInline(false); @@ -136,9 +145,8 @@ for (int i = 0; i < grid_len; ++i) { if (grid[i].IsAbsolute()) { - long long temp_product = - static_cast<long long>(grid_layout[i]) * remaining_fixed; - grid_layout[i] = static_cast<int>(temp_product / total_fixed); + grid_layout[i] = AdjustSizeToRemainingSize( + grid_layout[i], remaining_fixed, total_fixed); remaining_len -= grid_layout[i]; } } @@ -156,9 +164,8 @@ for (int i = 0; i < grid_len; ++i) { if (grid[i].IsPercentage()) { - long long temp_product = - static_cast<long long>(grid_layout[i]) * remaining_percent; - grid_layout[i] = static_cast<int>(temp_product / total_percent); + grid_layout[i] = AdjustSizeToRemainingSize( + grid_layout[i], remaining_percent, total_percent); remaining_len -= grid_layout[i]; } } @@ -206,9 +213,8 @@ for (int i = 0; i < grid_len; ++i) { if (grid[i].IsPercentage()) { - long long temp_product = - static_cast<long long>(grid_layout[i]) * remaining_percent; - change_percent = static_cast<int>(temp_product / total_percent); + change_percent = AdjustSizeToRemainingSize( + grid_layout[i], remaining_percent, total_percent); grid_layout[i] += change_percent; remaining_len -= change_percent; } @@ -222,9 +228,8 @@ for (int i = 0; i < grid_len; ++i) { if (grid[i].IsAbsolute()) { - long long temp_product = - static_cast<long long>(grid_layout[i]) * remaining_fixed; - change_fixed = static_cast<int>(temp_product / total_fixed); + change_fixed = AdjustSizeToRemainingSize( + grid_layout[i], remaining_fixed, total_fixed); grid_layout[i] += change_fixed; remaining_len -= change_fixed; }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc index 51cf17b..e43ec3b 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc
@@ -94,10 +94,6 @@ .SetIsShrinkToFit(shrink_to_fit) .SetFragmentainerSpaceAtBfcStart(fragmentainer_space_available) .SetFragmentationType(block_fragmentation) - .AddBaselineRequest({NGBaselineAlgorithmType::kAtomicInline, - FontBaseline::kAlphabeticBaseline}) - .AddBaselineRequest({NGBaselineAlgorithmType::kFirstLine, - FontBaseline::kAlphabeticBaseline}) .ToConstraintSpace(); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc index 24edfc6..1505b6bf06 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -231,12 +231,24 @@ </div> )HTML"); - NGConstraintSpace space100 = ConstructBlockLayoutTestConstraintSpace( - WritingMode::kHorizontalTb, TextDirection::kLtr, - NGLogicalSize(LayoutUnit(100), LayoutUnit(100))); - NGConstraintSpace space200 = ConstructBlockLayoutTestConstraintSpace( - WritingMode::kHorizontalTb, TextDirection::kLtr, - NGLogicalSize(LayoutUnit(100), LayoutUnit(200))); + auto create_space = [&](auto size) -> NGConstraintSpace { + return NGConstraintSpaceBuilder(WritingMode::kHorizontalTb, + WritingMode::kHorizontalTb, + /* is_new_formatting_context */ false) + .SetAvailableSize(size) + .SetPercentageResolutionSize(size) + .SetTextDirection(TextDirection::kLtr) + .AddBaselineRequest({NGBaselineAlgorithmType::kAtomicInline, + FontBaseline::kAlphabeticBaseline}) + .AddBaselineRequest({NGBaselineAlgorithmType::kFirstLine, + FontBaseline::kAlphabeticBaseline}) + .ToConstraintSpace(); + }; + + NGConstraintSpace space100 = + create_space(NGLogicalSize(LayoutUnit(100), LayoutUnit(100))); + NGConstraintSpace space200 = + create_space(NGLogicalSize(LayoutUnit(100), LayoutUnit(200))); auto run_test = [&](auto id) -> scoped_refptr<const NGLayoutResult> { // Grab the box under test. @@ -286,6 +298,96 @@ EXPECT_EQ(run_test("box9"), nullptr); } +TEST_F(NGBlockLayoutAlgorithmTest, ShrinkToFitCaching) { + ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true); + + SetBodyInnerHTML(R"HTML( + <div id="container" style="display: flow-root; width: 300px; height: 100px;"> + <div id="box1" style="float: left;"> + <div style="display: inline-block; width: 150px;"></div> + <div style="display: inline-block; width: 50px;"></div> + </div> + <div id="box2" style="float: left;"> + <div style="display: inline-block; width: 350px;"></div> + <div style="display: inline-block; width: 250px;"></div> + </div> + <div id="box3" style="float: left; min-width: 50%;"> + <div style="display: inline-block; width: 350px;"></div> + <div style="display: inline-block; width: 250px;"></div> + </div> + <div id="box4" style="float: left; margin-left: 75px;"> + <div style="display: inline-block; width: 150px;"></div> + <div style="display: inline-block; width: 50px;"></div> + </div> + </div> + )HTML"); + + NGConstraintSpace space100 = ConstructBlockLayoutTestConstraintSpace( + WritingMode::kHorizontalTb, TextDirection::kLtr, + NGLogicalSize(LayoutUnit(100), LayoutUnit(100)), + /* shrink_to_fit */ true, /* is_new_formatting_context */ true); + NGConstraintSpace space200 = ConstructBlockLayoutTestConstraintSpace( + WritingMode::kHorizontalTb, TextDirection::kLtr, + NGLogicalSize(LayoutUnit(200), LayoutUnit(100)), + /* shrink_to_fit */ true, /* is_new_formatting_context */ true); + NGConstraintSpace space250 = ConstructBlockLayoutTestConstraintSpace( + WritingMode::kHorizontalTb, TextDirection::kLtr, + NGLogicalSize(LayoutUnit(250), LayoutUnit(100)), + /* shrink_to_fit */ true, /* is_new_formatting_context */ true); + NGConstraintSpace space300 = ConstructBlockLayoutTestConstraintSpace( + WritingMode::kHorizontalTb, TextDirection::kLtr, + NGLogicalSize(LayoutUnit(300), LayoutUnit(100)), + /* shrink_to_fit */ true, /* is_new_formatting_context */ true); + NGConstraintSpace space400 = ConstructBlockLayoutTestConstraintSpace( + WritingMode::kHorizontalTb, TextDirection::kLtr, + NGLogicalSize(LayoutUnit(400), LayoutUnit(100)), + /* shrink_to_fit */ true, /* is_new_formatting_context */ true); + scoped_refptr<const NGLayoutResult> result; + + LayoutBlockFlow* box1 = ToLayoutBlockFlow(GetLayoutObjectByElementId("box1")); + LayoutBlockFlow* box2 = ToLayoutBlockFlow(GetLayoutObjectByElementId("box2")); + LayoutBlockFlow* box3 = ToLayoutBlockFlow(GetLayoutObjectByElementId("box3")); + LayoutBlockFlow* box4 = ToLayoutBlockFlow(GetLayoutObjectByElementId("box4")); + + // Ensure we cached the result for box1 in the first layout pass. + result = box1->CachedLayoutResult(space300, nullptr); + EXPECT_NE(result.get(), nullptr); + + // box1 was sized to its max-content size in the first layout pass, passing + // an available size larger than the fragment should hit the cache. + result = box1->CachedLayoutResult(space400, nullptr); + EXPECT_NE(result.get(), nullptr); + + // Passing an available size smaller than the fragment should miss the cache + // as the fragment may shrink. + result = box1->CachedLayoutResult(space100, nullptr); + EXPECT_EQ(result.get(), nullptr); + + // Ensure we cached the result for box2 in the first layout pass. + result = box2->CachedLayoutResult(space300, nullptr); + EXPECT_NE(result.get(), nullptr); + + // box2 was sized to its min-content size in the first layout pass, passing + // an available size smaller than the fragment should hit the cache. + result = box2->CachedLayoutResult(space200, nullptr); + EXPECT_NE(result.get(), nullptr); + + // Passing an available size larger than the fragment should miss the cache + // as the fragment may shrink. + result = box2->CachedLayoutResult(space400, nullptr); + EXPECT_EQ(result.get(), nullptr); + + // box3 was sized to its min-content size in the first layout pass, however + // it should miss the cache as it has a %-min-size. + result = box3->CachedLayoutResult(space200, nullptr); + EXPECT_EQ(result.get(), nullptr); + + // box4 was sized to its max-content size in the first layout pass (the same + // as box1) however it should miss the cache due to its margin. + result = box4->CachedLayoutResult(space250, nullptr); + EXPECT_EQ(result.get(), nullptr); +} + // Verifies that two children are laid out with the correct size and position. TEST_F(NGBlockLayoutAlgorithmTest, LayoutBlockChildren) { SetBodyInnerHTML(R"HTML(
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc index 3f91f64..3c56710 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc
@@ -94,6 +94,7 @@ .SetIsFixedSizeBlock(fixed_block) .SetFixedSizeBlockIsDefinite(fixed_block_is_definite) .SetIsShrinkToFit( + style.LogicalWidth().IsAuto() && block.SizesLogicalWidthToFitContent(style.LogicalWidth())) .SetTextDirection(style.Direction()) .ToConstraintSpace();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc index 8dd9d9f..e9a00af 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/layout/ng/ng_layout_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" +#include "third_party/blink/renderer/core/layout/ng/ng_fragment.h" #include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h" #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h" @@ -12,22 +13,105 @@ namespace { -inline bool InlineLengthMayChange(const Length& length, +bool ContentShrinkToFitMayChange(const ComputedStyle& style, + const NGConstraintSpace& new_space, + const NGConstraintSpace& old_space, + const NGLayoutResult& layout_result) { + if (old_space.AvailableSize().inline_size == + new_space.AvailableSize().inline_size) + return false; + + NGBoxStrut margins = ComputeMarginsForSelf(new_space, style); + +#if DCHECK_IS_ON() + // The margins must be the same, as this function won't be called if we have + // percentage inline margins, and the percentage resolution size changes. + NGBoxStrut old_margins = ComputeMarginsForSelf(old_space, style); + DCHECK_EQ(margins.inline_start, old_margins.inline_start); + DCHECK_EQ(margins.inline_end, old_margins.inline_end); +#endif + + LayoutUnit old_available_inline_size = + std::max(LayoutUnit(), + old_space.AvailableSize().inline_size - margins.InlineSum()); + LayoutUnit new_available_inline_size = + std::max(LayoutUnit(), + new_space.AvailableSize().inline_size - margins.InlineSum()); + + DCHECK(layout_result.PhysicalFragment()); + LayoutUnit inline_size = + NGFragment(style.GetWritingMode(), *layout_result.PhysicalFragment()) + .InlineSize(); + + // If the previous fragment was at its min-content size (indicated by the old + // available size being smaller than the fragment), we may be able to skip + // layout if the new available size is also smaller. + bool unaffected_as_min_content_size = + old_available_inline_size < inline_size && + new_available_inline_size <= inline_size; + + // If the previous fragment was at its max-content size (indicated by the old + // available size being larger than the fragment), we may be able to skip + // layout if the new available size is also larger. + bool unaffected_as_max_content_size = + old_available_inline_size > inline_size && + new_available_inline_size >= inline_size; + + // TODO(crbug.com/935634): There is an additional optimization where if we + // detect (by setting a flag in the layout result) that the + // min-content == max-content we can simply just skip layout, as the + // available size won't have any effect. + + if (unaffected_as_min_content_size || unaffected_as_max_content_size) + return false; + + return true; +} + +inline bool InlineLengthMayChange(const ComputedStyle& style, + const Length& length, LengthResolveType type, const NGConstraintSpace& new_space, - const NGConstraintSpace& old_space) { - // Percentage inline margins will affect the size if the size is unspecified - // (auto and similar). So we need to check both available size and the - // percentage resolution size in that case. + const NGConstraintSpace& old_space, + const NGLayoutResult& layout_result) { + DCHECK_EQ(new_space.IsShrinkToFit(), old_space.IsShrinkToFit()); +#if DCHECK_IS_ON() + if (type == LengthResolveType::kContentSize && new_space.IsShrinkToFit()) + DCHECK(length.IsAuto()); +#endif + bool is_unspecified = (length.IsAuto() && type != LengthResolveType::kMinSize) || length.IsFitContent() || length.IsFillAvailable(); + + // Percentage inline margins will affect the size if the size is unspecified + // (auto and similar). + if (is_unspecified && style.MayHaveMargin() && + (style.MarginStart().IsPercentOrCalc() || + style.MarginEnd().IsPercentOrCalc()) && + (new_space.PercentageResolutionInlineSize() != + old_space.PercentageResolutionInlineSize())) + return true; + + // For elements which shrink to fit, we can perform a specific optimization + // where we can skip relayout if the element was sized to its min-content or + // max-content size. + bool is_content_shrink_to_fit = + type == LengthResolveType::kContentSize && + (new_space.IsShrinkToFit() || length.IsFitContent()); + + if (is_content_shrink_to_fit) { + return ContentShrinkToFitMayChange(style, new_space, old_space, + layout_result); + } + if (is_unspecified) { if (new_space.AvailableSize().inline_size != old_space.AvailableSize().inline_size) return true; } - if (is_unspecified || length.IsPercentOrCalc()) { + + if (length.IsPercentOrCalc()) { if (new_space.PercentageResolutionInlineSize() != old_space.PercentageResolutionInlineSize()) return true; @@ -71,15 +155,15 @@ old_space.AvailableSize().inline_size) return true; } else { - if (InlineLengthMayChange(style.LogicalWidth(), + if (InlineLengthMayChange(style, style.LogicalWidth(), LengthResolveType::kContentSize, new_space, - old_space) || - InlineLengthMayChange(style.LogicalMinWidth(), - LengthResolveType::kMinSize, new_space, - old_space) || - InlineLengthMayChange(style.LogicalMaxWidth(), - LengthResolveType::kMaxSize, new_space, - old_space)) + old_space, layout_result) || + InlineLengthMayChange(style, style.LogicalMinWidth(), + LengthResolveType::kMinSize, new_space, old_space, + layout_result) || + InlineLengthMayChange(style, style.LogicalMaxWidth(), + LengthResolveType::kMaxSize, new_space, old_space, + layout_result)) return true; }
diff --git a/third_party/blink/renderer/core/loader/appcache/application_cache_host.h b/third_party/blink/renderer/core/loader/appcache/application_cache_host.h index a285a61..e8c678c 100644 --- a/third_party/blink/renderer/core/loader/appcache/application_cache_host.h +++ b/third_party/blink/renderer/core/loader/appcache/application_cache_host.h
@@ -68,7 +68,7 @@ CacheInfo(const KURL& manifest, double creation_time, double update_time, - long long size) + int64_t size) : manifest_(manifest), creation_time_(creation_time), update_time_(update_time), @@ -76,7 +76,7 @@ KURL manifest_; double creation_time_; double update_time_; - long long size_; + int64_t size_; }; struct ResourceInfo { @@ -87,7 +87,7 @@ bool is_fallback, bool is_foreign, bool is_explicit, - long long size) + int64_t size) : resource_(resource), is_master_(is_master), is_manifest_(is_manifest), @@ -101,7 +101,7 @@ bool is_fallback_; bool is_foreign_; bool is_explicit_; - long long size_; + int64_t size_; }; typedef Vector<ResourceInfo> ResourceInfoList;
diff --git a/third_party/blink/renderer/core/loader/navigation_scheduler.cc b/third_party/blink/renderer/core/loader/navigation_scheduler.cc index 93f1f2f5..9fd1716 100644 --- a/third_party/blink/renderer/core/loader/navigation_scheduler.cc +++ b/third_party/blink/renderer/core/loader/navigation_scheduler.cc
@@ -211,30 +211,6 @@ input_timestamp) {} }; -class ScheduledPageBlock final : public ScheduledNavigation { - public: - static ScheduledPageBlock* Create(Document* origin_document, int reason) { - return MakeGarbageCollected<ScheduledPageBlock>(origin_document, reason); - } - - ScheduledPageBlock(Document* origin_document, int reason) - : ScheduledNavigation(ClientNavigationReason::kPageBlock, - 0.0, - origin_document, - true, - base::TimeTicks() /* input_timestamp */), - reason_(reason) {} - - void Fire(LocalFrame* frame) override { - frame->Client()->LoadErrorPage(reason_); - } - - KURL Url() const override { return KURL(); } - - private: - int reason_; -}; - class ScheduledFormSubmission final : public ScheduledNavigation { public: static ScheduledFormSubmission* Create(Document* document, @@ -384,12 +360,6 @@ frame_load_type, input_timestamp)); } -void NavigationScheduler::SchedulePageBlock(Document* origin_document, - int reason) { - DCHECK(frame_->GetPage()); - Schedule(ScheduledPageBlock::Create(origin_document, reason)); -} - void NavigationScheduler::ScheduleFormSubmission(Document* document, FormSubmission* submission) { DCHECK(frame_->GetPage());
diff --git a/third_party/blink/renderer/core/loader/navigation_scheduler.h b/third_party/blink/renderer/core/loader/navigation_scheduler.h index d9769b2..cd9028c4 100644 --- a/third_party/blink/renderer/core/loader/navigation_scheduler.h +++ b/third_party/blink/renderer/core/loader/navigation_scheduler.h
@@ -68,7 +68,6 @@ void ScheduleRedirect(double delay, const KURL&, Document::HttpRefreshType); void ScheduleFrameNavigation(Document*, const KURL&, WebFrameLoadType); - void SchedulePageBlock(Document*, int reason); void ScheduleFormSubmission(Document*, FormSubmission*); void StartTimer();
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc index bf20ac2d..25fccab 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
@@ -225,8 +225,8 @@ std::unique_ptr<WorkerThread> DedicatedWorkerMessagingProxy::CreateWorkerThread() { - return DedicatedWorkerThread::Create(GetExecutionContext(), - WorkerObjectProxy()); + return std::make_unique<DedicatedWorkerThread>(GetExecutionContext(), + WorkerObjectProxy()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_test.cc b/third_party/blink/renderer/core/workers/dedicated_worker_test.cc index 8cb97e4..26176da 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_test.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker_test.cc
@@ -33,7 +33,7 @@ DedicatedWorkerThreadForTest(ExecutionContext* parent_execution_context, DedicatedWorkerObjectProxy& worker_object_proxy) : DedicatedWorkerThread(parent_execution_context, worker_object_proxy) { - worker_backing_thread_ = WorkerBackingThread::Create( + worker_backing_thread_ = std::make_unique<WorkerBackingThread>( ThreadCreationParams(WebThreadType::kTestThread)); }
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_thread.cc b/third_party/blink/renderer/core/workers/dedicated_worker_thread.cc index 31d16bd..3e25d5d 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_thread.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker_thread.cc
@@ -45,13 +45,6 @@ namespace blink { -std::unique_ptr<DedicatedWorkerThread> DedicatedWorkerThread::Create( - ExecutionContext* parent_execution_context, - DedicatedWorkerObjectProxy& worker_object_proxy) { - return base::WrapUnique( - new DedicatedWorkerThread(parent_execution_context, worker_object_proxy)); -} - DedicatedWorkerThread::DedicatedWorkerThread( ExecutionContext* parent_execution_context, DedicatedWorkerObjectProxy& worker_object_proxy) @@ -60,9 +53,9 @@ FrameOrWorkerScheduler* scheduler = parent_execution_context ? parent_execution_context->GetScheduler() : nullptr; - worker_backing_thread_ = - WorkerBackingThread::Create(ThreadCreationParams(GetThreadType()) - .SetFrameOrWorkerScheduler(scheduler)); + worker_backing_thread_ = std::make_unique<WorkerBackingThread>( + ThreadCreationParams(GetThreadType()) + .SetFrameOrWorkerScheduler(scheduler)); } DedicatedWorkerThread::~DedicatedWorkerThread() = default;
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_thread.h b/third_party/blink/renderer/core/workers/dedicated_worker_thread.h index 9bff5cf..dccafa7d 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_thread.h +++ b/third_party/blink/renderer/core/workers/dedicated_worker_thread.h
@@ -40,9 +40,8 @@ class CORE_EXPORT DedicatedWorkerThread : public WorkerThread { public: - static std::unique_ptr<DedicatedWorkerThread> Create( - ExecutionContext* parent_execution_context, - DedicatedWorkerObjectProxy&); + DedicatedWorkerThread(ExecutionContext* parent_execution_context, + DedicatedWorkerObjectProxy&); ~DedicatedWorkerThread() override; WorkerBackingThread& GetWorkerBackingThread() override { @@ -56,8 +55,6 @@ private: friend class DedicatedWorkerThreadForTest; - DedicatedWorkerThread(ExecutionContext* parent_execution_context, - DedicatedWorkerObjectProxy&); WorkerOrWorkletGlobalScope* CreateWorkerGlobalScope( std::unique_ptr<GlobalScopeCreationParams>) override;
diff --git a/third_party/blink/renderer/core/workers/experimental/thread_pool_thread.cc b/third_party/blink/renderer/core/workers/experimental/thread_pool_thread.cc index 1b7a00c5..88f1215 100644 --- a/third_party/blink/renderer/core/workers/experimental/thread_pool_thread.cc +++ b/third_party/blink/renderer/core/workers/experimental/thread_pool_thread.cc
@@ -60,7 +60,7 @@ ThreadBackingPolicy backing_policy) : WorkerThread(object_proxy), backing_policy_(backing_policy) { DCHECK(parent_execution_context); - worker_backing_thread_ = WorkerBackingThread::Create( + worker_backing_thread_ = std::make_unique<WorkerBackingThread>( ThreadCreationParams(GetThreadType()) .SetFrameOrWorkerScheduler(parent_execution_context->GetScheduler())); }
diff --git a/third_party/blink/renderer/core/workers/shared_worker_content_settings_proxy.cc b/third_party/blink/renderer/core/workers/shared_worker_content_settings_proxy.cc index 262aeea..ae88b4a 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_content_settings_proxy.cc +++ b/third_party/blink/renderer/core/workers/shared_worker_content_settings_proxy.cc
@@ -21,6 +21,13 @@ return result; } +bool SharedWorkerContentSettingsProxy::AllowCacheStorage( + const WebSecurityOrigin&) { + bool result = false; + GetService()->AllowCacheStorage(&result); + return result; +} + bool SharedWorkerContentSettingsProxy::RequestFileSystemAccessSync() { bool result = false; GetService()->RequestFileSystemAccessSync(&result);
diff --git a/third_party/blink/renderer/core/workers/shared_worker_content_settings_proxy.h b/third_party/blink/renderer/core/workers/shared_worker_content_settings_proxy.h index 7701400..716fd183 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_content_settings_proxy.h +++ b/third_party/blink/renderer/core/workers/shared_worker_content_settings_proxy.h
@@ -23,6 +23,7 @@ // WebContentSettingsClient overrides. bool AllowIndexedDB(const WebSecurityOrigin&) override; + bool AllowCacheStorage(const WebSecurityOrigin&) override; bool RequestFileSystemAccessSync() override; private:
diff --git a/third_party/blink/renderer/core/workers/shared_worker_thread.cc b/third_party/blink/renderer/core/workers/shared_worker_thread.cc index b61b0b1..b9fd86e 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_thread.cc +++ b/third_party/blink/renderer/core/workers/shared_worker_thread.cc
@@ -41,8 +41,8 @@ SharedWorkerThread::SharedWorkerThread( WorkerReportingProxy& worker_reporting_proxy) : WorkerThread(worker_reporting_proxy), - worker_backing_thread_( - WorkerBackingThread::Create(ThreadCreationParams(GetThreadType()))) {} + worker_backing_thread_(std::make_unique<WorkerBackingThread>( + ThreadCreationParams(GetThreadType()))) {} SharedWorkerThread::~SharedWorkerThread() = default;
diff --git a/third_party/blink/renderer/core/workers/worker_backing_thread.h b/third_party/blink/renderer/core/workers/worker_backing_thread.h index 3ce3b37b..026a82b 100644 --- a/third_party/blink/renderer/core/workers/worker_backing_thread.h +++ b/third_party/blink/renderer/core/workers/worker_backing_thread.h
@@ -29,11 +29,7 @@ USING_FAST_MALLOC(WorkerBackingThread); public: - static std::unique_ptr<WorkerBackingThread> Create( - const ThreadCreationParams& params) { - return base::WrapUnique(new WorkerBackingThread(params)); - } - + explicit WorkerBackingThread(const ThreadCreationParams&); ~WorkerBackingThread(); // InitializeOnBackingThread() and ShutdownOnBackingThread() attaches and @@ -56,8 +52,6 @@ static void SetRAILModeOnWorkerThreadIsolates(v8::RAILMode); private: - explicit WorkerBackingThread(const ThreadCreationParams&); - std::unique_ptr<WebThreadSupportingGC> backing_thread_; v8::Isolate* isolate_ = nullptr; };
diff --git a/third_party/blink/renderer/core/workers/worker_content_settings_client.cc b/third_party/blink/renderer/core/workers/worker_content_settings_client.cc index a255a36..f3d50d2 100644 --- a/third_party/blink/renderer/core/workers/worker_content_settings_client.cc +++ b/third_party/blink/renderer/core/workers/worker_content_settings_client.cc
@@ -57,6 +57,12 @@ return client_->AllowIndexedDB(WebSecurityOrigin()); } +bool WorkerContentSettingsClient::AllowCacheStorage() { + if (!client_) + return true; + return client_->AllowCacheStorage(WebSecurityOrigin()); +} + bool WorkerContentSettingsClient::AllowScriptFromSource( bool enabled_per_settings, const KURL& url) {
diff --git a/third_party/blink/renderer/core/workers/worker_content_settings_client.h b/third_party/blink/renderer/core/workers/worker_content_settings_client.h index 3a7f7f6..3af24f0 100644 --- a/third_party/blink/renderer/core/workers/worker_content_settings_client.h +++ b/third_party/blink/renderer/core/workers/worker_content_settings_client.h
@@ -60,6 +60,7 @@ bool RequestFileSystemAccessSync(); bool AllowIndexedDB(); + bool AllowCacheStorage(); bool AllowRunningInsecureContent(bool enabled_per_settings, const SecurityOrigin*, const KURL&);
diff --git a/third_party/blink/renderer/core/workers/worker_thread_test_helper.h b/third_party/blink/renderer/core/workers/worker_thread_test_helper.h index cab5f1e..4d8640c 100644 --- a/third_party/blink/renderer/core/workers/worker_thread_test_helper.h +++ b/third_party/blink/renderer/core/workers/worker_thread_test_helper.h
@@ -78,7 +78,7 @@ explicit WorkerThreadForTest( WorkerReportingProxy& mock_worker_reporting_proxy) : WorkerThread(mock_worker_reporting_proxy), - worker_backing_thread_(WorkerBackingThread::Create( + worker_backing_thread_(std::make_unique<WorkerBackingThread>( ThreadCreationParams(WebThreadType::kTestThread))) {} ~WorkerThreadForTest() override = default;
diff --git a/third_party/blink/renderer/core/workers/worklet_thread_holder.h b/third_party/blink/renderer/core/workers/worklet_thread_holder.h index 121bb33..dceb76de 100644 --- a/third_party/blink/renderer/core/workers/worklet_thread_holder.h +++ b/third_party/blink/renderer/core/workers/worklet_thread_holder.h
@@ -30,7 +30,8 @@ if (thread_holder_instance_) return; thread_holder_instance_ = new WorkletThreadHolder<DerivedWorkletThread>; - thread_holder_instance_->Initialize(WorkerBackingThread::Create(params)); + thread_holder_instance_->Initialize( + std::make_unique<WorkerBackingThread>(params)); } static void ClearInstance() {
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 e810c2e2..a855bb3 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache_storage.cc +++ b/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
@@ -12,12 +12,15 @@ #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/cache_storage/cache_storage_utils.h" #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" +#include "third_party/blink/public/platform/web_content_settings_client.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/fetch/request.h" #include "third_party/blink/renderer/core/fetch/response.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/core/workers/worker_content_settings_client.h" #include "third_party/blink/renderer/modules/cache_storage/cache_storage_error.h" #include "third_party/blink/renderer/modules/cache_storage/cache_storage_trace_utils.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h" @@ -54,6 +57,30 @@ namespace blink { +namespace { + +bool IsCacheStorageAllowed(ScriptState* script_state) { + ExecutionContext* context = ExecutionContext::From(script_state); + + if (auto* document = DynamicTo<Document>(context)) { + LocalFrame* frame = document->GetFrame(); + if (!frame) + return false; + if (auto* settings_client = frame->GetContentSettingsClient()) { + // This triggers a sync IPC. + return settings_client->AllowCacheStorage( + WebSecurityOrigin(context->GetSecurityOrigin())); + } + return true; + } + + WorkerGlobalScope& worker_global = *To<WorkerGlobalScope>(context); + // This triggers a sync IPC. + return WorkerContentSettingsClient::From(worker_global)->AllowCacheStorage(); +} + +} // namespace + CacheStorage* CacheStorage::Create(ExecutionContext* context, GlobalFetch::ScopedFetcher* fetcher) { return MakeGarbageCollected<CacheStorage>(context, fetcher); @@ -67,6 +94,12 @@ "name", CacheStorageTracedValue(cache_name)); ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); + ScriptPromise promise = resolver->Promise(); + + if (!IsAllowed(script_state)) { + resolver->Reject(DOMException::Create(DOMExceptionCode::kSecurityError)); + return promise; + } // Make sure to bind the CacheStorage object to keep the mojo interface // pointer alive during the operation. Otherwise GC might prevent the @@ -114,7 +147,7 @@ WrapPersistent(resolver), WrapPersistent(scoped_fetcher_.Get()), TimeTicks::Now(), trace_id, WrapPersistent(this))); - return resolver->Promise(); + return promise; } ScriptPromise CacheStorage::has(ScriptState* script_state, @@ -125,6 +158,12 @@ "name", CacheStorageTracedValue(cache_name)); ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); + ScriptPromise promise = resolver->Promise(); + + if (!IsAllowed(script_state)) { + resolver->Reject(DOMException::Create(DOMExceptionCode::kSecurityError)); + return promise; + } // Make sure to bind the CacheStorage object to keep the mojo interface // pointer alive during the operation. Otherwise GC might prevent the @@ -159,7 +198,7 @@ WrapPersistent(resolver), TimeTicks::Now(), trace_id, WrapPersistent(this))); - return resolver->Promise(); + return promise; } ScriptPromise CacheStorage::Delete(ScriptState* script_state, @@ -170,6 +209,12 @@ "name", CacheStorageTracedValue(cache_name)); ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); + ScriptPromise promise = resolver->Promise(); + + if (!IsAllowed(script_state)) { + resolver->Reject(DOMException::Create(DOMExceptionCode::kSecurityError)); + return promise; + } // Make sure to bind the CacheStorage object to keep the mojo interface // pointer alive during the operation. Otherwise GC might prevent the @@ -206,7 +251,7 @@ WrapPersistent(resolver), TimeTicks::Now(), trace_id, WrapPersistent(this))); - return resolver->Promise(); + return promise; } ScriptPromise CacheStorage::keys(ScriptState* script_state) { @@ -215,6 +260,12 @@ TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT); ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); + ScriptPromise promise = resolver->Promise(); + + if (!IsAllowed(script_state)) { + resolver->Reject(DOMException::Create(DOMExceptionCode::kSecurityError)); + return promise; + } // Make sure to bind the CacheStorage object to keep the mojo interface // pointer alive during the operation. Otherwise GC might prevent the @@ -238,7 +289,7 @@ WrapPersistent(resolver), TimeTicks::Now(), trace_id, WrapPersistent(this))); - return resolver->Promise(); + return promise; } ScriptPromise CacheStorage::match(ScriptState* script_state, @@ -272,6 +323,11 @@ ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); const ScriptPromise promise = resolver->Promise(); + if (!IsAllowed(script_state)) { + resolver->Reject(DOMException::Create(DOMExceptionCode::kSecurityError)); + return promise; + } + if (request->method() != http_names::kGET && !options->ignoreMethod()) { resolver->Resolve(); return promise; @@ -360,4 +416,12 @@ ScriptWrappable::Trace(visitor); } +bool CacheStorage::IsAllowed(ScriptState* script_state) { + if (!allowed_.has_value()) { + // Cache the IsCacheStorageAllowed() because it triggers a sync IPC. + allowed_.emplace(IsCacheStorageAllowed(script_state)); + } + return allowed_.value(); +} + } // namespace blink
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 10aa58d..70bbb60 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache_storage.h +++ b/third_party/blink/renderer/modules/cache_storage/cache_storage.h
@@ -7,6 +7,7 @@ #include <memory> #include "base/macros.h" +#include "base/optional.h" #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/fetch/global_fetch.h" @@ -45,9 +46,12 @@ const Request*, const MultiCacheQueryOptions*); + bool IsAllowed(ScriptState*); + Member<GlobalFetch::ScopedFetcher> scoped_fetcher_; RevocableInterfacePtr<mojom::blink::CacheStorage> cache_storage_ptr_; + base::Optional<bool> allowed_; DISALLOW_COPY_AND_ASSIGN(CacheStorage); };
diff --git a/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc b/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc index ccafe8a0..7e617bb 100644 --- a/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc +++ b/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc
@@ -50,7 +50,7 @@ FileEntrySync* DirectoryEntrySync::getFile(const String& path, const FileSystemFlags* options, ExceptionState& exception_state) { - EntryCallbacksSyncHelper* sync_helper = EntryCallbacksSyncHelper::Create(); + auto* sync_helper = MakeGarbageCollected<EntryCallbacksSyncHelper>(); file_system_->GetFile(this, path, options, sync_helper->GetSuccessCallback(), sync_helper->GetErrorCallback(), DOMFileSystemBase::kSynchronous); @@ -62,7 +62,7 @@ const String& path, const FileSystemFlags* options, ExceptionState& exception_state) { - EntryCallbacksSyncHelper* sync_helper = EntryCallbacksSyncHelper::Create(); + auto* sync_helper = MakeGarbageCollected<EntryCallbacksSyncHelper>(); file_system_->GetDirectory( this, path, options, sync_helper->GetSuccessCallback(), sync_helper->GetErrorCallback(), DOMFileSystemBase::kSynchronous); @@ -71,7 +71,7 @@ } void DirectoryEntrySync::removeRecursively(ExceptionState& exception_state) { - VoidCallbacksSyncHelper* sync_helper = VoidCallbacksSyncHelper::Create(); + auto* sync_helper = MakeGarbageCollected<VoidCallbacksSyncHelper>(); file_system_->RemoveRecursively(this, nullptr, sync_helper->GetErrorCallback(), DOMFileSystemBase::kSynchronous);
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc b/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc index afee5ea3..6b53ce57 100644 --- a/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc +++ b/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc
@@ -160,8 +160,7 @@ FileWriterSync* file_writer = FileWriterSync::Create(context_); - FileWriterCallbacksSyncHelper* sync_helper = - FileWriterCallbacksSyncHelper::Create(); + auto* sync_helper = MakeGarbageCollected<FileWriterCallbacksSyncHelper>(); auto callbacks = std::make_unique<FileWriterCallbacks>( file_writer, sync_helper->GetSuccessCallback(), sync_helper->GetErrorCallback(), context_);
diff --git a/third_party/blink/renderer/modules/filesystem/entry_sync.cc b/third_party/blink/renderer/modules/filesystem/entry_sync.cc index fe272ed..7f64c12 100644 --- a/third_party/blink/renderer/modules/filesystem/entry_sync.cc +++ b/third_party/blink/renderer/modules/filesystem/entry_sync.cc
@@ -47,8 +47,7 @@ } Metadata* EntrySync::getMetadata(ExceptionState& exception_state) { - MetadataCallbacksSyncHelper* sync_helper = - MetadataCallbacksSyncHelper::Create(); + auto* sync_helper = MakeGarbageCollected<MetadataCallbacksSyncHelper>(); file_system_->GetMetadata(this, sync_helper->GetSuccessCallback(), sync_helper->GetErrorCallback(), DOMFileSystemBase::kSynchronous); @@ -58,7 +57,7 @@ EntrySync* EntrySync::moveTo(DirectoryEntrySync* parent, const String& name, ExceptionState& exception_state) const { - EntryCallbacksSyncHelper* helper = EntryCallbacksSyncHelper::Create(); + auto* helper = MakeGarbageCollected<EntryCallbacksSyncHelper>(); file_system_->Move(this, parent, name, helper->GetSuccessCallback(), helper->GetErrorCallback(), DOMFileSystemBase::kSynchronous); @@ -69,7 +68,7 @@ EntrySync* EntrySync::copyTo(DirectoryEntrySync* parent, const String& name, ExceptionState& exception_state) const { - EntryCallbacksSyncHelper* sync_helper = EntryCallbacksSyncHelper::Create(); + auto* sync_helper = MakeGarbageCollected<EntryCallbacksSyncHelper>(); file_system_->Copy(this, parent, name, sync_helper->GetSuccessCallback(), sync_helper->GetErrorCallback(), DOMFileSystemBase::kSynchronous); @@ -78,7 +77,7 @@ } void EntrySync::remove(ExceptionState& exception_state) const { - VoidCallbacksSyncHelper* sync_helper = VoidCallbacksSyncHelper::Create(); + auto* sync_helper = MakeGarbageCollected<VoidCallbacksSyncHelper>(); file_system_->Remove(this, nullptr, sync_helper->GetErrorCallback(), DOMFileSystemBase::kSynchronous); sync_helper->GetResultOrThrow(exception_state);
diff --git a/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h b/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h index 89aa7d3..10bda92 100644 --- a/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h +++ b/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h
@@ -44,10 +44,6 @@ : public GarbageCollected< DOMFileSystemCallbacksSyncHelper<SuccessCallback, CallbackArg>> { public: - static DOMFileSystemCallbacksSyncHelper* Create() { - return MakeGarbageCollected<DOMFileSystemCallbacksSyncHelper>(); - } - DOMFileSystemCallbacksSyncHelper() = default; void Trace(blink::Visitor* visitor) { visitor->Trace(result_); }
diff --git a/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc b/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc index 08afe92..5ee4f8a7 100644 --- a/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc +++ b/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc
@@ -101,8 +101,7 @@ return nullptr; } - FileSystemCallbacksSyncHelper* sync_helper = - FileSystemCallbacksSyncHelper::Create(); + auto* sync_helper = MakeGarbageCollected<FileSystemCallbacksSyncHelper>(); auto callbacks = std::make_unique<FileSystemCallbacks>( sync_helper->GetSuccessCallback(), sync_helper->GetErrorCallback(), &worker, file_system_type); @@ -166,7 +165,7 @@ return nullptr; } - EntryCallbacksSyncHelper* sync_helper = EntryCallbacksSyncHelper::Create(); + auto* sync_helper = MakeGarbageCollected<EntryCallbacksSyncHelper>(); std::unique_ptr<ResolveURICallbacks> callbacks = std::make_unique<ResolveURICallbacks>(sync_helper->GetSuccessCallback(), sync_helper->GetErrorCallback(),
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc b/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc index e560be7..c0c6a49 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc
@@ -52,8 +52,8 @@ mojom::blink::CacheStoragePtrInfo cache_storage_info) : WorkerThread(*global_scope_proxy), global_scope_proxy_(global_scope_proxy), - worker_backing_thread_( - WorkerBackingThread::Create(ThreadCreationParams(GetThreadType()))), + worker_backing_thread_(std::make_unique<WorkerBackingThread>( + ThreadCreationParams(GetThreadType()))), installed_scripts_manager_(std::move(installed_scripts_manager)), cache_storage_info_(std::move(cache_storage_info)) {}
diff --git a/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc b/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc index 13b20ce..6abb770 100644 --- a/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc +++ b/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
@@ -16,47 +16,6 @@ namespace blink { -namespace { - -WebString BarcodeFormatToString( - const shape_detection::mojom::blink::BarcodeFormat format) { - switch (format) { - case shape_detection::mojom::blink::BarcodeFormat::AZTEC: - return WebString::FromUTF8("aztec"); - case shape_detection::mojom::blink::BarcodeFormat::CODE_128: - return WebString::FromUTF8("code_128"); - case shape_detection::mojom::blink::BarcodeFormat::CODE_39: - return WebString::FromUTF8("code_39"); - case shape_detection::mojom::blink::BarcodeFormat::CODE_93: - return WebString::FromUTF8("code_93"); - case shape_detection::mojom::blink::BarcodeFormat::CODABAR: - return WebString::FromUTF8("codabar"); - case shape_detection::mojom::blink::BarcodeFormat::DATA_MATRIX: - return WebString::FromUTF8("data_matrix"); - case shape_detection::mojom::blink::BarcodeFormat::EAN_13: - return WebString::FromUTF8("ean_13"); - case shape_detection::mojom::blink::BarcodeFormat::EAN_8: - return WebString::FromUTF8("ean_8"); - case shape_detection::mojom::blink::BarcodeFormat::ITF: - return WebString::FromUTF8("itf"); - case shape_detection::mojom::blink::BarcodeFormat::PDF417: - return WebString::FromUTF8("pdf417"); - case shape_detection::mojom::blink::BarcodeFormat::QR_CODE: - return WebString::FromUTF8("qr_code"); - case shape_detection::mojom::blink::BarcodeFormat::UNKNOWN: - return WebString::FromUTF8("unknown"); - case shape_detection::mojom::blink::BarcodeFormat::UPC_A: - return WebString::FromUTF8("upc_a"); - case shape_detection::mojom::blink::BarcodeFormat::UPC_E: - return WebString::FromUTF8("upc_e"); - default: - NOTREACHED() << "Invalid BarcodeFormat"; - } - return WebString(); -} - -} // namespace - BarcodeDetector* BarcodeDetector::Create(ExecutionContext* context) { return MakeGarbageCollected<BarcodeDetector>(context); } @@ -107,7 +66,7 @@ Vector<WTF::String> formats; formats.ReserveInitialCapacity(format_results.size()); for (const auto& format : format_results) - formats.push_back(BarcodeFormatToString(format)); + formats.push_back(DetectedBarcode::BarcodeFormatToString(format)); resolver->Resolve(formats); } @@ -149,7 +108,7 @@ DOMRectReadOnly::Create( barcode->bounding_box.x, barcode->bounding_box.y, barcode->bounding_box.width, barcode->bounding_box.height), - corner_points)); + barcode->format, corner_points)); } resolver->Resolve(detected_barcodes);
diff --git a/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc b/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc index 4815379b..c4a1bb2 100644 --- a/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc +++ b/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc
@@ -12,17 +12,57 @@ DetectedBarcode* DetectedBarcode::Create() { HeapVector<Member<Point2D>> empty_list; return MakeGarbageCollected<DetectedBarcode>( - g_empty_string, DOMRectReadOnly::Create(0, 0, 0, 0), empty_list); + g_empty_string, DOMRectReadOnly::Create(0, 0, 0, 0), + shape_detection::mojom::BarcodeFormat::UNKNOWN, empty_list); } DetectedBarcode* DetectedBarcode::Create( String raw_value, DOMRectReadOnly* bounding_box, + shape_detection::mojom::BarcodeFormat format, HeapVector<Member<Point2D>> corner_points) { - return MakeGarbageCollected<DetectedBarcode>(raw_value, bounding_box, + return MakeGarbageCollected<DetectedBarcode>(raw_value, bounding_box, format, corner_points); } +// static +WebString DetectedBarcode::BarcodeFormatToString( + const shape_detection::mojom::BarcodeFormat format) { + switch (format) { + case shape_detection::mojom::BarcodeFormat::AZTEC: + return WebString::FromUTF8("aztec"); + case shape_detection::mojom::BarcodeFormat::CODE_128: + return WebString::FromUTF8("code_128"); + case shape_detection::mojom::BarcodeFormat::CODE_39: + return WebString::FromUTF8("code_39"); + case shape_detection::mojom::BarcodeFormat::CODE_93: + return WebString::FromUTF8("code_93"); + case shape_detection::mojom::BarcodeFormat::CODABAR: + return WebString::FromUTF8("codabar"); + case shape_detection::mojom::BarcodeFormat::DATA_MATRIX: + return WebString::FromUTF8("data_matrix"); + case shape_detection::mojom::BarcodeFormat::EAN_13: + return WebString::FromUTF8("ean_13"); + case shape_detection::mojom::BarcodeFormat::EAN_8: + return WebString::FromUTF8("ean_8"); + case shape_detection::mojom::BarcodeFormat::ITF: + return WebString::FromUTF8("itf"); + case shape_detection::mojom::BarcodeFormat::PDF417: + return WebString::FromUTF8("pdf417"); + case shape_detection::mojom::BarcodeFormat::QR_CODE: + return WebString::FromUTF8("qr_code"); + case shape_detection::mojom::BarcodeFormat::UNKNOWN: + return WebString::FromUTF8("unknown"); + case shape_detection::mojom::BarcodeFormat::UPC_A: + return WebString::FromUTF8("upc_a"); + case shape_detection::mojom::BarcodeFormat::UPC_E: + return WebString::FromUTF8("upc_e"); + default: + NOTREACHED() << "Invalid BarcodeFormat"; + } + return WebString(); +} + const String& DetectedBarcode::rawValue() const { return raw_value_; } @@ -35,17 +75,24 @@ return corner_points_; } +String DetectedBarcode::format() const { + return DetectedBarcode::BarcodeFormatToString(format_); +} + DetectedBarcode::DetectedBarcode(String raw_value, DOMRectReadOnly* bounding_box, + shape_detection::mojom::BarcodeFormat format, HeapVector<Member<Point2D>> corner_points) : raw_value_(raw_value), bounding_box_(bounding_box), + format_(format), corner_points_(corner_points) {} ScriptValue DetectedBarcode::toJSONForBinding(ScriptState* script_state) const { V8ObjectBuilder result(script_state); result.AddString("rawValue", rawValue()); result.Add("boundingBox", boundingBox()->toJSONForBinding(script_state)); + result.AddString("format", format()); Vector<ScriptValue> corner_points; for (const auto& corner_point : corner_points_) { V8ObjectBuilder builder(script_state);
diff --git a/third_party/blink/renderer/modules/shapedetection/detected_barcode.h b/third_party/blink/renderer/modules/shapedetection/detected_barcode.h index 201a6d1..6c213af5 100644 --- a/third_party/blink/renderer/modules/shapedetection/detected_barcode.h +++ b/third_party/blink/renderer/modules/shapedetection/detected_barcode.h
@@ -5,6 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_BARCODE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_BARCODE_H_ +#include "services/shape_detection/public/mojom/barcodedetection_provider.mojom-shared.h" +#include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/modules/imagecapture/point_2d.h" #include "third_party/blink/renderer/modules/modules_export.h" @@ -22,12 +24,19 @@ static DetectedBarcode* Create(); static DetectedBarcode* Create(String, DOMRectReadOnly*, + shape_detection::mojom::BarcodeFormat, HeapVector<Member<Point2D>>); + static WebString BarcodeFormatToString( + const shape_detection::mojom::BarcodeFormat format); - DetectedBarcode(String, DOMRectReadOnly*, HeapVector<Member<Point2D>>); + DetectedBarcode(String, + DOMRectReadOnly*, + shape_detection::mojom::BarcodeFormat, + HeapVector<Member<Point2D>>); const String& rawValue() const; DOMRectReadOnly* boundingBox() const; + String format() const; const HeapVector<Member<Point2D>>& cornerPoints() const; ScriptValue toJSONForBinding(ScriptState*) const; @@ -36,6 +45,7 @@ private: const String raw_value_; const Member<DOMRectReadOnly> bounding_box_; + const shape_detection::mojom::BarcodeFormat format_; const HeapVector<Member<Point2D>> corner_points_; };
diff --git a/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl b/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl index 12682c8..aa14784 100644 --- a/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl +++ b/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl
@@ -12,6 +12,7 @@ // TODO(mcasas): Implement missing fields. https://crbug.com/646083 [SameObject] readonly attribute DOMString rawValue; [SameObject] readonly attribute DOMRectReadOnly boundingBox; + [SameObject] readonly attribute DOMString format; // 4 corner points in clockwise direction starting with top-left. Due to // possible perspective distortions, this is not necessarily a rectangle. [SameObject, SaveSameObject] readonly attribute FrozenArray<Point2D> cornerPoints;
diff --git a/third_party/blink/renderer/platform/exported/web_url_response.cc b/third_party/blink/renderer/platform/exported/web_url_response.cc index c80fcaa..7f66f2a 100644 --- a/third_party/blink/renderer/platform/exported/web_url_response.cc +++ b/third_party/blink/renderer/platform/exported/web_url_response.cc
@@ -136,8 +136,8 @@ return static_cast<HTTPVersion>(resource_response_->HttpVersion()); } -void WebURLResponse::SetHTTPVersion(HTTPVersion version) { - resource_response_->SetHTTPVersion( +void WebURLResponse::SetHttpVersion(HTTPVersion version) { + resource_response_->SetHttpVersion( static_cast<ResourceResponse::HTTPVersion>(version)); }
diff --git a/third_party/blink/renderer/platform/geometry/layout_unit.h b/third_party/blink/renderer/platform/geometry/layout_unit.h index 72c6399..7abd3c55 100644 --- a/third_party/blink/renderer/platform/geometry/layout_unit.h +++ b/third_party/blink/renderer/platform/geometry/layout_unit.h
@@ -139,7 +139,7 @@ constexpr int RawValue() const { return value_; } inline void SetRawValue(int value) { value_ = value; } - void SetRawValue(long long value) { + void SetRawValue(int64_t value) { REPORT_OVERFLOW(value > std::numeric_limits<int>::min() && value < std::numeric_limits<int>::max()); value_ = static_cast<int>(value); @@ -435,8 +435,8 @@ inline LayoutUnit operator/(const LayoutUnit& a, const LayoutUnit& b) { LayoutUnit return_val; - long long raw_val = static_cast<long long>(kFixedPointDenominator) * - a.RawValue() / b.RawValue(); + int64_t raw_val = static_cast<int64_t>(kFixedPointDenominator) * + a.RawValue() / b.RawValue(); return_val.SetRawValue(base::saturated_cast<int>(raw_val)); return return_val; } @@ -546,8 +546,8 @@ // This calculates the modulo so that: a = (a / b) * b + LayoutMod(a, b). inline LayoutUnit LayoutMod(const LayoutUnit& a, const LayoutUnit& b) { LayoutUnit return_val; - long long raw_val = - (static_cast<long long>(kFixedPointDenominator) * a.RawValue()) % + int64_t raw_val = + (static_cast<int64_t>(kFixedPointDenominator) * a.RawValue()) % b.RawValue(); return_val.SetRawValue(raw_val / kFixedPointDenominator); return return_val;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_response.h b/third_party/blink/renderer/platform/loader/fetch/resource_response.h index c795043..fd92f2e 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_response.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_response.h
@@ -244,7 +244,7 @@ void SetResourceLoadInfo(scoped_refptr<ResourceLoadInfo>); HTTPVersion HttpVersion() const { return http_version_; } - void SetHTTPVersion(HTTPVersion version) { http_version_ = version; } + void SetHttpVersion(HTTPVersion version) { http_version_ = version; } int RequestId() const { return request_id_; } void SetRequestId(int request_id) { request_id_ = request_id; }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 3582e91..a051538 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1339,7 +1339,7 @@ { name: "StaleWhileRevalidate", origin_trial_feature_name: "StaleWhileRevalidate", - status: "experimental", + status: "stable", }, { name: "StorageQuotaDetails",
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc index c2f50406..4167536 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc
@@ -27,7 +27,8 @@ InitDefaultQueues(default_task_queue_, control_task_queue_, TaskType::kMainThreadTaskQueueDefault); sequence_manager_->EnableCrashKeys("blink_scheduler_task_file_name", - "blink_scheduler_task_function_name"); + "blink_scheduler_task_function_name", + "blink_scheduler_async_stack"); } MainThreadSchedulerHelper::~MainThreadSchedulerHelper() {
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 51b38dc..524cb999 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -6032,7 +6032,6 @@ # Sheriff 2019-03-01 crbug.com/937170 [ Linux Win7 ] external/wpt/IndexedDB/interleaved-cursors-large.html [ Pass Timeout Crash ] crbug.com/937312 [ Win7 ] external/wpt/background-fetch/fetch.https.window.html [ Pass Timeout ] -crbug.com/893659 [ Mac ] virtual/threaded/fast/events/pointerevents/pinch/pointerevent_touch-action-pinch_zoom_touch.html [ Pass Failure Crash ] crbug.com/937378 [ Win7 ] http/tests/devtools/service-workers/service-workers-force-update-on-page-load.js [ Pass Timeout ] crbug.com/864994 [ Linux Win7 ] external/wpt/encoding/legacy-mb-korean/euc-kr/euckr-decode-ksc_5601.html [ Timeout Failure Pass ] crbug.com/937416 [ Linux Mac ] http/tests/devtools/resource-tree/resource-tree-htmlimports.js [ Pass Failure ] @@ -6078,5 +6077,5 @@ crbug.com/836242 [ Linux ] fast/loader/reload-zero-byte-plugin.html [ Pass Failure ] crbug.com/836242 [ Mac ] fast/loader/reload-zero-byte-plugin.html [ Pass Failure ] crbug.com/836242 [ Win ] fast/loader/reload-zero-byte-plugin.html [ Pass Failure ] -crbug.com/806357 [ Linux Win ] virtual/threaded/fast/events/pointerevents/pinch/pointerevent_touch-action-pinch_zoom_touch.html [ Pass Failure ] +crbug.com/806357 virtual/threaded/fast/events/pointerevents/pinch/pointerevent_touch-action-pinch_zoom_touch.html [ Pass Failure Crash ] crbug.com/941931 [ Linux Win ] http/tests/security/contentSecurityPolicy/1.1/plugintypes-affects-cross-site-child-disallowed.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-cross-origin-with-click.sub.tentative.html b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-cross-origin-with-click.sub.tentative.html index dca44dd..e7d98c3b1 100644 --- a/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-cross-origin-with-click.sub.tentative.html +++ b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-cross-origin-with-click.sub.tentative.html
@@ -12,7 +12,8 @@ <script src="/resources/testdriver-vendor.js"></script> </head> <body> - <h1>User activation can be transferred to a cross-origin child frame via a postMessage option.</h1> + <h1>User activation can be transferred to a cross-origin child frame + via a postMessage option.</h1> <ol id="instructions"> <li>Click this instruction text. </ol> @@ -35,6 +36,8 @@ } else if (msg.type == 'child-four-report') { assert_true(msg.isActive); assert_true(msg.hasBeenActive); + + // check sender's activation state again assert_false(navigator.userActivation.isActive); assert_false(navigator.userActivation.hasBeenActive); t.done(); @@ -45,7 +48,12 @@ assert_true(navigator.userActivation.hasBeenActive); // transfer user activation to the child frame - child.contentWindow.postMessage("transfer_user_activation", {targetOrigin: "*", transferUserActivation: true}); + child.contentWindow.postMessage("transfer_user_activation", + {targetOrigin: "*", transferUserActivation: true}); + + // sender's activation state is updated synchronously + assert_false(navigator.userActivation.isActive); + assert_false(navigator.userActivation.hasBeenActive); })); child.src = "http://{{domains[www]}}:{{ports[http][0]}}/html/user-activation/resources/child-four.html"; }, "Cross-origin user activation transfer through postMessages");
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-with-click.tentative.html b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-with-click.tentative.html index ebb4f5f..6b7a2b72 100644 --- a/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-with-click.tentative.html +++ b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-with-click.tentative.html
@@ -12,7 +12,8 @@ <script src="/resources/testdriver-vendor.js"></script> </head> <body> - <h1>User activation can be transferred to a child frame via a postMessage option.</h1> + <h1>User activation can be transferred to a child frame + via a postMessage option.</h1> <ol id="instructions"> <li>Click this instruction text. </ol> @@ -35,6 +36,8 @@ } else if (msg.type == 'child-four-report') { assert_true(msg.isActive); assert_true(msg.hasBeenActive); + + // check sender's activation state again assert_false(navigator.userActivation.isActive); assert_false(navigator.userActivation.hasBeenActive); t.done(); @@ -45,7 +48,12 @@ assert_true(navigator.userActivation.hasBeenActive); // transfer user activation to the child frame - child.contentWindow.postMessage("transfer_user_activation", {transferUserActivation: true}); + child.contentWindow.postMessage("transfer_user_activation", + {transferUserActivation: true}); + + // sender's activation state is updated synchronously + assert_false(navigator.userActivation.isActive); + assert_false(navigator.userActivation.hasBeenActive); })); child.src = "resources/child-four.html"; }, "User activation transfer through postMessages");
diff --git a/third_party/blink/web_tests/external/wpt/shape-detection/idlharness.any-expected.txt b/third_party/blink/web_tests/external/wpt/shape-detection/idlharness.any-expected.txt index a2c26dc..da45152 100644 --- a/third_party/blink/web_tests/external/wpt/shape-detection/idlharness.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/shape-detection/idlharness.any-expected.txt
@@ -35,7 +35,7 @@ PASS DetectedBarcode interface: existence and properties of interface prototype object's @@unscopables property PASS DetectedBarcode interface: attribute boundingBox PASS DetectedBarcode interface: attribute rawValue -FAIL DetectedBarcode interface: attribute format assert_true: The prototype object must have a property "format" expected true got false +PASS DetectedBarcode interface: attribute format PASS DetectedBarcode interface: attribute cornerPoints Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-basic-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-basic-expected.txt new file mode 100644 index 0000000..6087216 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-basic-expected.txt
@@ -0,0 +1,16 @@ +Tests basic function of the BackgroundService domain. +Found error: Invalid service name +Enabled successfully: true +{ + isRecording : false + service : backgroundSync +} +{ + isRecording : true + service : backgroundSync +} +{ + isRecording : false + service : backgroundSync +} +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-basic.js b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-basic.js new file mode 100644 index 0000000..c4db6ea --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-basic.js
@@ -0,0 +1,30 @@ +(async function(testRunner) { + + const {page, session, dp} = await testRunner.startBlank( + `Tests basic function of the BackgroundService domain.`); + + // Enable non-existant service. + let result = await dp.BackgroundService.startObserving({service: 'fakeservice'}); + testRunner.log(`Found error: ${result.error.message}`); + + // Enable actual service. + result = await dp.BackgroundService.startObserving({service: 'backgroundFetch'}); + testRunner.log(`Enabled successfully: ${!result.error}`); + + // Enabling a Service should return the recording state. + dp.BackgroundService.startObserving({service: 'backgroundSync'}); + result = await dp.BackgroundService.onceRecordingStateChanged(); + testRunner.log(result.params); + + // Enable recording. + dp.BackgroundService.setRecording({shouldRecord: true, service: 'backgroundSync'}); + result = await dp.BackgroundService.onceRecordingStateChanged(); + testRunner.log(result.params); + + // Disable recording. + dp.BackgroundService.setRecording({shouldRecord: false, service: 'backgroundSync'}); + result = await dp.BackgroundService.onceRecordingStateChanged(); + testRunner.log(result.params); + + testRunner.completeTest(); +});
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-clear-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-clear-expected.txt new file mode 100644 index 0000000..2efe20b --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-clear-expected.txt
@@ -0,0 +1,6 @@ +Tests that background service events are received when appropriate. +Has events initially: false +Completed "my-fetch-with-recording" +Has events with recording on: true +Has events initially: false +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-clear.js b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-clear.js new file mode 100644 index 0000000..56a0243 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-clear.js
@@ -0,0 +1,35 @@ +(async function(testRunner) { + var {page, session, dp} = await testRunner.startURL( + 'resources/background-services.html', + `Tests that background service events are received when appropriate.`); + + await session.evaluateAsync('installSW()'); + + let receivedEvent = false; + dp.BackgroundService.onBackgroundServiceEventReceived(() => receivedEvent = true); + + dp.BackgroundService.startObserving({service: 'backgroundFetch'}); + await dp.BackgroundService.onceRecordingStateChanged(); + // Initially there should be zero logged events. + testRunner.log(`Has events initially: ${receivedEvent}`); + + dp.BackgroundService.setRecording({shouldRecord: true, service: 'backgroundFetch'}); + await dp.BackgroundService.onceRecordingStateChanged(); + session.evaluate(`sw.backgroundFetch.fetch('my-fetch-with-recording', '/')`); + testRunner.log(await session.evaluateAsync('waitForMessageFromSW()')); + // Events should have been received since `Recording` is on. + testRunner.log(`Has events with recording on: ${receivedEvent}`); + + // Reset parameters and clear the stored events. + receivedEvent = false; + dp.BackgroundService.setRecording({shouldRecord: false, service: 'backgroundFetch'}); + await dp.BackgroundService.onceRecordingStateChanged(); + dp.BackgroundService.clearEvents({service: 'backgroundFetch'}); + dp.BackgroundService.stopObserving({service: 'backgroundFetch'}); + + // There shouldn't be any events now that they have been cleared. + await dp.BackgroundService.startObserving({service: 'backgroundFetch'}); + testRunner.log(`Has events initially: ${receivedEvent}`); + + testRunner.completeTest(); +});
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-event-updates-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-event-updates-expected.txt new file mode 100644 index 0000000..e0ac252 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-event-updates-expected.txt
@@ -0,0 +1,8 @@ +Tests that background service events are received when appropriate. +Has events initially: false +Completed "my-fetch-no-recording" +Has events with recording off: false +Completed "my-fetch-with-recording" +Has events with recording on: true +Has events initially: true +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-event-updates.js b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-event-updates.js new file mode 100644 index 0000000..2b3984f --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/background-services-event-updates.js
@@ -0,0 +1,38 @@ +(async function(testRunner) { + var {page, session, dp} = await testRunner.startURL( + 'resources/background-services.html', + `Tests that background service events are received when appropriate.`); + + await session.evaluateAsync('installSW()'); + + let receivedEvent = false; + dp.BackgroundService.onBackgroundServiceEventReceived(() => receivedEvent = true); + + await dp.BackgroundService.startObserving({service: 'backgroundFetch'}); + // Initially there should be zero logged events. + testRunner.log(`Has events initially: ${receivedEvent}`); + + session.evaluate(`sw.backgroundFetch.fetch('my-fetch-no-recording', '/')`); + testRunner.log(await session.evaluateAsync('waitForMessageFromSW()')); + // No events should be received since `Recording` is off. + testRunner.log(`Has events with recording off: ${receivedEvent}`); + + dp.BackgroundService.setRecording({shouldRecord: true, service: 'backgroundFetch'}); + await dp.BackgroundService.onceRecordingStateChanged(); + session.evaluate(`sw.backgroundFetch.fetch('my-fetch-with-recording', '/')`); + testRunner.log(await session.evaluateAsync('waitForMessageFromSW()')); + // Events should have been received since `Recording` is on. + testRunner.log(`Has events with recording on: ${receivedEvent}`); + + // Reset parameters. + receivedEvent = false; + dp.BackgroundService.setRecording({shouldRecord: false, service: 'backgroundFetch'}); + await dp.BackgroundService.onceRecordingStateChanged(); + dp.BackgroundService.stopObserving({service: 'backgroundFetch'}); + + await dp.BackgroundService.startObserving({service: 'backgroundFetch'}); + // We should receive the logged events initially even with recording off. + testRunner.log(`Has events initially: ${receivedEvent}`); + + testRunner.completeTest(); +});
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/background-services.html b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/background-services.html new file mode 100644 index 0000000..99e426c1 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/background-services.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<head> +<title>Service Worker for a background service test</title> +<script> + +let sw = null; + +async function installSW() { + sw = await navigator.serviceWorker.register('service-worker.js'); + await navigator.serviceWorker.ready; + sw.active.postMessage('Posting message!'); +} + +async function waitForMessageFromSW() { + return await new Promise( + resolve => navigator.serviceWorker.onmessage = e => resolve(e.data)); +} + +</script> +</head> +<body></body> +</html>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/service-worker.js b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/service-worker.js new file mode 100644 index 0000000..c9870ca --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/background-services/resources/service-worker.js
@@ -0,0 +1,9 @@ +async function postMessageToWindow(msg) { + const matchedClients = await clients.matchAll({includeUncontrolled: true}); + for (const client of matchedClients) + client.postMessage(msg); +} + +self.addEventListener( + 'backgroundfetchsuccess', + event => postMessageToWindow(`Completed "${event.registration.id}"`));
diff --git a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png index bd478a62..af5f21f1 100644 --- a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png +++ b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png index 7c7e327..f2469d0 100644 --- a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png +++ b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/12-55-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/12-55-expected.png index 1f91feda..f38df4d 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/12-55-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/12-55-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/182-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/182-expected.png index 61887f59..f9ea39f 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/182-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/182-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/2-dht-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/2-dht-expected.png index a3f6eaf..483b603 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/2-dht-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/2-dht-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/23-55-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/23-55-expected.png index fedf2451..06fa592 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/23-55-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/23-55-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/55-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/55-expected.png index a388772..6762251 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/55-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/55-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png index 1acaaf0..2368484 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png index bea8973..746dd01 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png index 43f64621..a2a7e4f 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png index fb927f7..71492a8 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-css-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-css-expected.png index a3018ee..5f34bcf 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-css-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-css-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-expected.png index ae08025b..de03609 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png index 26d18f7..ba74f14 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/favicon-as-image-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/favicon-as-image-expected.png index f14e1330..3bf27c1 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/favicon-as-image-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/favicon-as-image-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-edge-cases-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-edge-cases-expected.png index 9879c7d..81a0dfa9 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-edge-cases-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-edge-cases-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png index aa60ad5..da6882a 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.txt new file mode 100644 index 0000000..e9416b3 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.txt
@@ -0,0 +1,6 @@ +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-forced-layout-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-forced-layout-expected.png index ad4cdc6..c2ca27a3 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-forced-layout-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-forced-layout-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-responsive-image-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-responsive-image-expected.png index 6cb1553..0e70bc8 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-responsive-image-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-responsive-image-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-styles-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-styles-expected.png index 21cb653..5c18807 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-styles-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-styles-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/image-map-anchor-children-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/image-map-anchor-children-expected.png index 1557bdf5..5da2590 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/image-map-anchor-children-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/image-map-anchor-children-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png index 8bc8e30..d18d15c 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png index b855fae2..9e0c2cc 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png index 6df2bc3..8521d6ba 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png index d11b4b18..7db3caa 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png index 2123c16..7bc1471 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png index 368152fc..80ae5b78 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png index 2a102ee..6e0a7aa 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png index b023864..41cdec4 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png index d08378ab..4a7edaee 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png index 201244f5..97253a14 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png index eb32dbc..aada43e 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png index b47f876..db6cafd 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/pixel-crack-image-background-webkit-transform-scale-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/pixel-crack-image-background-webkit-transform-scale-expected.png index b3939dc..c9b5810 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/pixel-crack-image-background-webkit-transform-scale-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/pixel-crack-image-background-webkit-transform-scale-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png index d62551f..f6aac27 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png index 6c0766a..7a901aeb 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png index 23e531e..5e04d3c 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png index ee9b5c5f..fedf2f9 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png index 8bbb7e4..d96e05d6 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png index 42fa90e..64b9c59b 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-expected.png index ad300ea..92dfb008 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/scroll_customization/fast/events/touch/multi-touch-user-gesture-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/scroll_customization/fast/events/touch/multi-touch-user-gesture-expected.txt new file mode 100644 index 0000000..61a5134 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/scroll_customization/fast/events/touch/multi-touch-user-gesture-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Test user gesture behavior during multi-finger touch events. assert_equals: expected "touchstart@target1(false), touchstart@target2(false), touchmove@target1(false), touchmove@target2(false), touchend@target1(true), touchend@target2(true)" but got "touchstart@target1(false), touchstart@target2(false), touchmove@target2(false), touchmove@target1(false), touchend@target1(true), touchend@target2(true)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac/fast/events/touch/multi-touch-user-gesture-expected.txt b/third_party/blink/web_tests/platform/mac/fast/events/touch/multi-touch-user-gesture-expected.txt new file mode 100644 index 0000000..61a5134 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/fast/events/touch/multi-touch-user-gesture-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Test user gesture behavior during multi-finger touch events. assert_equals: expected "touchstart@target1(false), touchstart@target2(false), touchmove@target1(false), touchmove@target2(false), touchend@target1(true), touchend@target2(true)" but got "touchstart@target1(false), touchstart@target2(false), touchmove@target2(false), touchmove@target1(false), touchend@target1(true), touchend@target2(true)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png b/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png index 396cceda0..5bbaf24 100644 --- a/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png +++ b/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png b/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png index b0ce6b9..e3d3e15 100644 --- a/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png +++ b/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png index a736ed1..ca93bc953 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png index 1caf1f5..fdb18a28 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png index 1918867..d42a7941 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/image-map-anchor-children-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/image-map-anchor-children-expected.png index 4f1c80e..30a3c0ba 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/image-map-anchor-children-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/image-map-anchor-children-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png index db7d836f..f5c8a71 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png index 1ff122a..2b82dcf 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png index 03884e6..e727603 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png index 7e7ff5b7..3d9b736 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png index 96e8a35..6ab669dd 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png index 0c6a756..705df7f 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png index 7a4bdb74..890e7744 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png index 47a71898..fa4e40f3 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png index 281176ed..3de2dbf 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png index 50a38bc..a3d58a6 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png index 1495b74..a3a6752 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png index 9b79ee5..44982e9 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png b/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png index 0aeb2da..e59f7e4f 100644 --- a/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png +++ b/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png b/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png index 356ea4f85..eb1456c4 100644 --- a/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png +++ b/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png index 5bdaf81..2616aa00 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png index c631562..c7bd016 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png index 4708b520..266834369 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png index 4769870..3c75d67 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png index 3be9597..94ac255 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png index e713bcb..8f58f48 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png index 2834530..5b6e63e 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png index 49d3b534..efca9837 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png index 4c4385c..425e555e 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png index cccfc99..7e99a0be 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png index 2858fa6..b3756a6 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png index 6929b29..4274da1 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png index 066f33b..8414dc3 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.txt new file mode 100644 index 0000000..e294d225 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.txt
@@ -0,0 +1,12 @@ +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
diff --git a/third_party/blink/web_tests/shapedetection/detection-HTMLCanvasElement.html b/third_party/blink/web_tests/shapedetection/detection-HTMLCanvasElement.html index 2c07c4f..941bed8 100644 --- a/third_party/blink/web_tests/shapedetection/detection-HTMLCanvasElement.html +++ b/third_party/blink/web_tests/shapedetection/detection-HTMLCanvasElement.html
@@ -64,7 +64,9 @@ function BarcodeDetectorDetectionResultTest(detectionResult, mock) { assert_equals(detectionResult.length, 2, "Number of barcodes"); assert_equals(detectionResult[0].rawValue, "cats", "barcode 1"); + assert_equals(detectionResult[0].format, "qr_code", "barcode 1 format"); assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2"); + assert_equals(detectionResult[1].format, "code_128", "barcode 2 format"); } function TextDetectorDetectionResultTest(detectionResult, mock) {
diff --git a/third_party/blink/web_tests/shapedetection/detection-HTMLImageElement.html b/third_party/blink/web_tests/shapedetection/detection-HTMLImageElement.html index 3e0ea812..5f68203 100644 --- a/third_party/blink/web_tests/shapedetection/detection-HTMLImageElement.html +++ b/third_party/blink/web_tests/shapedetection/detection-HTMLImageElement.html
@@ -54,7 +54,9 @@ function BarcodeDetectorDetectionResultTest(detectionResult, mock) { assert_equals(detectionResult.length, 2, "Number of barcodes"); assert_equals(detectionResult[0].rawValue, "cats", "barcode 1"); + assert_equals(detectionResult[0].format, "qr_code", "barcode 1 format"); assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2"); + assert_equals(detectionResult[1].format, "code_128", "barcode 2 format"); } function TextDetectorDetectionResultTest(detectionResult, mock) {
diff --git a/third_party/blink/web_tests/shapedetection/detection-HTMLVideoElement.html b/third_party/blink/web_tests/shapedetection/detection-HTMLVideoElement.html index 0a3fa39a..682b0921 100644 --- a/third_party/blink/web_tests/shapedetection/detection-HTMLVideoElement.html +++ b/third_party/blink/web_tests/shapedetection/detection-HTMLVideoElement.html
@@ -46,7 +46,9 @@ function BarcodeDetectorDetectionResultTest(detectionResult, mock) { assert_equals(detectionResult.length, 2, "Number of barcodes"); assert_equals(detectionResult[0].rawValue, "cats", "barcode 1"); + assert_equals(detectionResult[0].format, "qr_code", "barcode 1 format"); assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2"); + assert_equals(detectionResult[1].format, "code_128", "barcode 2 format"); } function TextDetectorDetectionResultTest(detectionResult, mock) {
diff --git a/third_party/blink/web_tests/shapedetection/detection-ImageBitmap.html b/third_party/blink/web_tests/shapedetection/detection-ImageBitmap.html index ba6e07b9..4f64ac72 100644 --- a/third_party/blink/web_tests/shapedetection/detection-ImageBitmap.html +++ b/third_party/blink/web_tests/shapedetection/detection-ImageBitmap.html
@@ -46,7 +46,9 @@ function BarcodeDetectorDetectionResultTest(detectionResult, mock) { assert_equals(detectionResult.length, 2, "Number of barcodes"); assert_equals(detectionResult[0].rawValue, "cats", "barcode 1"); + assert_equals(detectionResult[0].format, "qr_code", "barcode 1 format"); assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2"); + assert_equals(detectionResult[1].format, "code_128", "barcode 2 format"); } function TextDetectorDetectionResultTest(detectionResult, mock) {
diff --git a/third_party/blink/web_tests/shapedetection/detection-ImageData.html b/third_party/blink/web_tests/shapedetection/detection-ImageData.html index 4120dcd..4f9d102 100644 --- a/third_party/blink/web_tests/shapedetection/detection-ImageData.html +++ b/third_party/blink/web_tests/shapedetection/detection-ImageData.html
@@ -50,7 +50,9 @@ function BarcodeDetectorDetectionResultTest(detectionResult, mock) { assert_equals(detectionResult.length, 2, "Number of barcodes"); assert_equals(detectionResult[0].rawValue, "cats", "barcode 1"); + assert_equals(detectionResult[0].format, "qr_code", "barcode 1 format"); assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2"); + assert_equals(detectionResult[1].format, "code_128", "barcode 2 format"); } function TextDetectorDetectionResultTest(detectionResult, mock) {
diff --git a/third_party/blink/web_tests/shapedetection/detector-same-object.html b/third_party/blink/web_tests/shapedetection/detector-same-object.html index 67751d8..6d595fd 100644 --- a/third_party/blink/web_tests/shapedetection/detector-same-object.html +++ b/third_party/blink/web_tests/shapedetection/detector-same-object.html
@@ -48,6 +48,7 @@ assert_greater_than(detectedBarcodes.length, 0, "Number of barcodes"); assert_equals(detectedBarcodes[0].rawValue, detectedBarcodes[0].rawValue); assert_equals(detectedBarcodes[0].boundingBox, detectedBarcodes[0].boundingBox); + assert_equals(detectedBarcodes[0].format, detectedBarcodes[0].format); assert_equals(detectedBarcodes[0].cornerPoints, detectedBarcodes[0].cornerPoints); }
diff --git a/third_party/blink/web_tests/shapedetection/resources/mock-barcodedetection.js b/third_party/blink/web_tests/shapedetection/resources/mock-barcodedetection.js index b542ca5..4ee47f0 100644 --- a/third_party/blink/web_tests/shapedetection/resources/mock-barcodedetection.js +++ b/third_party/blink/web_tests/shapedetection/resources/mock-barcodedetection.js
@@ -50,6 +50,7 @@ { rawValue : "cats", boundingBox: { x: 1.0, y: 1.0, width: 100.0, height: 100.0 }, + format: shapeDetection.mojom.BarcodeFormat.QR_CODE, cornerPoints: [ { x: 1.0, y: 1.0 }, { x: 101.0, y: 1.0 }, @@ -60,6 +61,7 @@ { rawValue : "dogs", boundingBox: { x: 2.0, y: 2.0, width: 50.0, height: 50.0 }, + format: shapeDetection.mojom.BarcodeFormat.CODE_128, cornerPoints: [ { x: 2.0, y: 2.0 }, { x: 52.0, y: 2.0 },
diff --git a/third_party/blink/web_tests/svg/filters/feImage-preserveAspectRatio-all-expected.png b/third_party/blink/web_tests/svg/filters/feImage-preserveAspectRatio-all-expected.png index 7c626e7..d52e71d 100644 --- a/third_party/blink/web_tests/svg/filters/feImage-preserveAspectRatio-all-expected.png +++ b/third_party/blink/web_tests/svg/filters/feImage-preserveAspectRatio-all-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/svg/filters/feImage-preserveAspectratio-expected.png b/third_party/blink/web_tests/svg/filters/feImage-preserveAspectratio-expected.png index cfe069d..6336afe1 100644 --- a/third_party/blink/web_tests/svg/filters/feImage-preserveAspectratio-expected.png +++ b/third_party/blink/web_tests/svg/filters/feImage-preserveAspectratio-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/svg/filters/filteredImage-expected.png b/third_party/blink/web_tests/svg/filters/filteredImage-expected.png index fec75dc..aa1a9b3 100644 --- a/third_party/blink/web_tests/svg/filters/filteredImage-expected.png +++ b/third_party/blink/web_tests/svg/filters/filteredImage-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/dark-mode/paint/dark-mode/image-filter-all/image-invert-expected.png b/third_party/blink/web_tests/virtual/dark-mode/paint/dark-mode/image-filter-all/image-invert-expected.png index bc6b96e..2aa2c0b8 100644 --- a/third_party/blink/web_tests/virtual/dark-mode/paint/dark-mode/image-filter-all/image-invert-expected.png +++ b/third_party/blink/web_tests/virtual/dark-mode/paint/dark-mode/image-filter-all/image-invert-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png b/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png index 212a5e11..e2cbbdf 100644 --- a/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png +++ b/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png b/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png index 0e6cc0a..42c84084 100644 --- a/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png +++ b/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png b/third_party/blink/web_tests/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png index 45c5653..3a286c2 100644 --- a/third_party/blink/web_tests/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png +++ b/third_party/blink/web_tests/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index df01222..c546aef 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -1475,6 +1475,7 @@ attribute @@toStringTag getter boundingBox getter cornerPoints + getter format getter rawValue method constructor method toJSON
diff --git a/third_party/yasm/BUILD.gn b/third_party/yasm/BUILD.gn index 35a85b1..6e245fe 100644 --- a/third_party/yasm/BUILD.gn +++ b/third_party/yasm/BUILD.gn
@@ -55,6 +55,12 @@ # highbd_sad4d_sse2.asm on Windows this saves about 15 s. configs_to_delete += [ "//build/config/win:default_crt" ] configs_to_add += [ "//build/config/win:release_crt" ] + + # Without no_default_deps, an implicit dependency on libc++ is added. + # libc++ may have been built referencing the debug CRT, but since we're + # explicitly using the release CRT, this would result in undefined symbol + # errors when linking, so we need to remove the implicit libc++ dependency. + no_default_deps = true } }
diff --git a/tools/code_coverage/coverage_test.py b/tools/code_coverage/coverage_test.py index ab9bf5b..df944cf9 100755 --- a/tools/code_coverage/coverage_test.py +++ b/tools/code_coverage/coverage_test.py
@@ -8,8 +8,16 @@ import re import shutil import subprocess +import sys import unittest +# Appends third_party/ so that coverage_utils can import jinja2 from +# third_party/, note that this is not done inside coverage_utils because +# coverage_utils is also used outside of Chromium source tree. +sys.path.append( + os.path.join( + os.path.dirname(__file__), os.path.pardir, os.path.pardir, + 'third_party')) import coverage_utils
diff --git a/tools/metrics/common/models.py b/tools/metrics/common/models.py index 78a2395..f923f8f 100644 --- a/tools/metrics/common/models.py +++ b/tools/metrics/common/models.py
@@ -13,6 +13,7 @@ """ import abc +import re from xml.dom import minidom import pretty_print_xml @@ -222,9 +223,10 @@ Args: tag: The name of XML tag for this type of node. - attributes: A list of (name, type) pairs, e.g. [('foo', unicode)]. The - order of the attributes determines the ordering of attributes, when - serializing objects to XML. + attributes: A list of (name, type, regex) tubles, e.g. [('foo', unicode, + r'^\w+$')]. The order of the attributes determines the ordering of + attributes, when serializing objects to XML. The "regex" can be None + to do no validation, otherwise the attribute must match that pattern. text_attribute: An attribute stored in the text content of the node. children: A list of ChildTypes describing the objects children. @@ -241,7 +243,7 @@ self.attributes = attributes or [] self.children = children or [] self.text_attribute = text_attribute - if len(self.attributes) != len(dict(self.attributes)): + if len(self.attributes) != len(set(a for a, _, _ in self.attributes)): raise ValueError('Duplicate attribute definition.') def __str__(self): @@ -263,9 +265,13 @@ obj[COMMENT_KEY] = GetCommentsForNode(node) - for attr, attr_type in self.attributes: + for attr, attr_type, attr_re in self.attributes: if node.hasAttribute(attr): obj[attr] = attr_type(node.getAttribute(attr)) + if attr_re is not None: + if not re.match(attr_re, obj[attr]): + raise ValueError('%s "%s" does not match regex "%s"' % + (attr, obj[attr], attr_re)) if self.text_attribute and node.firstChild: obj[self.text_attribute] = node.firstChild.nodeValue @@ -290,7 +296,7 @@ An XML node encoding the object. """ node = doc.createElement(self.tag) - for attr, _ in self.attributes: + for attr, _, _ in self.attributes: if attr in obj: node.setAttribute(attr, str(obj[attr])) @@ -322,7 +328,7 @@ Returns: A list of names of XML attributes, sorted by the order they should appear. """ - return [attr for attr, _ in self.attributes] + return [attr for attr, _, _ in self.attributes] def GetNodeTypes(self): """Get a map of tags to node types for all dependent types.
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index e11cb721..568c3371 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -5185,6 +5185,11 @@ <int value="1" label="HTTP cache hit"/> </enum> +<enum name="BooleanFullScreen"> + <int value="0" label="Window Mode"/> + <int value="1" label="Full Screen Mode"/> +</enum> + <enum name="BooleanGAIAWebViewFlow"> <int value="0" label="iframe-based flow"/> <int value="1" label="WebView-based flow"/> @@ -5535,6 +5540,11 @@ <int value="1" label="Overlapped"/> </enum> +<enum name="BooleanOverlayDamageRect"> + <int value="0" label="Zero damage rect"/> + <int value="1" label="Non-Zero damage rect"/> +</enum> + <enum name="BooleanOverlaySupported"> <int value="0" label="No overlays supported"/> <int value="1" label="Supports overlays"/> @@ -5803,6 +5813,11 @@ <int value="1" label="Translated"/> </enum> +<enum name="BooleanUnderlay"> + <int value="0" label="Overlay Mode"/> + <int value="1" label="Underlay Mode"/> +</enum> + <enum name="BooleanUninstallable"> <int value="0" label="Not uninstallable"/> <int value="1" label="Uninstallable"/> @@ -16002,6 +16017,7 @@ <int value="534" label="RemoteAccessHostAllowFileTransfer"/> <int value="535" label="DeviceWilcoDtcConfig"/> <int value="536" label="SpellcheckLanguageBlacklist"/> + <int value="537" label="DeviceWiFiAllowed"/> </enum> <enum name="EnterprisePolicyInvalidations"> @@ -30028,6 +30044,15 @@ <int value="6" label="Migration stopped"/> </enum> +<enum name="KidsManagementURLCheckerResponseStatus"> + <int value="0" label="Success"/> + <int value="1" label="Network Error"/> + <int value="2" label="Unexpected Classification Value"/> + <int value="3" label="Parsing Error"/> + <int value="4" label="Token Error"/> + <int value="5" label="Http Error"/> +</enum> + <enum name="KioskLaunchError"> <int value="0" label="No error"/> <int value="1" label="Has pending launch"/> @@ -54210,6 +54235,13 @@ <int value="7" label="kNoStore"/> </enum> +<enum name="UnderlayDamageRect"> + <int value="0" label="Zero Damage Rect"/> + <int value="1" label="Non-Occluding Damage Only"/> + <int value="2" label="Occluding Damage Only"/> + <int value="3" label="Occluding and Non-Occluding Damages"/> +</enum> + <enum name="UnifiedConsentBumpAction"> <int value="0" label="Opt into Unified Consent was clicked"/> <int value="1" label="More options: Opt into Unified Consent was selected"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 676bc96..8e12354 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -40192,6 +40192,26 @@ </summary> </histogram> +<histogram name="GPU.DirectComposition.FullScreenOverlay" + enum="BooleanFullScreen" expires_after="2020-12-31"> + <owner>magchen@chromium.org</owner> + <owner>zmo@chromium.org</owner> + <summary> + Recorded for each overlay/underlay quad during the video playback whether + the video is played in full screen mode + </summary> +</histogram> + +<histogram name="GPU.DirectComposition.IsUnderlay" enum="BooleanUnderlay" + expires_after="2020-12-31"> + <owner>magchen@chromium.org</owner> + <owner>zmo@chromium.org</owner> + <summary> + Recorded for each video quad during the video playback whether it is an + underlay or an overlay + </summary> +</histogram> + <histogram name="GPU.DirectComposition.OverlayFormatUsed" enum="OverlayFormat"> <obsolete> Deprecated 10/2018. Replaced by GPU.DirectComposition.OverlayFormatUsed2. @@ -47206,6 +47226,39 @@ </summary> </histogram> +<histogram name="ManagedUsers.KidsManagementClassifyUrlFailureDelay" units="ms"> + <owner>escordeiro@chromium.org</owner> + <owner>unichrome-eng@google.com</owner> + <summary> + The extra page load delays introduced by network requests due to the + supervised user url filtering feature, measured once per page load, for + failed requests. This is the delay to fetch the token and call the + ClassifyUrl rpc, when there is a cache miss. + </summary> +</histogram> + +<histogram name="ManagedUsers.KidsManagementClassifyUrlSuccessDelay" units="ms"> + <owner>escordeiro@chromium.org</owner> + <owner>unichrome-eng@google.com</owner> + <summary> + The extra page load delays introduced by network requests due to the + supervised user url filtering feature, measured once per page load. This is + the delay to fetch the token and call the ClassifyUrl rpc, when there is a + cache miss. Only recorded for successful requests. + </summary> +</histogram> + +<histogram name="ManagedUsers.KidsManagementUrlCheckerResponseStatus" + enum="KidsManagementURLCheckerResponseStatus"> + <owner>escordeiro@chromium.org</owner> + <owner>unichrome-eng@google.com</owner> + <summary> + The counts of response status from supervised user + KidsManagementURLCheckerCLient. Each entry includes the outcome of a request + (i.e. success, net error, parsing error). + </summary> +</histogram> + <histogram name="ManagedUsers.SafeSitesDelay" units="ms"> <owner>treib@chromium.org</owner> <owner>escordeiro@chromium.org</owner> @@ -117386,8 +117439,9 @@ </histogram> <histogram base="true" name="Sync.DuplicateClientTagHashInApplyPendingUpdates" - enum="BooleanPresent" expires_after="2019-03-31"> + enum="BooleanPresent" expires_after="2019-09-30"> <owner>treib@chromium.org</owner> + <owner>jkrcal@chromium.org</owner> <summary> Whether ModelTypeWorker received any duplicate client tag hashes within a full GetUpdates cycle (which, in the case of pagination, might consist of @@ -117396,8 +117450,9 @@ </histogram> <histogram base="true" name="Sync.DuplicateClientTagHashInGetUpdatesResponse" - enum="BooleanPresent" expires_after="2019-03-31"> + enum="BooleanPresent" expires_after="2019-09-30"> <owner>treib@chromium.org</owner> + <owner>jkrcal@chromium.org</owner> <summary> Whether ModelTypeWorker received any duplicate client tag hashes within a single GetUpdates response (which, in the case of pagination, might be only @@ -127616,6 +127671,24 @@ </summary> </histogram> +<histogram name="Viz.DisplayCompositor.RootDamageRect.Overlay" + enum="BooleanOverlayDamageRect" expires_after="2020-12-31"> + <owner>magchen@chromium.org</owner> + <owner>zmo@chromium.org</owner> + <summary> + Any root damage excluding overlay damage in the current frame? + </summary> +</histogram> + +<histogram name="Viz.DisplayCompositor.RootDamageRect.Underlay" + enum="UnderlayDamageRect" expires_after="2020-12-31"> + <owner>magchen@chromium.org</owner> + <owner>zmo@chromium.org</owner> + <summary> + The root damage type excluding underlay damage in the current frame. + </summary> +</histogram> + <histogram name="Viz.DisplayCompositor.SurfaceEmbeddingTime" units="ms"> <owner>jonross@chromium.org</owner> <summary>
diff --git a/tools/metrics/rappor/rappor_model.py b/tools/metrics/rappor/rappor_model.py index c10daee..140713c5 100644 --- a/tools/metrics/rappor/rappor_model.py +++ b/tools/metrics/rappor/rappor_model.py
@@ -20,16 +20,16 @@ _NOISE_VALUES_TYPE = models.ObjectNodeType( 'noise-values', attributes=[ - ('fake-prob', float), - ('fake-one-prob', float), - ('one-coin-prob', float), - ('zero-coin-prob', float), + ('fake-prob', float, None), + ('fake-one-prob', float, None), + ('one-coin-prob', float, None), + ('zero-coin-prob', float, None), ]) _NOISE_LEVEL_TYPE = models.ObjectNodeType( 'noise-level', extra_newlines=(1, 1, 1), - attributes=[('name', unicode)], + attributes=[('name', unicode, None)], children=[ models.ChildType('summary', _SUMMARY_TYPE, False), models.ChildType('values', _NOISE_VALUES_TYPE, False), @@ -46,17 +46,17 @@ _PARAMETERS_TYPE = models.ObjectNodeType( 'parameters', attributes=[ - ('num-cohorts', int), - ('bytes', int), - ('hash-functions', int), - ('reporting-level', unicode), - ('noise-level', unicode), + ('num-cohorts', int, None), + ('bytes', int, None), + ('hash-functions', int, None), + ('reporting-level', unicode, None), + ('noise-level', unicode, None), ]) _RAPPOR_PARAMETERS_TYPE = models.ObjectNodeType( 'rappor-parameters', extra_newlines=(1, 1, 1), - attributes=[('name', unicode)], + attributes=[('name', unicode, None)], children=[ models.ChildType('summary', _SUMMARY_TYPE, False), models.ChildType('parameters', _PARAMETERS_TYPE, False), @@ -73,21 +73,21 @@ _STRING_FIELD_TYPE = models.ObjectNodeType( 'string-field', extra_newlines=(1, 1, 0), - attributes=[('name', unicode)], + attributes=[('name', unicode, None)], children=[ models.ChildType('summary', _SUMMARY_TYPE, False), ]) _FLAG_TYPE = models.ObjectNodeType( 'flag', - attributes=[('bit', int), ('label', unicode)], + attributes=[('bit', int, None), ('label', unicode, None)], text_attribute='summary', single_line=True) _FLAGS_FIELD_TYPE = models.ObjectNodeType( 'flags-field', extra_newlines=(1, 1, 0), - attributes=[('name', unicode), ('noise-level', unicode)], + attributes=[('name', unicode, None), ('noise-level', unicode, None)], children=[ models.ChildType('flags', _FLAG_TYPE, True), models.ChildType('summary', _SUMMARY_TYPE, False), @@ -96,7 +96,7 @@ _UINT64_FIELD_TYPE = models.ObjectNodeType( 'uint64-field', extra_newlines=(1, 1, 0), - attributes=[('name', unicode), ('noise-level', unicode)], + attributes=[('name', unicode, None), ('noise-level', unicode, None)], children=[ models.ChildType('summary', _SUMMARY_TYPE, False), ]) @@ -104,7 +104,7 @@ _RAPPOR_METRIC_TYPE = models.ObjectNodeType( 'rappor-metric', extra_newlines=(1, 1, 1), - attributes=[('name', unicode), ('type', unicode)], + attributes=[('name', unicode, None), ('type', unicode, None)], children=[ models.ChildType('obsolete', _OBSOLETE_TYPE, False), models.ChildType('owners', _OWNER_TYPE, True), @@ -170,7 +170,8 @@ Returns: True iff the object contains all of the attributes. """ - return _CheckRequired(obj, label, (attr for attr, _ in node_type.attributes)) + return _CheckRequired(obj, label, + (attr for attr, _, _ in node_type.attributes)) def _IsValidNoiseLevel(noise_level):
diff --git a/tools/metrics/ukm/ukm_model.py b/tools/metrics/ukm/ukm_model.py index 5bf4bec6..e67e573 100644 --- a/tools/metrics/ukm/ukm_model.py +++ b/tools/metrics/ukm/ukm_model.py
@@ -24,14 +24,14 @@ _QUANTILES_TYPE = models.ObjectNodeType( 'quantiles', attributes=[ - ('type', unicode), + ('type', unicode, None), ], single_line=True) _INDEX_TYPE = models.ObjectNodeType( 'index', attributes=[ - ('fields', unicode), + ('fields', unicode, None), ], single_line=True) @@ -61,8 +61,8 @@ _METRIC_TYPE = models.ObjectNodeType( 'metric', attributes=[ - ('name', unicode), - ('semantic_type', unicode), + ('name', unicode, r'^[A-Za-z0-9_.]+$'), + ('semantic_type', unicode, None), ], children=[ models.ChildType('obsolete', _OBSOLETE_TYPE, False), @@ -74,7 +74,9 @@ _EVENT_TYPE = models.ObjectNodeType( 'event', alphabetization=[('metric', _LOWERCASE_NAME_FN)], - attributes=[('name', unicode), ('singular', bool)], + attributes=[ + ('name', unicode, r'^[A-Za-z0-9.]+$'), + ('singular', bool, None)], extra_newlines=(1, 1, 1), children=[ models.ChildType('obsolete', _OBSOLETE_TYPE, False),
diff --git a/tools/metrics/ukm/ukm_model_test.py b/tools/metrics/ukm/ukm_model_test.py index 3880dcc..a45fc96 100755 --- a/tools/metrics/ukm/ukm_model_test.py +++ b/tools/metrics/ukm/ukm_model_test.py
@@ -37,6 +37,20 @@ result = ukm_model.UpdateXML(PRETTY_XML) self.assertMultiLineEqual(PRETTY_XML, result.strip()) + def testHasBadEventName(self): + bad_xml = PRETTY_XML.replace('Event1', 'Event:1') + with self.assertRaises(ValueError) as context: + ukm_model.UpdateXML(bad_xml) + self.assertIn('Event:1', str(context.exception)) + self.assertIn('does not match regex', str(context.exception)) + + def testHasBadMetricName(self): + bad_xml = PRETTY_XML.replace('Metric1', 'Metric:1') + with self.assertRaises(ValueError) as context: + ukm_model.UpdateXML(bad_xml) + self.assertIn('Metric:1', str(context.exception)) + self.assertIn('does not match regex', str(context.exception)) + if __name__ == '__main__': unittest.main()
diff --git a/tools/perf/chrome_telemetry_build/BUILD.gn b/tools/perf/chrome_telemetry_build/BUILD.gn index 49c1ca31..ba8dcda3 100644 --- a/tools/perf/chrome_telemetry_build/BUILD.gn +++ b/tools/perf/chrome_telemetry_build/BUILD.gn
@@ -83,22 +83,23 @@ group("telemetry_chrome_test_without_chrome") { testonly = true - data_deps = [ - "//third_party/catapult:telemetry_chrome_test_support", - ] - if (is_android) { - data_deps += [ - "//third_party/breakpad:minidump_dump", - "//third_party/breakpad:minidump_stackwalk", - "//third_party/breakpad:dump_syms", - ] - } else { - data_deps += [ "//third_party/catapult/telemetry:bitmaptools" ] - } - data = [ "//tools/perf/core/", # chrome_telemetry_build/ depends on core/ "//tools/perf/chrome_telemetry_build/", "//components/crash/content/tools/generate_breakpad_symbols.py", ] + data_deps = [ + "//third_party/catapult:telemetry_chrome_test_support", + ] + if (is_android) { + data += [ "//build/android/stacktrace/" ] + data_deps += [ + "//build/android:devil_chromium_py", + "//third_party/breakpad:dump_syms", + "//third_party/breakpad:minidump_dump", + "//third_party/breakpad:minidump_stackwalk", + ] + } else { + data_deps += [ "//third_party/catapult/telemetry:bitmaptools" ] + } }
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 4bc53c68..1c60f05 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -141,6 +141,7 @@ <item id="interest_feed_send" hash_code="76717919" type="0" content_hash_code="34678180" os_list="linux,windows" file_path="components/feed/core/feed_networking_host.cc"/> <item id="intranet_redirect_detector" hash_code="21785164" type="0" content_hash_code="62025595" os_list="linux,windows" file_path="chrome/browser/intranet_redirect_detector.cc"/> <item id="invalidation_service" hash_code="72354423" type="0" content_hash_code="78425687" os_list="linux,windows" file_path="components/invalidation/impl/gcm_network_channel.cc"/> + <item id="kids_management_url_checker" hash_code="57474321" type="0" content_hash_code="14764704" os_list="linux,windows" file_path="chrome/browser/supervised_user/kids_management_url_checker_client.cc"/> <item id="lib_address_input" hash_code="50816767" type="0" content_hash_code="57977576" os_list="linux,windows" file_path="third_party/libaddressinput/chromium/chrome_metadata_source.cc"/> <item id="logo_service" hash_code="35473769" type="0" content_hash_code="20271299" os_list="linux,windows" file_path="components/search_provider_logos/logo_service_impl.cc"/> <item id="logo_tracker" hash_code="36859107" type="0" deprecated="2018-12-07" content_hash_code="67588075" file_path=""/> @@ -240,7 +241,6 @@ <item id="security_key_socket" hash_code="31074955" type="0" content_hash_code="11296409" os_list="linux,windows" file_path="remoting/host/security_key/security_key_socket.cc"/> <item id="service_worker_navigation_preload" hash_code="129872904" type="0" content_hash_code="79473248" os_list="linux,windows" file_path="content/browser/service_worker/service_worker_fetch_dispatcher.cc"/> <item id="service_worker_update_checker" hash_code="130931413" type="0" content_hash_code="46608086" os_list="linux,windows" file_path="content/browser/service_worker/service_worker_single_script_update_checker.cc"/> - <item id="service_worker_write_to_cache_job" hash_code="117963307" type="0" content_hash_code="18065724" os_list="linux,windows" file_path="content/browser/service_worker/service_worker_write_to_cache_job.cc"/> <item id="services_http_server_error_response" hash_code="59302801" type="0" content_hash_code="127774041" os_list="linux,windows" file_path="services/network/public/cpp/server/http_server.cc"/> <item id="sigined_exchange_cert_fetcher" hash_code="79442849" type="0" content_hash_code="8138156" os_list="linux,windows" file_path="content/browser/web_package/signed_exchange_cert_fetcher.cc"/> <item id="signed_in_profile_avatar" hash_code="108903331" type="0" content_hash_code="72850619" os_list="linux,windows" file_path="chrome/browser/profiles/profile_downloader.cc"/>
diff --git a/ui/accessibility/BUILD.gn b/ui/accessibility/BUILD.gn index 56641fdd..677d702 100644 --- a/ui/accessibility/BUILD.gn +++ b/ui/accessibility/BUILD.gn
@@ -210,17 +210,12 @@ static_library("test_support") { testonly = true sources = [ + "platform/test_ax_node_wrapper.cc", + "platform/test_ax_node_wrapper.h", "tree_generator.cc", "tree_generator.h", ] - if (is_win || use_atk) { - sources += [ - "platform/test_ax_node_wrapper.cc", - "platform/test_ax_node_wrapper.h", - ] - } - deps = [ ":accessibility", ]
diff --git a/ui/accessibility/ax_position.h b/ui/accessibility/ax_position.h index 80de0c9..0a6bb57 100644 --- a/ui/accessibility/ax_position.h +++ b/ui/accessibility/ax_position.h
@@ -1138,50 +1138,6 @@ // TODO(nektar): Add sentence and paragraph navigation methods. - // Abstract methods. - - // Returns the text that is present inside the anchor node, including any text - // found in descendant nodes. - virtual base::string16 GetInnerText() const = 0; - // Returns the length of the text that is present inside the anchor node, - // including any text found in descendant text nodes. - virtual int MaxTextOffset() const = 0; - - protected: - AXPosition() = default; - AXPosition(const AXPosition<AXPositionType, AXNodeType>& other) = default; - virtual AXPosition<AXPositionType, AXNodeType>& operator=( - const AXPosition<AXPositionType, AXNodeType>& other) = default; - - virtual void Initialize(AXPositionKind kind, - AXTreeID tree_id, - int32_t anchor_id, - int child_index, - int text_offset, - ax::mojom::TextAffinity affinity) { - kind_ = kind; - tree_id_ = tree_id; - anchor_id_ = anchor_id; - child_index_ = child_index; - text_offset_ = text_offset; - affinity_ = affinity; - - if (!GetAnchor() || kind_ == AXPositionKind::NULL_POSITION || - (kind_ == AXPositionKind::TREE_POSITION && - (child_index_ != BEFORE_TEXT && - (child_index_ < 0 || child_index_ > AnchorChildCount()))) || - (kind_ == AXPositionKind::TEXT_POSITION && - (text_offset_ < 0 || text_offset_ > MaxTextOffset()))) { - // Reset to the null position. - kind_ = AXPositionKind::NULL_POSITION; - tree_id_ = AXTreeIDUnknown(); - anchor_id_ = INVALID_ANCHOR_ID; - child_index_ = INVALID_INDEX; - text_offset_ = INVALID_OFFSET; - affinity_ = ax::mojom::TextAffinity::kDownstream; - } - } - // Uses depth-first pre-order traversal. AXPositionInstance CreateNextAnchorPosition() const { if (IsNullPosition()) @@ -1243,6 +1199,50 @@ return leaf; } + // Abstract methods. + + // Returns the text that is present inside the anchor node, including any text + // found in descendant nodes. + virtual base::string16 GetInnerText() const = 0; + // Returns the length of the text that is present inside the anchor node, + // including any text found in descendant text nodes. + virtual int MaxTextOffset() const = 0; + + protected: + AXPosition() = default; + AXPosition(const AXPosition<AXPositionType, AXNodeType>& other) = default; + virtual AXPosition<AXPositionType, AXNodeType>& operator=( + const AXPosition<AXPositionType, AXNodeType>& other) = default; + + virtual void Initialize(AXPositionKind kind, + AXTreeID tree_id, + int32_t anchor_id, + int child_index, + int text_offset, + ax::mojom::TextAffinity affinity) { + kind_ = kind; + tree_id_ = tree_id; + anchor_id_ = anchor_id; + child_index_ = child_index; + text_offset_ = text_offset; + affinity_ = affinity; + + if (!GetAnchor() || kind_ == AXPositionKind::NULL_POSITION || + (kind_ == AXPositionKind::TREE_POSITION && + (child_index_ != BEFORE_TEXT && + (child_index_ < 0 || child_index_ > AnchorChildCount()))) || + (kind_ == AXPositionKind::TEXT_POSITION && + (text_offset_ < 0 || text_offset_ > MaxTextOffset()))) { + // Reset to the null position. + kind_ = AXPositionKind::NULL_POSITION; + tree_id_ = AXTreeIDUnknown(); + anchor_id_ = INVALID_ANCHOR_ID; + child_index_ = INVALID_INDEX; + text_offset_ = INVALID_OFFSET; + affinity_ = ax::mojom::TextAffinity::kDownstream; + } + } + // Returns the character offset inside our anchor's parent at which our text // starts. int AnchorTextOffsetInParent() const {
diff --git a/ui/accessibility/ax_range.h b/ui/accessibility/ax_range.h index 914f350..3f859ce8 100644 --- a/ui/accessibility/ax_range.h +++ b/ui/accessibility/ax_range.h
@@ -7,8 +7,11 @@ #include <memory> #include <utility> +#include <vector> #include "base/strings/string16.h" +#include "ui/accessibility/ax_tree_manager_map.h" +#include "ui/accessibility/platform/ax_platform_node_delegate.h" namespace ui { @@ -106,6 +109,116 @@ return text.substr(0, text_length); } + // Returns a vector of AXRanges that span from the start of an anchor + // to the end of an anchor, all of which are in between anchor_ and focus_ + // endpoints of this range. + std::vector<AXRange<AXPositionType>> GetAnchors() { + DCHECK(*anchor_ <= *focus_); + + std::vector<AXRange<AXPositionType>> anchors; + auto range_start = anchor_->Clone(); + auto range_end = focus_->Clone(); + + // Non-null degenerate ranges span no content, but they do have a single + // anchor. + auto current_anchor_start = range_start->AsLeafTextPosition(); + if (!current_anchor_start->IsNullPosition() && *range_start == *range_end) { + anchors.emplace_back(AXRange(current_anchor_start->Clone(), + current_anchor_start->Clone())); + return anchors; + } + + // If start and end are in the same anchor, use end instead of + // CreatePositionAtEndOfAnchor to ensure this doesn't return a range that + // spans past end. + auto current_anchor_end = + current_anchor_start->CreatePositionAtEndOfAnchor(); + const auto end = range_end->AsLeafTextPosition(); + if (*current_anchor_end > *end && + end->GetAnchor() == current_anchor_start->GetAnchor()) + current_anchor_end = end->Clone(); + + while (!current_anchor_start->IsNullPosition() && + !current_anchor_end->IsNullPosition() && + *current_anchor_start < *current_anchor_end) { + if (current_anchor_start->GetAnchor() == + current_anchor_end->GetAnchor()) { + anchors.emplace_back(AXRange(current_anchor_start->Clone(), + current_anchor_end->Clone())); + } + + if (*current_anchor_end >= *end) + break; + + if (current_anchor_end->CreateNextTextAnchorPosition() + ->IsNullPosition()) { + current_anchor_start = current_anchor_start->CreateNextAnchorPosition() + ->AsLeafTextPosition(); + } else { + current_anchor_start = + current_anchor_end->CreateNextTextAnchorPosition(); + } + + current_anchor_end = current_anchor_start->CreatePositionAtEndOfAnchor(); + + // If CreatePositionAtEndOfAnchor goes past the end anchor, use the end + // anchor instead. + if (*current_anchor_end > *end && + end->GetAnchor() == current_anchor_start->GetAnchor()) + current_anchor_end = end->Clone(); + } + + return anchors; + } + + // Appends rects in screen coordinates of all text nodes that span between + // anchor_ and focus_. Rects outside of the viewport are skipped. + std::vector<gfx::Rect> GetScreenRects() const { + DCHECK(*anchor_ <= *focus_); + std::vector<gfx::Rect> rectangles; + auto current_line_start = anchor_->Clone(); + auto range_end = focus_->Clone(); + + while (*current_line_start < *range_end) { + auto current_line_end = current_line_start->CreateNextLineEndPosition( + ui::AXBoundaryBehavior::CrossBoundary); + + if (*current_line_end > *range_end) + current_line_end = range_end->Clone(); + + DCHECK(current_line_end->GetAnchor() == current_line_start->GetAnchor()); + int length_of_current_line = + current_line_end->text_offset() - current_line_start->text_offset(); + + if (current_line_start->GetAnchor()->data().role == + ax::mojom::Role::kInlineTextBox) { + current_line_start = current_line_start->CreateParentPosition(); + } + + AXTreeID current_tree_id = current_line_start->tree_id(); + AXTreeManager* manager = + AXTreeManagerMap::GetInstance().GetManager(current_tree_id); + AXNode* current_anchor = current_line_start->GetAnchor(); + AXPlatformNodeDelegate* current_anchor_delegate = + manager->GetDelegate(current_tree_id, current_anchor->id()); + + gfx::Rect current_rect = current_anchor_delegate->GetScreenBoundsForRange( + current_line_start->text_offset(), length_of_current_line, + /*clipped*/ true); + + // Only add rects that are within the current viewport. The 'clipped' + // parameter for GetScreenBoundsForRange will return an empty rect in + // that case. + if (!current_rect.IsEmpty()) + rectangles.emplace_back(current_rect); + + current_line_start = current_line_end->CreateNextLineStartPosition( + ui::AXBoundaryBehavior::CrossBoundary); + } + + return rectangles; + } + private: std::unique_ptr<AXPositionType> anchor_; std::unique_ptr<AXPositionType> focus_;
diff --git a/ui/accessibility/ax_tree_manager.h b/ui/accessibility/ax_tree_manager.h index 5f96a65..0361847 100644 --- a/ui/accessibility/ax_tree_manager.h +++ b/ui/accessibility/ax_tree_manager.h
@@ -11,6 +11,8 @@ namespace ui { +class AXPlatformNodeDelegate; + // Each AXNode has access to its own tree, but a manager of multiple AXTrees // is necessary for operations that span across trees. class AX_EXPORT AXTreeManager { @@ -19,6 +21,12 @@ // This allows for callers to access nodes outside of their own tree. // Returns nullptr if the AXTreeID or node_id is not found. virtual AXNode* GetNodeFromTree(AXTreeID tree_id, int32_t node_id) = 0; + + // Exposes the mapping of AXPlatformNodeDelegate*'s from AXTreeID and + // AXNodeID. This is non-static to allow for test code to override with + // custom implementations. + virtual AXPlatformNodeDelegate* GetDelegate(AXTreeID tree_id, + int32_t node_id) = 0; }; } // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc index 0963a99..2a95a27 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -4,6 +4,7 @@ #include "ui/accessibility/platform/ax_platform_node_auralinux.h" +#include <dlfcn.h> #include <stdint.h> #include <algorithm> @@ -56,6 +57,47 @@ // null if if the AtkObject is destroyed. AtkObject* g_active_top_level_frame = nullptr; +// AtkTableCell was introduced in ATK 2.12. Ubuntu Trusty has ATK 2.10. +// Compile-time checks are in place for ATK versions that are older than 2.12. +// However, we also need runtime checks in case the version we are building +// against is newer than the runtime version. To prevent a runtime error, we +// check that we have a version of ATK that supports AtkTableCell. If we do, +// we dynamically load the symbol; if we don't, the interface is absent from +// the accessible object and its methods will not be exposed or callable. +// The definitions below ensure we have no missing symbols. Note that in +// environments where we have ATK > 2.12, the definitions of AtkTableCell and +// AtkTableCellIface below are overridden by the runtime version. +// TODO(accessibility) Remove these definitions, along with the use of +// LoadTableCellMethods() when 2.12 is the minimum supported version. +typedef struct _AtkTableCell AtkTableCell; +typedef struct _AtkTableCellIface AtkTableCellIface; +typedef GType (*cell_get_type_func)(); +typedef GPtrArray* (*get_column_header_cells_func)(AtkTableCell* cell); +typedef GPtrArray* (*get_row_header_cells_func)(AtkTableCell* cell); +typedef bool (*get_row_column_span_func)(AtkTableCell* cell, + gint* row, + gint* column, + gint* row_span, + gint* col_span); + +cell_get_type_func cell_get_type = nullptr; +get_column_header_cells_func get_column_header_cells = nullptr; +get_row_header_cells_func get_row_header_cells = nullptr; +get_row_column_span_func get_row_column_span = nullptr; + +static bool LoadTableCellMethods() { + cell_get_type = reinterpret_cast<cell_get_type_func>( + dlsym(RTLD_DEFAULT, "atk_table_cell_get_type")); + get_column_header_cells = reinterpret_cast<get_column_header_cells_func>( + dlsym(RTLD_DEFAULT, "atk_table_cell_get_column_header_cells")); + get_row_header_cells = reinterpret_cast<get_row_header_cells_func>( + dlsym(RTLD_DEFAULT, "atk_table_cell_get_row_header_cells")); + get_row_column_span = reinterpret_cast<get_row_column_span_func>( + dlsym(RTLD_DEFAULT, "atk_table_cell_get_row_column_span")); + + return cell_get_type; +} + static AtkObject* FindAtkObjectParentFrame(AtkObject* atk_object) { while (atk_object) { if (atk_object_get_role(atk_object) == ATK_ROLE_FRAME) @@ -286,6 +328,10 @@ "footnote", // ATK_ROLE_FOOTNOTE = 122. }; +#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 12, 0) +#define ATK_212 +#endif + #if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 16, 0) #define ATK_216 #endif @@ -1581,6 +1627,116 @@ nullptr}; // +// AtkTableCell interface (Requires at least ATK 2.12) +// +static void IdsToGPtrArray(AXPlatformNodeDelegate* delegate, + std::vector<int32_t>& ids, + GPtrArray* array) { + for (const auto& node_id : ids) { + if (AXPlatformNode* header = delegate->GetFromNodeID(node_id)) { + if (AtkObject* atk_header = header->GetNativeViewAccessible()) { + g_object_ref(atk_header); + g_ptr_array_add(array, atk_header); + } + } + } +} + +#if defined(ATK_212) +gint AXPlatformNodeAuraLinuxGetColumnSpan(AtkTableCell* cell) { + if (auto* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(cell))) + return obj->GetTableColumnSpan(); + + return 0; +} + +GPtrArray* AXPlatformNodeAuraLinuxGetColumnHeaderCells(AtkTableCell* cell) { + GPtrArray* array = g_ptr_array_new(); + + // AtkTableCell is implemented on cells, row headers, and column headers. + // Calling GetColHeaderNodeIds() on a column header cell will include that + // column header, along with any other column headers in the column which + // may or may not describe the header cell in question. Therefore, just return + // headers for non-header cells. + if (atk_object_get_role(ATK_OBJECT(cell)) != ATK_ROLE_TABLE_CELL) + return array; + + if (auto* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(cell))) { + if (auto* table = obj->GetTable()) { + std::vector<int32_t> ids = + table->GetDelegate()->GetColHeaderNodeIds(obj->GetTableColumn()); + IdsToGPtrArray(table->GetDelegate(), ids, array); + } + } + + return array; +} + +gboolean AXPlatformNodeAuraLinuxGetCellPosition(AtkTableCell* cell, + gint* row, + gint* column) { + if (auto* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(cell))) { + *row = obj->GetTableRow(); + *column = obj->GetTableColumn(); + return true; + } + + return false; +} + +gint AXPlatformNodeAuraLinuxGetRowSpan(AtkTableCell* cell) { + if (auto* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(cell))) + return obj->GetTableRowSpan(); + + return 0; +} + +GPtrArray* AXPlatformNodeAuraLinuxGetRowHeaderCells(AtkTableCell* cell) { + GPtrArray* array = g_ptr_array_new(); + + // AtkTableCell is implemented on cells, row headers, and column headers. + // Calling GetRowHeaderNodeIds() on a row header cell will include that + // row header, along with any other row headers in the row which may or + // may not describe the header cell in question. Therefore, just return + // headers for non-header cells. + if (atk_object_get_role(ATK_OBJECT(cell)) != ATK_ROLE_TABLE_CELL) + return array; + + if (auto* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(cell))) { + if (auto* table = obj->GetTable()) { + std::vector<int32_t> ids = + table->GetDelegate()->GetRowHeaderNodeIds(obj->GetTableRow()); + IdsToGPtrArray(table->GetDelegate(), ids, array); + } + } + + return array; +} + +AtkObject* AXPlatformNodeAuraLinuxGetTable(AtkTableCell* cell) { + if (auto* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(cell))) { + if (auto* table = obj->GetTable()) + return table->GetNativeViewAccessible(); + } + + return nullptr; +} + +static void AXTableCellInterfaceBaseInit(AtkTableCellIface* iface) { + iface->get_column_span = AXPlatformNodeAuraLinuxGetColumnSpan; + iface->get_column_header_cells = AXPlatformNodeAuraLinuxGetColumnHeaderCells; + iface->get_position = AXPlatformNodeAuraLinuxGetCellPosition; + iface->get_row_span = AXPlatformNodeAuraLinuxGetRowSpan; + iface->get_row_header_cells = AXPlatformNodeAuraLinuxGetRowHeaderCells; + iface->get_table = AXPlatformNodeAuraLinuxGetTable; +} + +static const GInterfaceInfo TableCellInfo = { + reinterpret_cast<GInterfaceInitFunc>(AXTableCellInterfaceBaseInit), nullptr, + nullptr}; +#endif + +// // The rest of the AXPlatformNodeAtk code, not specific to one // of the Atk* interfaces. // @@ -1708,6 +1864,15 @@ if (role == ATK_ROLE_TABLE) interface_mask |= 1 << ATK_TABLE_INTERFACE; + // Because the TableCell Interface is only supported in ATK version 2.12 and + // later, GetAccessibilityGType has a runtime check to verify we have a recent + // enough version. If we don't, GetAccessibilityGType will exclude + // AtkTableCell from the supported interfaces and none of its methods or + // properties will be exposed to assistive technologies. + if (role == ATK_ROLE_TABLE_CELL || role == ATK_ROLE_COLUMN_HEADER || + role == ATK_ROLE_ROW_HEADER) + interface_mask |= 1 << ATK_TABLE_CELL_INTERFACE; + return interface_mask; } @@ -1756,6 +1921,11 @@ if (interface_mask_ & (1 << ATK_TABLE_INTERFACE)) g_type_add_interface_static(type, ATK_TYPE_TABLE, &TableInfo); + // Run-time check to ensure AtkTableCell is supported (requires ATK 2.12). + if (LoadTableCellMethods() && + interface_mask_ & (1 << ATK_TABLE_CELL_INTERFACE)) + g_type_add_interface_static(type, cell_get_type(), &TableCellInfo); + return type; } @@ -2526,8 +2696,6 @@ base::StringPrintf("caption=%s;", caption ? "true" : "false")); // Summarize information about the cells from the table's perspective here. - // TODO(jdiggs): When AtkTableCell is implemented, we will use it to output - // specifics on a per-cell basis. std::vector<std::string> span_info; for (int r = 0; r < n_rows; r++) { for (int c = 0; c < n_cols; c++) { @@ -2547,6 +2715,48 @@ } dict->Set("table", std::move(table_properties)); + + // Properties obtained via AtkTableCell, if possible. If we do not have at + // least ATK 2.12, use the same logic in our AtkTableCell implementation so + // that tests can still be run. + auto cell_properties = std::make_unique<base::ListValue>(); + if (role == ATK_ROLE_TABLE_CELL || role == ATK_ROLE_COLUMN_HEADER || + role == ATK_ROLE_ROW_HEADER) { + int row, col, row_span, col_span; + GPtrArray* col_headers; + GPtrArray* row_headers; + if (cell_get_type) { + AtkTableCell* cell = G_TYPE_CHECK_INSTANCE_CAST( + (atk_object_), cell_get_type(), AtkTableCell); + col_headers = get_column_header_cells(cell); + row_headers = get_row_header_cells(cell); + get_row_column_span(cell, &row, &col, &row_span, &col_span); + } else { + auto* obj = AtkObjectToAXPlatformNodeAuraLinux(atk_object_); + row = obj->GetTableRow(); + col = obj->GetTableColumn(); + row_span = obj->GetTableRowSpan(); + col_span = obj->GetTableColumnSpan(); + col_headers = g_ptr_array_new(); + row_headers = g_ptr_array_new(); + if (role == ATK_ROLE_TABLE_CELL) { + auto* delegate = obj->GetTable()->GetDelegate(); + std::vector<int32_t> col_header_ids = + delegate->GetColHeaderNodeIds(col); + std::vector<int32_t> row_header_ids = + delegate->GetRowHeaderNodeIds(row); + IdsToGPtrArray(delegate, col_header_ids, col_headers); + IdsToGPtrArray(delegate, row_header_ids, row_headers); + } + } + cell_properties->AppendString( + base::StringPrintf("(row=%i, col=%i, row_span=%i, col_span=%i", row, + col, row_span, col_span)); + cell_properties->AppendString( + base::StringPrintf("n_row_headers=%i, n_col_headers=%i)", + row_headers->len, col_headers->len)); + } + dict->Set("cell", std::move(cell_properties)); } gfx::NativeViewAccessible AXPlatformNodeAuraLinux::GetNativeViewAccessible() {
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.h b/ui/accessibility/platform/ax_platform_node_auralinux.h index ff805bb5..fb9125c 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.h +++ b/ui/accessibility/platform/ax_platform_node_auralinux.h
@@ -139,6 +139,7 @@ ATK_IMAGE_INTERFACE, ATK_SELECTION_INTERFACE, ATK_TABLE_INTERFACE, + ATK_TABLE_CELL_INTERFACE, ATK_TEXT_INTERFACE, ATK_VALUE_INTERFACE, ATK_WINDOW_INTERFACE,
diff --git a/ui/accessibility/platform/ax_platform_node_delegate.h b/ui/accessibility/platform/ax_platform_node_delegate.h index 3e7f481..74fa33c 100644 --- a/ui/accessibility/platform/ax_platform_node_delegate.h +++ b/ui/accessibility/platform/ax_platform_node_delegate.h
@@ -86,6 +86,12 @@ // any clipping; it may be outside of the window or offscreen. virtual gfx::Rect GetUnclippedScreenBoundsRect() const = 0; + // Returns the bounds of the given range in screen coordinates. Only valid + // when the role is WebAXRoleStaticText. + virtual gfx::Rect GetScreenBoundsForRange(int start, + int len, + bool clipped = false) const = 0; + // Do a *synchronous* hit test of the given location in global screen // coordinates, and the node within this node's subtree (inclusive) that's // hit, if any.
diff --git a/ui/accessibility/platform/ax_platform_node_delegate_base.cc b/ui/accessibility/platform/ax_platform_node_delegate_base.cc index 21d9fe2..6cd7faa3 100644 --- a/ui/accessibility/platform/ax_platform_node_delegate_base.cc +++ b/ui/accessibility/platform/ax_platform_node_delegate_base.cc
@@ -59,6 +59,13 @@ return gfx::Rect(); } +gfx::Rect AXPlatformNodeDelegateBase::GetScreenBoundsForRange( + int start, + int len, + bool clipped) const { + return gfx::Rect(); +} + gfx::NativeViewAccessible AXPlatformNodeDelegateBase::HitTestSync(int x, int y) { return nullptr;
diff --git a/ui/accessibility/platform/ax_platform_node_delegate_base.h b/ui/accessibility/platform/ax_platform_node_delegate_base.h index 34baed1b..dbf5149 100644 --- a/ui/accessibility/platform/ax_platform_node_delegate_base.h +++ b/ui/accessibility/platform/ax_platform_node_delegate_base.h
@@ -59,6 +59,14 @@ // any clipping; it may be outside of the window or offscreen. gfx::Rect GetUnclippedScreenBoundsRect() const override; + // Get the bounds of this node with text offsets in screen coordinates, + // optionally applying clipping to all bounding boxes so that the resulting + // rect is within the window. Only valid when the role is + // ax::mojom::Role::kStaticText. + gfx::Rect GetScreenBoundsForRange(int start, + int len, + bool clipped = false) const override; + // Do a *synchronous* hit test of the given location in global screen // coordinates, and the node within this node's subtree (inclusive) that's // hit, if any.
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc index 9a7ccf3..c58fb44 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc
@@ -93,7 +93,57 @@ STDMETHODIMP AXPlatformNodeTextRangeProviderWin::GetBoundingRectangles( SAFEARRAY** rectangles) { - return E_NOTIMPL; + UIA_VALIDATE_TEXTRANGEPROVIDER_CALL(); + + *rectangles = nullptr; + + AXNodeRange range(start_->Clone(), end_->Clone()); + std::vector<AXNodeRange> anchors = range.GetAnchors(); + + std::vector<gfx::Rect> rects; + for (auto&& current_range : anchors) { + std::vector<gfx::Rect> current_anchor_rects = + current_range.GetScreenRects(); + // std::vector does not have a built-in way of appending another + // std::vector. Using insert with iterators is the safest and most + // performant way to accomplish this. + rects.insert(rects.end(), current_anchor_rects.begin(), + current_anchor_rects.end()); + } + + // 4 array items per rect: left, top, width, height + SAFEARRAY* safe_array = SafeArrayCreateVector( + VT_R8 /* element type */, 0 /* lower bound */, rects.size() * 4); + + if (!safe_array) + return E_OUTOFMEMORY; + + if (rects.size() > 0) { + double* double_array = nullptr; + HRESULT hr = SafeArrayAccessData(safe_array, + reinterpret_cast<void**>(&double_array)); + + if (SUCCEEDED(hr)) { + for (size_t rect_index = 0; rect_index < rects.size(); rect_index++) { + const gfx::Rect& rect = rects[rect_index]; + double_array[rect_index * 4] = rect.x(); + double_array[rect_index * 4 + 1] = rect.y(); + double_array[rect_index * 4 + 2] = rect.width(); + double_array[rect_index * 4 + 3] = rect.height(); + } + hr = SafeArrayUnaccessData(safe_array); + } + + if (FAILED(hr)) { + DCHECK(safe_array); + SafeArrayDestroy(safe_array); + return E_FAIL; + } + } + + *rectangles = safe_array; + + return S_OK; } STDMETHODIMP AXPlatformNodeTextRangeProviderWin::GetEnclosingElement(
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h index 41cecff8..95bd47d 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h
@@ -87,8 +87,6 @@ using AXPositionInstance = AXNodePosition::AXPositionInstance; using AXNodeRange = AXRange<AXNodePosition::AXPositionInstance::element_type>; - using AXPositionInstancePair = - std::tuple<AXPositionInstance, AXPositionInstance>; AXNodePosition::AXPositionInstance start_; AXNodePosition::AXPositionInstance end_;
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc index 7f34fc4..9adccdf 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc
@@ -6,14 +6,38 @@ #include <UIAutomationClient.h> #include <UIAutomationCoreApi.h> +#include <atlsafe.h> + #include "base/win/atl.h" #include "base/win/scoped_bstr.h" +#include "ui/accessibility/ax_tree_manager_map.h" #include "ui/accessibility/platform/ax_fragment_root_win.h" #include "ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h" using Microsoft::WRL::ComPtr; namespace ui { +#define EXPECT_UIA_DOUBLE_SAFEARRAY_EQ(safearray, expected_property_values) \ + { \ + EXPECT_EQ(8U, ::SafeArrayGetElemsize(rectangles)); \ + ASSERT_EQ(1u, SafeArrayGetDim(safearray)); \ + LONG array_lower_bound; \ + ASSERT_HRESULT_SUCCEEDED( \ + SafeArrayGetLBound(safearray, 1, &array_lower_bound)); \ + LONG array_upper_bound; \ + ASSERT_HRESULT_SUCCEEDED( \ + SafeArrayGetUBound(safearray, 1, &array_upper_bound)); \ + double* array_data; \ + ASSERT_HRESULT_SUCCEEDED(::SafeArrayAccessData( \ + safearray, reinterpret_cast<void**>(&array_data))); \ + size_t count = array_upper_bound - array_lower_bound + 1; \ + ASSERT_EQ(expected_property_values.size(), count); \ + for (size_t i = 0; i < count; ++i) { \ + EXPECT_EQ(array_data[i], expected_property_values[i]); \ + } \ + ASSERT_HRESULT_SUCCEEDED(::SafeArrayUnaccessData(safearray)); \ + } + class AXPlatformNodeTextRangeProviderTest : public ui::AXPlatformNodeWinTest { public: const AXNodePosition::AXPositionInstance& GetStart( @@ -224,4 +248,80 @@ AXNodePosition::SetTreeForTesting(nullptr); } +TEST_F(AXPlatformNodeTextRangeProviderTest, + TestITextRangeProviderGetBoundingRectangles) { + ui::AXNodeData text_data; + text_data.id = 2; + text_data.role = ax::mojom::Role::kStaticText; + text_data.relative_bounds.bounds = gfx::RectF(100, 150, 200, 200); + text_data.SetName("some text"); + + ui::AXNodeData more_text_data; + more_text_data.id = 3; + more_text_data.role = ax::mojom::Role::kStaticText; + more_text_data.relative_bounds.bounds = gfx::RectF(200, 250, 100, 100); + more_text_data.SetName("more text"); + + ui::AXNodeData root_data; + root_data.id = 1; + root_data.role = ax::mojom::Role::kRootWebArea; + root_data.child_ids.push_back(2); + root_data.child_ids.push_back(3); + + ui::AXTreeUpdate update; + ui::AXTreeData tree_data; + tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID(); + update.tree_data = tree_data; + update.has_tree_data = true; + update.root_id = root_data.id; + update.nodes.push_back(root_data); + update.nodes.push_back(text_data); + update.nodes.push_back(more_text_data); + + Init(update); + + AXNode* root_node = GetRootNode(); + AXNodePosition::SetTreeForTesting(tree_.get()); + AXTreeManagerMap::GetInstance().AddTreeManager(tree_data.tree_id, this); + AXNode* text_node = root_node->children()[0]; + + ComPtr<IRawElementProviderSimple> text_node_raw = + QueryInterfaceFromNode<IRawElementProviderSimple>(text_node); + + ComPtr<ITextProvider> text_provider; + EXPECT_HRESULT_SUCCEEDED( + text_node_raw->GetPatternProvider(UIA_TextPatternId, &text_provider)); + + ComPtr<ITextRangeProvider> text_range_provider; + EXPECT_HRESULT_SUCCEEDED( + text_provider->get_DocumentRange(&text_range_provider)); + + CComSafeArray<LONG> rectangles; + EXPECT_HRESULT_SUCCEEDED( + text_range_provider->GetBoundingRectangles(rectangles.GetSafeArrayPtr())); + + std::vector<double> expected_values = {100, 150, 200, 200}; + EXPECT_UIA_DOUBLE_SAFEARRAY_EQ(rectangles, expected_values); + + Microsoft::WRL::ComPtr<IRawElementProviderSimple> root_node_raw = + QueryInterfaceFromNode<IRawElementProviderSimple>(root_node); + + Microsoft::WRL::ComPtr<ITextProvider> document_provider; + EXPECT_HRESULT_SUCCEEDED( + root_node_raw->GetPatternProvider(UIA_TextPatternId, &document_provider)); + + ComPtr<ITextRangeProvider> document_textrange; + EXPECT_HRESULT_SUCCEEDED( + document_provider->get_DocumentRange(&document_textrange)); + + CComSafeArray<LONG> body_rectangles; + EXPECT_HRESULT_SUCCEEDED(document_textrange->GetBoundingRectangles( + body_rectangles.GetSafeArrayPtr())); + expected_values = {100, 150, 200, 200, 200, 250, 100, 100}; + EXPECT_UIA_DOUBLE_SAFEARRAY_EQ(body_rectangles, expected_values); + + AXTreeManagerMap::GetInstance().RemoveTreeManager(tree_data.tree_id); + AXNodePosition::SetTreeForTesting(nullptr); +} + } // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node_unittest.cc b/ui/accessibility/platform/ax_platform_node_unittest.cc index add0625..0f262c1 100644 --- a/ui/accessibility/platform/ax_platform_node_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_unittest.cc
@@ -4,6 +4,7 @@ #include "ui/accessibility/platform/ax_platform_node_unittest.h" #include "ui/accessibility/ax_constants.mojom.h" +#include "ui/accessibility/platform/test_ax_node_wrapper.h" namespace ui { @@ -58,6 +59,27 @@ Init(update); } +AXNode* AXPlatformNodeTest::GetNodeFromTree(ui::AXTreeID tree_id, + int32_t node_id) { + if (tree_->data().tree_id == tree_id) + return tree_->GetFromId(node_id); + + return nullptr; +} + +AXPlatformNodeDelegate* AXPlatformNodeTest::GetDelegate(ui::AXTreeID tree_id, + int32_t node_id) { + AXNode* node = GetNodeFromTree(tree_id, node_id); + + if (node) { + TestAXNodeWrapper* wrapper = + TestAXNodeWrapper::GetOrCreate(tree_.get(), node); + + return wrapper; + } + return nullptr; +} + AXTreeUpdate AXPlatformNodeTest::BuildTextField() { AXNodeData text_field_node; text_field_node.id = 1;
diff --git a/ui/accessibility/platform/ax_platform_node_unittest.h b/ui/accessibility/platform/ax_platform_node_unittest.h index fb5bfc1..c9218a4 100644 --- a/ui/accessibility/platform/ax_platform_node_unittest.h +++ b/ui/accessibility/platform/ax_platform_node_unittest.h
@@ -9,11 +9,12 @@ #include "ui/accessibility/ax_node.h" #include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/ax_tree.h" +#include "ui/accessibility/ax_tree_manager.h" #include "ui/accessibility/ax_tree_update.h" namespace ui { -class AXPlatformNodeTest : public testing::Test { +class AXPlatformNodeTest : public testing::Test, public AXTreeManager { public: AXPlatformNodeTest(); ~AXPlatformNodeTest() override; @@ -35,6 +36,11 @@ const ui::AXNodeData& node11 = ui::AXNodeData(), const ui::AXNodeData& node12 = ui::AXNodeData()); + // AXTreeManager implementation. + AXNode* GetNodeFromTree(ui::AXTreeID tree_id, int32_t node_id) override; + AXPlatformNodeDelegate* GetDelegate(AXTreeID tree_id, + int32_t node_id) override; + protected: AXNode* GetRootNode() { return tree_->root(); }
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc index 534db8d..a572291 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.cc +++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -129,6 +129,16 @@ return gfx::ToEnclosingRect(bounds); } +gfx::Rect TestAXNodeWrapper::GetScreenBoundsForRange(int start, + int len, + bool clipped) const { + // Ignoring start, len, and clipped, as there's no clean way to map these + // via unit tests. + gfx::RectF bounds = GetData().relative_bounds.bounds; + bounds.Offset(g_offset); + return gfx::ToEnclosingRect(bounds); +} + TestAXNodeWrapper* TestAXNodeWrapper::HitTestSyncInternal(int x, int y) { // Here we find the deepest child whose bounding box contains the given point. // The assuptions are that there are no overlapping bounding rects and that
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.h b/ui/accessibility/platform/test_ax_node_wrapper.h index 0fea6a3d..72630e3 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.h +++ b/ui/accessibility/platform/test_ax_node_wrapper.h
@@ -53,6 +53,9 @@ gfx::NativeViewAccessible ChildAtIndex(int index) override; gfx::Rect GetClippedScreenBoundsRect() const override; gfx::Rect GetUnclippedScreenBoundsRect() const override; + gfx::Rect GetScreenBoundsForRange(int start, + int len, + bool clipped) const override; gfx::NativeViewAccessible HitTestSync(int x, int y) override; gfx::NativeViewAccessible GetFocus() override; AXPlatformNode* GetFromNodeID(int32_t id) override;
diff --git a/ui/message_center/public/cpp/message_center_constants.h b/ui/message_center/public/cpp/message_center_constants.h index 0bce5eea..c87bb97 100644 --- a/ui/message_center/public/cpp/message_center_constants.h +++ b/ui/message_center/public/cpp/message_center_constants.h
@@ -78,9 +78,13 @@ // Background of small icon image. constexpr SkColor kSmallImageMaskBackgroundColor = SkColorSetRGB(0xa3, 0xa3, 0xa3); -// Background of the close button and the settings button +// Background of the close button and the settings button. +#if defined(OS_CHROMEOS) constexpr SkColor kControlButtonBackgroundColor = SkColorSetA(SK_ColorWHITE, 0.9 * 0xff); +#else +constexpr SkColor kControlButtonBackgroundColor = SK_ColorTRANSPARENT; +#endif // Default accent color of notifications that are not generated by system. constexpr SkColor kNotificationDefaultAccentColor = gfx::kChromeIconGrey;
diff --git a/ui/ozone/platform/wayland/wayland_object.cc b/ui/ozone/platform/wayland/wayland_object.cc index ed4de39..31fae0c 100644 --- a/ui/ozone/platform/wayland/wayland_object.cc +++ b/ui/ozone/platform/wayland/wayland_object.cc
@@ -102,6 +102,9 @@ &wl_registry_interface; void (*ObjectTraits<wl_registry>::deleter)(wl_registry*) = &wl_registry_destroy; +const wl_interface* ObjectTraits<wl_region>::interface = &wl_region_interface; +void (*ObjectTraits<wl_region>::deleter)(wl_region*) = &wl_region_destroy; + const wl_interface* ObjectTraits<wl_seat>::interface = &wl_seat_interface; void (*ObjectTraits<wl_seat>::deleter)(wl_seat*) = &delete_seat;
diff --git a/ui/ozone/platform/wayland/wayland_object.h b/ui/ozone/platform/wayland/wayland_object.h index 6e5e1b08..f7f7fd3 100644 --- a/ui/ozone/platform/wayland/wayland_object.h +++ b/ui/ozone/platform/wayland/wayland_object.h
@@ -20,6 +20,7 @@ struct wl_output; struct wl_pointer; struct wl_registry; +struct wl_region; struct wl_seat; struct wl_shm; struct wl_shm_pool; @@ -119,6 +120,12 @@ }; template <> +struct ObjectTraits<wl_region> { + static const wl_interface* interface; + static void (*deleter)(wl_region*); +}; + +template <> struct ObjectTraits<wl_seat> { static const wl_interface* interface; static void (*deleter)(wl_seat*);
diff --git a/ui/ozone/platform/wayland/wayland_window.cc b/ui/ozone/platform/wayland/wayland_window.cc index 0245365..7b65895 100644 --- a/ui/ozone/platform/wayland/wayland_window.cc +++ b/ui/ozone/platform/wayland/wayland_window.cc
@@ -26,7 +26,6 @@ #include "ui/ozone/platform/wayland/xdg_surface_wrapper_v5.h" #include "ui/ozone/platform/wayland/xdg_surface_wrapper_v6.h" #include "ui/platform_window/platform_window_handler/wm_drop_handler.h" -#include "ui/platform_window/platform_window_init_properties.h" namespace ui { @@ -125,6 +124,7 @@ DCHECK(xdg_shell_objects_factory_); bounds_ = properties.bounds; + opacity_ = properties.opacity; surface_.reset(wl_compositor_create_surface(connection_->compositor())); if (!surface_) { @@ -133,6 +133,7 @@ } wl_surface_set_user_data(surface_.get(), this); AddSurfaceListener(); + MaybeUpdateOpaqueRegion(); ui::PlatformWindowType ui_window_type = properties.type; switch (ui_window_type) { @@ -324,6 +325,11 @@ if (bounds == bounds_) return; bounds_ = bounds; + + // Opaque region is based on the size of the window. Thus, update the region + // on each update. + MaybeUpdateOpaqueRegion(); + delegate_->OnBoundsChanged(bounds); } @@ -849,6 +855,22 @@ return parent_window_ ? parent_window_->GetTopLevelWindow() : this; } +void WaylandWindow::MaybeUpdateOpaqueRegion() { + if (!IsOpaqueWindow()) + return; + + wl::Object<wl_region> region( + wl_compositor_create_region(connection_->compositor())); + wl_region_add(region.get(), 0, 0, bounds_.width(), bounds_.height()); + wl_surface_set_opaque_region(surface(), region.get()); + + connection_->ScheduleFlush(); +} + +bool WaylandWindow::IsOpaqueWindow() const { + return opacity_ == ui::PlatformWindowOpacity::kOpaqueWindow; +} + // 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 7a32d8dc..4c7271d 100644 --- a/ui/ozone/platform/wayland/wayland_window.h +++ b/ui/ozone/platform/wayland/wayland_window.h
@@ -18,6 +18,7 @@ #include "ui/platform_window/platform_window_delegate.h" #include "ui/platform_window/platform_window_handler/wm_drag_handler.h" #include "ui/platform_window/platform_window_handler/wm_move_resize_handler.h" +#include "ui/platform_window/platform_window_init_properties.h" namespace gfx { class PointF; @@ -32,8 +33,6 @@ class XDGPopupWrapper; class XDGSurfaceWrapper; -struct PlatformWindowInitProperties; - namespace { class XDGShellObjectFactory; } // namespace @@ -179,6 +178,12 @@ WaylandWindow* GetTopLevelWindow(); + // It's important to set opaque region for opaque windows (provides + // optimization hint for the Wayland compositor). + void MaybeUpdateOpaqueRegion(); + + bool IsOpaqueWindow() const; + // wl_surface_listener static void Enter(void* data, struct wl_surface* wl_surface, @@ -223,6 +228,9 @@ // activated. ui::PlatformWindowState pending_state_; + // Stores current opacity of the window. Set on ::Initialize call. + ui::PlatformWindowOpacity opacity_; + bool is_active_ = false; bool is_minimizing_ = false;
diff --git a/ui/ozone/platform/wayland/wayland_window_unittest.cc b/ui/ozone/platform/wayland/wayland_window_unittest.cc index c85ff8e..1c94f168 100644 --- a/ui/ozone/platform/wayland/wayland_window_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_window_unittest.cc
@@ -5,6 +5,7 @@ #include "ui/ozone/platform/wayland/wayland_window.h" #include <memory> +#include <utility> #include <linux/input.h> #include <wayland-server-core.h> @@ -20,6 +21,7 @@ #include "ui/events/event.h" #include "ui/ozone/platform/wayland/test/mock_pointer.h" #include "ui/ozone/platform/wayland/test/mock_surface.h" +#include "ui/ozone/platform/wayland/test/test_region.h" #include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h" #include "ui/ozone/platform/wayland/wayland_test.h" #include "ui/ozone/platform/wayland/wayland_util.h" @@ -1097,6 +1099,47 @@ VerifyAndClearExpectations(); } +ACTION_P(VerifyRegion, ptr) { + wl::TestRegion* region = wl::GetUserDataAs<wl::TestRegion>(arg0); + EXPECT_EQ(*ptr, region->getBounds()); +} + +TEST_P(WaylandWindowTest, SetOpaqueRegion) { + MockPlatformWindowDelegate delegate; + + PlatformWindowInitProperties properties; + properties.bounds = gfx::Rect(0, 0, 700, 600); + properties.type = ui::PlatformWindowType::kWindow; + properties.opacity = ui::PlatformWindowOpacity::kOpaqueWindow; + + std::unique_ptr<WaylandWindow> window = + std::make_unique<WaylandWindow>(&delegate, connection_.get()); + + EXPECT_TRUE(window->Initialize(std::move(properties))); + + Sync(); + + wl::MockSurface* mock_surface = + server_.GetObject<wl::MockSurface>(window->GetWidget()); + SkIRect rect = SkIRect::MakeXYWH(0, 0, 500, 400); + EXPECT_CALL(*mock_surface, SetOpaqueRegion(_)).WillOnce(VerifyRegion(&rect)); + + window->SetBounds({0, 0, 500, 400}); + + Sync(); + + VerifyAndClearExpectations(); + + rect = SkIRect::MakeXYWH(0, 0, 1000, 534); + EXPECT_CALL(*mock_surface, SetOpaqueRegion(_)).WillOnce(VerifyRegion(&rect)); + + window->SetBounds({0, 0, 1000, 534}); + + Sync(); + + VerifyAndClearExpectations(); +} + INSTANTIATE_TEST_SUITE_P(XdgVersionV5Test, WaylandWindowTest, ::testing::Values(kXdgShellV5));
diff --git a/ui/platform_window/platform_window_init_properties.h b/ui/platform_window/platform_window_init_properties.h index fc00c92..20236ab0 100644 --- a/ui/platform_window/platform_window_init_properties.h +++ b/ui/platform_window/platform_window_init_properties.h
@@ -24,6 +24,12 @@ kTooltip, }; +enum class PlatformWindowOpacity { + kInferOpacity, + kOpaqueWindow, + kTranslucentWindow, +}; + // Initial properties which are passed to PlatformWindow to be initialized // with a desired set of properties. struct PlatformWindowInitProperties { @@ -43,6 +49,9 @@ // Tells PlatformWindow which native widget its parent holds. It is usually // used to find a parent from internal list of PlatformWindows. gfx::AcceleratedWidget parent_widget = gfx::kNullAcceleratedWidget; + // Tells the opacity type of a window. Check the comment in the + // Widget::InitProperties::WindowOpacity. + PlatformWindowOpacity opacity = PlatformWindowOpacity::kOpaqueWindow; #if defined(OS_FUCHSIA) fuchsia::ui::gfx::ExportToken view_token;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc index d07f4fd..1afcdd74 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
@@ -54,6 +54,18 @@ if (params.parent && params.parent->GetHost()) properties.parent_widget = params.parent->GetHost()->GetAcceleratedWidget(); + switch (params.opacity) { + case Widget::InitParams::WindowOpacity::INFER_OPACITY: + properties.opacity = ui::PlatformWindowOpacity::kInferOpacity; + break; + case Widget::InitParams::WindowOpacity::OPAQUE_WINDOW: + properties.opacity = ui::PlatformWindowOpacity::kOpaqueWindow; + break; + case Widget::InitParams::WindowOpacity::TRANSLUCENT_WINDOW: + properties.opacity = ui::PlatformWindowOpacity::kTranslucentWindow; + break; + } + return properties; }
diff --git a/ui/webui/resources/js/cr/ui/focus_row_behavior.js b/ui/webui/resources/js/cr/ui/focus_row_behavior.js index b2691df..52021847a 100644 --- a/ui/webui/resources/js/cr/ui/focus_row_behavior.js +++ b/ui/webui/resources/js/cr/ui/focus_row_behavior.js
@@ -128,7 +128,6 @@ assert(rowContainer); this.row_ = new VirtualFocusRow( rowContainer, new FocusRowBehaviorDelegate(this)); - this.ironListTabIndexChanged_(); this.addItems_(); // Adding listeners asynchronously to reduce blocking time, since this @@ -190,6 +189,7 @@ /** @private */ addItems_: function() { + this.ironListTabIndexChanged_(); if (this.row_) { this.removeObservers_(); this.row_.destroy();