diff --git a/DEPS b/DEPS index fcd92a16..3771f26 100644 --- a/DEPS +++ b/DEPS
@@ -203,11 +203,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': 'ee0ce9858cbc5c21f838fcaffadc93e08ee73344', + 'skia_revision': '0c0884991d53083c59ec4b9abca921f134544f71', # 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': 'bc5c47815cc7cbd63f78a779ed5470f91422f1f9', + 'v8_revision': '17ac33b5c91f05d0b8cc842311d037c3b59383d8', # 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. @@ -215,7 +215,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '36787dcb438203b3bade1d99aa5b996c84d04cbe', + 'angle_revision': '9828732beeee09eab746a328a7b757cd998e7e6f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -274,7 +274,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'aa1e66743da1ef0f5d5ccf46994113c99b287062', + 'devtools_frontend_revision': '1eb165cc6c39c95e825b7644a3e561c69f5912da', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -330,7 +330,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. - 'quiche_revision': '7a74e09cab5e081930e363d8d3cfdef2d4f9aa0c', + 'quiche_revision': 'a1662b3f0e9245cddf02336826aa19afa1f045ca', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -909,7 +909,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e7a31f42cda3d70b2da66b44634fc0a157dbe347', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'edd94d2b8c50d604e136c1fcb57926a24c6116b7', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1262,7 +1262,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '38f3d771bd8e100b4b8b0acac08b1e457d5f14a7', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '8da8bcdf92fba0d2aeaedbc58f6f75775712aaef', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1543,7 +1543,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/linux-amd64', - 'version': 'O3XpMr3WCt1GviS8wGsldM7NCVb2wabpHx0lJZEemjIC', + 'version': 'F1V3MxURYBy3ZkQCqWrW-_qo1aZFer1oyHdGOjT_CZoC', }, ], 'dep_type': 'cipd', @@ -1553,7 +1553,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/windows-amd64', - 'version': 'lSgrnuo5FQl_aJkQyR7BSuMSrKb37G40wPe4xQBmTnEC', + 'version': 'qZ2Cb5DPSSKjIrxhfYGgVzooq2ElNVLxNOVjsMKgfV0C', }, ], 'dep_type': 'cipd', @@ -1563,7 +1563,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/mac-amd64', - 'version': '9ofAReQA7h1bDa9kU-Rmr4_0AEQli7Pnj3lsid5AisAC', + 'version': 'Z_FxtkL4vnfqaGkZhy2qkTcVwRXIfMzIP0gDJO5O6HkC', }, ], 'dep_type': 'cipd', @@ -1577,7 +1577,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@33858054c80588938520f560dc16fc023680feb2', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1bc8d7d3cf8a0924761aeb41799c1600547155c4', 'condition': 'checkout_src_internal', }, @@ -1585,7 +1585,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'pWeqsIGRIui0WPD3a7xaKASeJ10P8A3jGHGdlGXx0loC', + 'version': 'Ly_iBRyRFPeLm1Uv4G-1csjeI7KpsnlQ81ABJEDJRdcC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/frame/default_frame_header_unittest.cc b/ash/frame/default_frame_header_unittest.cc index 7b5c452..c3aa6a3 100644 --- a/ash/frame/default_frame_header_unittest.cc +++ b/ash/frame/default_frame_header_unittest.cc
@@ -8,12 +8,12 @@ #include "ash/frame/non_client_frame_view_ash.h" #include "ash/public/cpp/shell_window_ids.h" -#include "ash/public/cpp/window_properties.h" #include "ash/test/ash_test_base.h" #include "ash/wm/desks/desks_util.h" #include "base/i18n/rtl.h" #include "base/stl_util.h" #include "base/test/icu_test_util.h" +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/frame/caption_buttons/frame_back_button.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" #include "ui/aura/window.h" @@ -28,6 +28,8 @@ using chromeos::FrameBackButton; using chromeos::FrameCaptionButtonContainerView; using chromeos::FrameHeader; +using chromeos::kFrameActiveColorKey; +using chromeos::kFrameInactiveColorKey; using views::NonClientFrameView; using views::Widget;
diff --git a/ash/frame/header_view.cc b/ash/frame/header_view.cc index 13d22de..778446c 100644 --- a/ash/frame/header_view.cc +++ b/ash/frame/header_view.cc
@@ -7,11 +7,11 @@ #include <memory> #include "ash/public/cpp/default_frame_header.h" -#include "ash/public/cpp/window_properties.h" #include "ash/shell.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "base/auto_reset.h" +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/frame/caption_buttons/caption_button_model.h" #include "chromeos/ui/frame/caption_buttons/frame_back_button.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" @@ -24,6 +24,9 @@ namespace ash { +using ::chromeos::kFrameActiveColorKey; +using ::chromeos::kFrameInactiveColorKey; + // The view used to draw the content (background and title string) // of the header. This is a separate view so that it can use // different scaling strategy than the rest of the frame such
diff --git a/ash/frame/non_client_frame_view_ash.cc b/ash/frame/non_client_frame_view_ash.cc index b0bb2f4..ab0db8c 100644 --- a/ash/frame/non_client_frame_view_ash.cc +++ b/ash/frame/non_client_frame_view_ash.cc
@@ -41,6 +41,8 @@ namespace ash { using ::chromeos::ImmersiveFullscreenController; +using ::chromeos::kFrameActiveColorKey; +using ::chromeos::kFrameInactiveColorKey; using ::chromeos::kImmersiveImpliedByFullscreen; using ::chromeos::WindowStateType;
diff --git a/ash/frame/non_client_frame_view_ash_unittest.cc b/ash/frame/non_client_frame_view_ash_unittest.cc index 31b59f9d..45f3747d 100644 --- a/ash/frame/non_client_frame_view_ash_unittest.cc +++ b/ash/frame/non_client_frame_view_ash_unittest.cc
@@ -11,7 +11,6 @@ #include "ash/frame/wide_frame_view.h" #include "ash/public/cpp/ash_switches.h" #include "ash/public/cpp/default_frame_header.h" -#include "ash/public/cpp/window_properties.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" @@ -24,6 +23,7 @@ #include "ash/wm/wm_event.h" #include "base/command_line.h" #include "base/containers/flat_set.h" +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" @@ -53,6 +53,8 @@ using ::chromeos::ImmersiveFullscreenController; using ::chromeos::ImmersiveFullscreenControllerDelegate; using ::chromeos::ImmersiveFullscreenControllerTestApi; +using ::chromeos::kFrameActiveColorKey; +using ::chromeos::kFrameInactiveColorKey; // A views::WidgetDelegate which uses a NonClientFrameViewAsh. class NonClientFrameViewAshTestWidgetDelegate
diff --git a/ash/public/cpp/ash_constants.h b/ash/public/cpp/ash_constants.h index 6cda5d8b..4bfcfb5 100644 --- a/ash/public/cpp/ash_constants.h +++ b/ash/public/cpp/ash_constants.h
@@ -14,9 +14,6 @@ namespace ash { -// Radius of the header's top corners when the window is restored. -constexpr int kTopCornerRadiusWhenRestored = 2; - // Background color used for the Chrome OS boot splash screen. constexpr SkColor kChromeOsBootColor = SkColorSetRGB(0xfe, 0xfe, 0xfe);
diff --git a/ash/public/cpp/default_frame_header.cc b/ash/public/cpp/default_frame_header.cc index 9e736b4..1212073a 100644 --- a/ash/public/cpp/default_frame_header.cc +++ b/ash/public/cpp/default_frame_header.cc
@@ -4,9 +4,8 @@ #include "ash/public/cpp/default_frame_header.h" -#include "ash/public/cpp/ash_constants.h" -#include "ash/public/cpp/window_properties.h" #include "base/logging.h" // DCHECK +#include "chromeos/ui/base/chromeos_ui_constants.h" #include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/base/window_state_type.h" #include "chromeos/ui/frame/caption_buttons/caption_button_model.h" @@ -22,6 +21,8 @@ #include "ui/views/widget/widget_delegate.h" #include "ui/views/window/caption_button_layout_constants.h" +using chromeos::kFrameActiveColorKey; +using chromeos::kFrameInactiveColorKey; using views::Widget; namespace { @@ -109,7 +110,7 @@ void DefaultFrameHeader::DoPaintHeader(gfx::Canvas* canvas) { int corner_radius = IsNormalWindowStateType(GetTargetWindow()->GetProperty( chromeos::kWindowStateTypeKey)) - ? kTopCornerRadiusWhenRestored + ? chromeos::kTopCornerRadiusWhenRestored : 0; cc::PaintFlags flags;
diff --git a/ash/public/cpp/window_properties.cc b/ash/public/cpp/window_properties.cc index 3d2c24d7..46ebda5e 100644 --- a/ash/public/cpp/window_properties.cc +++ b/ash/public/cpp/window_properties.cc
@@ -57,12 +57,6 @@ DEFINE_UI_CLASS_PROPERTY_KEY(aura::Window*, kTabDraggingSourceWindowKey, nullptr) -DEFINE_UI_CLASS_PROPERTY_KEY(SkColor, - kFrameActiveColorKey, - chromeos::kDefaultFrameColor) -DEFINE_UI_CLASS_PROPERTY_KEY(SkColor, - kFrameInactiveColorKey, - chromeos::kDefaultFrameColor) DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(base::string16, kWindowOverviewTitleKey, nullptr)
diff --git a/ash/public/cpp/window_properties.h b/ash/public/cpp/window_properties.h index f564341..d160798 100644 --- a/ash/public/cpp/window_properties.h +++ b/ash/public/cpp/window_properties.h
@@ -178,13 +178,6 @@ ASH_PUBLIC_EXPORT extern const aura::WindowProperty<aura::Window*>* const kTabDraggingSourceWindowKey; -// A property key to store the active color on the window frame. -ASH_PUBLIC_EXPORT extern const aura::WindowProperty<SkColor>* const - kFrameActiveColorKey; -// A property key to store the inactive color on the window frame. -ASH_PUBLIC_EXPORT extern const aura::WindowProperty<SkColor>* const - kFrameInactiveColorKey; - // A property key whose value is shown in alt-tab/overview mode. If non-value // is set, the window's title is used. ASH_PUBLIC_EXPORT extern const aura::WindowProperty<base::string16*>* const
diff --git a/ash/shortcut_viewer/BUILD.gn b/ash/shortcut_viewer/BUILD.gn index a0507f0..25df657c 100644 --- a/ash/shortcut_viewer/BUILD.gn +++ b/ash/shortcut_viewer/BUILD.gn
@@ -32,6 +32,7 @@ "//ash/shortcut_viewer/strings", "//ash/shortcut_viewer/vector_icons", "//cc/paint", + "//chromeos/ui/base", "//ui/accessibility", "//ui/aura", "//ui/chromeos/events",
diff --git a/ash/shortcut_viewer/views/keyboard_shortcut_view.cc b/ash/shortcut_viewer/views/keyboard_shortcut_view.cc index c9714c1..e2f8319 100644 --- a/ash/shortcut_viewer/views/keyboard_shortcut_view.cc +++ b/ash/shortcut_viewer/views/keyboard_shortcut_view.cc
@@ -32,6 +32,7 @@ #include "base/strings/string_number_conversions.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" +#include "chromeos/ui/base/window_properties.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/base/accelerators/accelerator.h" @@ -184,8 +185,8 @@ // Set frame view Active and Inactive colors, both are SK_ColorWHITE. aura::Window* window = g_ksv_view->GetWidget()->GetNativeWindow(); - window->SetProperty(ash::kFrameActiveColorKey, SK_ColorWHITE); - window->SetProperty(ash::kFrameInactiveColorKey, SK_ColorWHITE); + window->SetProperty(chromeos::kFrameActiveColorKey, SK_ColorWHITE); + window->SetProperty(chromeos::kFrameInactiveColorKey, SK_ColorWHITE); // Set shelf icon. const ash::ShelfID shelf_id(ash::kInternalAppIdKeyboardShortcutViewer);
diff --git a/base/stl_util.h b/base/stl_util.h index 024e1e0..3984045 100644 --- a/base/stl_util.h +++ b/base/stl_util.h
@@ -25,6 +25,7 @@ #include "base/check.h" #include "base/optional.h" +#include "base/ranges/algorithm.h" #include "base/template_util.h" namespace base { @@ -464,29 +465,11 @@ std::forward<Args>(args)...); } -// Returns true if the container is sorted. Requires constexpr std::begin/end, -// which exists for arrays in C++14. -// Note that std::is_sorted is constexpr beginning C++20 and this should be -// switched to use it when C++20 is supported. -template <typename Container> -constexpr bool STLIsSorted(const Container& cont) { - auto it = std::begin(cont); - const auto end = std::end(cont); - if (it == end) - return true; - - for (auto prev = it++; it != end; prev = it++) { - if (*it < *prev) - return false; - } - return true; -} - // Returns a new ResultType containing the difference of two sorted containers. template <typename ResultType, typename Arg1, typename Arg2> ResultType STLSetDifference(const Arg1& a1, const Arg2& a2) { - DCHECK(STLIsSorted(a1)); - DCHECK(STLIsSorted(a2)); + DCHECK(ranges::is_sorted(a1)); + DCHECK(ranges::is_sorted(a2)); ResultType difference; std::set_difference(a1.begin(), a1.end(), a2.begin(), a2.end(), @@ -497,8 +480,8 @@ // Returns a new ResultType containing the union of two sorted containers. template <typename ResultType, typename Arg1, typename Arg2> ResultType STLSetUnion(const Arg1& a1, const Arg2& a2) { - DCHECK(STLIsSorted(a1)); - DCHECK(STLIsSorted(a2)); + DCHECK(ranges::is_sorted(a1)); + DCHECK(ranges::is_sorted(a2)); ResultType result; std::set_union(a1.begin(), a1.end(), a2.begin(), a2.end(), @@ -510,8 +493,8 @@ // containers. template <typename ResultType, typename Arg1, typename Arg2> ResultType STLSetIntersection(const Arg1& a1, const Arg2& a2) { - DCHECK(STLIsSorted(a1)); - DCHECK(STLIsSorted(a2)); + DCHECK(ranges::is_sorted(a1)); + DCHECK(ranges::is_sorted(a2)); ResultType result; std::set_intersection(a1.begin(), a1.end(), a2.begin(), a2.end(), @@ -523,8 +506,8 @@ // container |a2|. template <typename Arg1, typename Arg2> bool STLIncludes(const Arg1& a1, const Arg2& a2) { - DCHECK(STLIsSorted(a1)); - DCHECK(STLIsSorted(a2)); + DCHECK(ranges::is_sorted(a1)); + DCHECK(ranges::is_sorted(a2)); return std::includes(a1.begin(), a1.end(), a2.begin(), a2.end()); }
diff --git a/base/stl_util_unittest.cc b/base/stl_util_unittest.cc index 55980a51..1df02e9 100644 --- a/base/stl_util_unittest.cc +++ b/base/stl_util_unittest.cc
@@ -352,43 +352,6 @@ RunConstCastIteratorTest<std::unordered_multiset<int>>(); } -TEST(STLUtilTest, STLIsSorted) { - { - std::set<int> set; - set.insert(24); - set.insert(1); - set.insert(12); - EXPECT_TRUE(STLIsSorted(set)); - } - - { - std::set<ComparableValue> set; - set.insert(ComparableValue(24)); - set.insert(ComparableValue(1)); - set.insert(ComparableValue(12)); - EXPECT_TRUE(STLIsSorted(set)); - } - - { - std::vector<int> vector; - vector.push_back(1); - vector.push_back(1); - vector.push_back(4); - vector.push_back(64); - vector.push_back(12432); - EXPECT_TRUE(STLIsSorted(vector)); - vector.back() = 1; - EXPECT_FALSE(STLIsSorted(vector)); - } - - { - int array[] = {1, 1, 4, 64, 12432}; - EXPECT_TRUE(STLIsSorted(array)); - array[4] = 1; - EXPECT_FALSE(STLIsSorted(array)); - } -} - TEST(STLUtilTest, STLSetDifference) { std::set<int> a1; a1.insert(1); @@ -808,16 +771,5 @@ EXPECT_NE(nullptr, base::OptionalOrNullptr(optional)); } -TEST(STLUtilTest, STLIsSortedConstexpr) { - constexpr int kArrayAscending[] = {1, 2, 3, 4}; - static_assert(base::STLIsSorted(kArrayAscending), ""); - - constexpr int kArrayDescending[] = {4, 3, 2, 1}; - static_assert(!base::STLIsSorted(kArrayDescending), ""); - - constexpr int kArrayEqual[] = {1, 1, 1, 1}; - static_assert(base::STLIsSorted(kArrayEqual), ""); -} - } // namespace } // namespace base
diff --git a/build/config/ios/BUILD.gn b/build/config/ios/BUILD.gn index 0282084..c80f98a 100644 --- a/build/config/ios/BUILD.gn +++ b/build/config/ios/BUILD.gn
@@ -151,10 +151,10 @@ # On "catalyst", the bundle structure is different (uses the same structure # as a regular macOS app), so an additional -rpath is required. if (target_environment == "catalyst") { - ldflags += [ "-Wl,-rpath,@loader_path/../Frameworks" ] + ldflags += [ "-Wl,-rpath,@loader_path/../../../../Frameworks" ] } - ldflags += [ "-Wl,-rpath,@executable_path/Frameworks" ] + ldflags += [ "-Wl,-rpath,@executable_path/../../Frameworks" ] } config("ios_dynamic_flags") {
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 3b1648c3..3b1417b1 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20201109.3.2 +0.20201110.1.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 3b1648c3..3b1417b1 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20201109.3.2 +0.20201110.1.1
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn index aba3291a..09d922a 100644 --- a/build/toolchain/mac/BUILD.gn +++ b/build/toolchain/mac/BUILD.gn
@@ -266,12 +266,20 @@ script = rebase_path("//build/toolchain/mac/filter_libtool.py", root_build_dir) + # Note about -filelist: Apple's linker reads the file list file and + # interprets each newline-separated chunk of text as a file name. It + # doesn't do the things one would expect from the shell like unescaping + # or handling quotes. In contrast, when Ninja finds a file name with + # spaces, it single-quotes them in $inputs_newline as it would normally + # do for command-line arguments. Thus any source names with spaces, or + # label names with spaces (which GN bases the output paths on) will be + # corrupted by this process. Don't use spaces for source files or labels. rspfile = "{{output}}.rsp" - rspfile_content = "{{inputs}}" + rspfile_content = "{{inputs_newline}}" # Specify explicit path for libtool. libtool = mac_bin_path + "libtool" - command = "rm -f {{output}} && TOOL_VERSION=${tool_versions.filter_libtool} python $script $libtool -static -D {{arflags}} -o {{output}} \"@$rspfile\"" + command = "rm -f {{output}} && TOOL_VERSION=${tool_versions.filter_libtool} python $script $libtool -static -D {{arflags}} -o {{output}} -filelist $rspfile" description = "LIBTOOL-STATIC {{output}}" outputs = [ "{{output_dir}}/{{target_output_name}}{{output_extension}}" ] default_output_dir = "{{target_out_dir}}" @@ -310,15 +318,14 @@ link_command += " -Wl,-install_name,@rpath/\"{{target_output_name}}{{output_extension}}\" " } link_command += dsym_switch - link_command += "{{ldflags}} -o \"$dylib\" @\"$rspfile\"" + link_command += "{{ldflags}} -o \"$dylib\" -Wl,-filelist,\"$rspfile\" {{frameworks}} {{swiftmodules}} {{solibs}} {{libs}}" replace_command = "if ! cmp -s \"$temporary_tocname\" \"$tocname\"; then mv \"$temporary_tocname\" \"$tocname\"" extract_toc_command = "{ $otool -l \"$dylib\" | grep LC_ID_DYLIB -A 5; $nm -gPp \"$dylib\" | cut -f1-2 -d' ' | grep -v U\$\$; true; }" command = "if $does_reexport_command ; then $link_command && $extract_toc_command > \"$tocname\"; else $link_command && $extract_toc_command > \"$temporary_tocname\" && $replace_command ; fi; fi" - rspfile_content = - "{{inputs}} {{frameworks}} {{swiftmodules}} {{solibs}} {{libs}}" + rspfile_content = "{{inputs_newline}}" description = "SOLINK {{output}}" @@ -358,16 +365,15 @@ rspfile = sofile + ".rsp" pool = "//build/toolchain:link_pool($default_toolchain)" - link_command = - "$linker_driver $ld -bundle {{ldflags}} -o \"$sofile\" @\"$rspfile\"" + link_command = "$linker_driver $ld -bundle {{ldflags}} -o \"$sofile\" -Wl,-filelist,\"$rspfile\"" if (is_component_build) { link_command += " -Wl,-install_name,@rpath/{{target_output_name}}{{output_extension}}" } link_command += dsym_switch + link_command += " {{frameworks}} {{swiftmodules}} {{solibs}} {{libs}}" command = link_command - rspfile_content = - "{{inputs}} {{frameworks}} {{swiftmodules}} {{solibs}} {{libs}}" + rspfile_content = "{{inputs_newline}}" description = "SOLINK_MODULE {{output}}" @@ -392,10 +398,17 @@ rspfile = "$outfile.rsp" pool = "//build/toolchain:link_pool($default_toolchain)" - command = "$linker_driver $ld $dsym_switch {{ldflags}} -o \"$outfile\" @\"$rspfile\"" + # Note about -filelist: Apple's linker reads the file list file and + # interprets each newline-separated chunk of text as a file name. It + # doesn't do the things one would expect from the shell like unescaping + # or handling quotes. In contrast, when Ninja finds a file name with + # spaces, it single-quotes them in $inputs_newline as it would normally + # do for command-line arguments. Thus any source names with spaces, or + # label names with spaces (which GN bases the output paths on) will be + # corrupted by this process. Don't use spaces for source files or labels. + command = "$linker_driver $ld $dsym_switch {{ldflags}} -o \"$outfile\" -Wl,-filelist,\"$rspfile\" {{frameworks}} {{swiftmodules}} {{solibs}} {{libs}}" description = "LINK $outfile" - rspfile_content = - "{{inputs}} {{frameworks}} {{swiftmodules}} {{solibs}} {{libs}}" + rspfile_content = "{{inputs_newline}}" outputs = [ outfile ] if (_enable_dsyms) {
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni index 511635a3..8bb5db7 100644 --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni
@@ -1043,6 +1043,7 @@ "java/res/xml/about_chrome_preferences.xml", "java/res/xml/accessibility_preferences.xml", "java/res/xml/account_management_preferences.xml", + "java/res/xml/autofill_assistant_preferences.xml", "java/res/xml/autofill_server_profile_preferences.xml", "java/res/xml/bookmark_widget_info.xml", "java/res/xml/clear_browsing_data_preferences_tab.xml",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 6c10ccb7..4e47a15f 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -133,6 +133,7 @@ "java/src/org/chromium/chrome/browser/autofill/settings/AutofillServerCardEditor.java", "java/src/org/chromium/chrome/browser/autofill/settings/AutofillServerProfileFragment.java", "java/src/org/chromium/chrome/browser/autofill/settings/CreditCardNumberFormattingTextWatcher.java", + "java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferenceFragment.java", "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java", "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskScheduler.java", "java/src/org/chromium/chrome/browser/background_sync/GooglePlayServicesChecker.java", @@ -287,11 +288,11 @@ "java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabSheetContent.java", "java/src/org/chromium/chrome/browser/compositor/layouts/EmptyOverviewModeObserver.java", "java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java", - "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java", "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java", "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java", "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java", "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerHost.java", + "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java", "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutProvider.java", "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutRenderHost.java", "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutUpdateHost.java", @@ -1124,9 +1125,8 @@ "java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestion.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionUiType.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java", + "java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownAdapter.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownDelegate.java", - "java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsRecyclerView.java", - "java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsRecyclerViewAdapter.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionCommonProperties.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionHost.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index 8522efab..b358212 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -65,6 +65,7 @@ "javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragmentTest.java", "javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillProfilesFragmentTest.java", "javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillTestRule.java", + "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferenceFragmentTest.java", "javatests/src/org/chromium/chrome/browser/background_sync/BackgroundSyncTest.java", "javatests/src/org/chromium/chrome/browser/background_sync/PeriodicBackgroundSyncTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java index 6558853..78fced6 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java
@@ -17,10 +17,10 @@ import org.chromium.base.task.PostTask; import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.autofill_assistant.AssistantTextUtils; +import org.chromium.chrome.browser.autofill_assistant.AutofillAssistantPreferenceFragment; import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantChipAdapter; import org.chromium.chrome.browser.settings.SettingsLauncher; import org.chromium.chrome.browser.settings.SettingsLauncherImpl; -import org.chromium.chrome.browser.sync.settings.SyncAndServicesSettings; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.components.browser_ui.widget.textbubble.TextBubble; import org.chromium.content_public.browser.UiThreadTaskTraits; @@ -159,7 +159,7 @@ if (itemId == R.id.settings) { SettingsLauncher settingsLauncher = new SettingsLauncherImpl(); settingsLauncher.launchSettingsActivity( - view.mHeader.getContext(), SyncAndServicesSettings.class); + view.mHeader.getContext(), AutofillAssistantPreferenceFragment.class); return true; } else if (itemId == R.id.send_feedback) { if (feedbackCallback != null) {
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java index bfb14c04..162bb30 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java
@@ -189,7 +189,7 @@ "#js_dropdown_options li")) .addFilters( SelectorProto.Filter.newBuilder().setBoundingBox( - SelectorProto.EmptyFilter + SelectorProto.BoundingBoxFilter .getDefaultInstance()))) .setClickType(ClickType.TAP) .build(); @@ -373,7 +373,7 @@ "div#toggle_on")) .addFilters( SelectorProto.Filter.newBuilder().setBoundingBox( - SelectorProto.EmptyFilter + SelectorProto.BoundingBoxFilter .getDefaultInstance())))) .build(); list.add((ActionProto) ActionProto.newBuilder()
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandlerTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandlerTest.java index ab8a2f8..f1bd1242 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandlerTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandlerTest.java
@@ -233,15 +233,6 @@ acceptOnboarding(); } - @Test - @MediumTest - public void testSwitchedOffInPreferences() throws Exception { - AutofillAssistantPreferencesUtil.setInitialPreferences(false); - - assertThat(isOnboardingReported(), is(false)); - assertFalse(performAction("onboarding", Bundle.EMPTY)); - } - private void acceptOnboarding() throws Exception { WaitingCallback<Boolean> onboardingCallback = performActionAsync("onboarding", Bundle.EMPTY);
diff --git a/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferencesUtil.java b/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferencesUtil.java index 36b4cee3..ee02915 100644 --- a/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferencesUtil.java +++ b/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferencesUtil.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.autofill_assistant; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; @@ -25,6 +26,16 @@ ChromePreferenceKeys.AUTOFILL_ASSISTANT_ENABLED, true); } + /** Checks whether the proactive help switch preference in settings is on. */ + static boolean isProactiveHelpSwitchOn() { + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP)) { + return false; + } + + return SharedPreferencesManager.getInstance().readBoolean( + ChromePreferenceKeys.AUTOFILL_ASSISTANT_PROACTIVE_HELP, true); + } + /** Returns whether the user has seen a lite script before or not. */ static boolean isAutofillAssistantFirstTimeLiteScriptUser() { return SharedPreferencesManager.getInstance().readBoolean( @@ -92,8 +103,10 @@ * @param accept Flag indicating whether the ToS have been accepted. */ static void setInitialPreferences(boolean accept) { - SharedPreferencesManager.getInstance().writeBoolean( - ChromePreferenceKeys.AUTOFILL_ASSISTANT_ENABLED, accept); + if (accept) { + SharedPreferencesManager.getInstance().writeBoolean( + ChromePreferenceKeys.AUTOFILL_ASSISTANT_ENABLED, accept); + } SharedPreferencesManager.getInstance().writeBoolean( ChromePreferenceKeys.AUTOFILL_ASSISTANT_ONBOARDING_ACCEPTED, accept); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediator.java index 77fbb0a4..8f5a498 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediator.java
@@ -17,7 +17,7 @@ import org.chromium.base.ObserverList; import org.chromium.base.StrictModeContext; import org.chromium.base.metrics.RecordUserAction; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.Tab; @@ -78,7 +78,7 @@ mShouldIgnoreNextSelect = false; return; } - mTabSelectingListener.onTabSelecting(LayoutManager.time(), tab.getId()); + mTabSelectingListener.onTabSelecting(LayoutManagerImpl.time(), tab.getId()); } }; mTabModelSelectorObserver = new EmptyTabModelSelectorObserver() { @@ -249,6 +249,6 @@ RecordUserAction.record("MobileTabReturnedToCurrentTab.SingleTabCard"); } mTabSelectingListener.onTabSelecting( - LayoutManager.time(), mTabModelSelector.getCurrentTabId()); + LayoutManagerImpl.time(), mTabModelSelector.getCurrentTabId()); } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java index a3157f1..93c658f 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java
@@ -32,7 +32,7 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -774,7 +774,7 @@ public void onTabSelecting(int tabId) { mIsSelectingInTabSwitcher = true; if (mOnTabSelectingListener != null) { - mOnTabSelectingListener.onTabSelecting(LayoutManager.time(), tabId); + mOnTabSelectingListener.onTabSelecting(LayoutManagerImpl.time(), tabId); } }
diff --git a/chrome/android/java/res/values/ids.xml b/chrome/android/java/res/values/ids.xml index c3f94db..f9702751 100644 --- a/chrome/android/java/res/values/ids.xml +++ b/chrome/android/java/res/values/ids.xml
@@ -63,6 +63,7 @@ <item type="id" name="contextmenu_save_link_as" /> <item type="id" name="contextmenu_share_link" /> <item type="id" name="contextmenu_direct_share_link" /> + <item type="id" name="contextmenu_read_later" /> <!--Image Group --> <item type="id" name="contextmenu_load_original_image" />
diff --git a/chrome/android/java/res/xml/autofill_assistant_preferences.xml b/chrome/android/java/res/xml/autofill_assistant_preferences.xml new file mode 100644 index 0000000..fd1e050 --- /dev/null +++ b/chrome/android/java/res/xml/autofill_assistant_preferences.xml
@@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2020 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<PreferenceScreen + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <PreferenceCategory + android:key="web_assistance" + android:title="@string/prefs_web_assistance_section_title"> + + <org.chromium.components.browser_ui.settings.ChromeSwitchPreference + android:key="autofill_assistant_switch" + android:title="@string/prefs_autofill_assistant_get_help_title" + android:summary="@string/prefs_autofill_assistant_get_help_summary" + android:persistent="false"/> + + <org.chromium.components.browser_ui.settings.ChromeSwitchPreference + android:key="proactive_help_switch" + android:title="@string/prefs_autofill_assistant_proactive_help_title" + android:summary="@string/prefs_autofill_assistant_proactive_help_summary" + android:persistent="false"/> + + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="google_services_settings_link" + android:summary="@string/prefs_proactive_help_sync_link" + app:allowDividerAbove="false" + app:allowDividerBelow="false" /> + </PreferenceCategory> + +</PreferenceScreen>
diff --git a/chrome/android/java/res/xml/google_services_preferences.xml b/chrome/android/java/res/xml/google_services_preferences.xml index 754013d..4951f90c 100644 --- a/chrome/android/java/res/xml/google_services_preferences.xml +++ b/chrome/android/java/res/xml/google_services_preferences.xml
@@ -7,7 +7,8 @@ |GetSyncedServicePrefNames| in chrome/browser/unified_consent/unified_consent_service_factory.cc has to be updated accordingly. --> -<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> <org.chromium.components.browser_ui.settings.ChromeSwitchPreference android:key="allow_signin" android:title="@string/allow_chrome_signin_title" @@ -55,9 +56,15 @@ <org.chromium.components.browser_ui.settings.ChromeSwitchPreference android:key="autofill_assistant" android:title="@string/prefs_autofill_assistant_title" - android:summary="@string/prefs_autofill_assistant_summary" + android:summary="@string/prefs_autofill_assistant_get_help_summary" android:persistent="false"/> <org.chromium.components.browser_ui.settings.ChromeBasePreference + android:key="autofill_assistant_subsection" + android:title="@string/prefs_autofill_assistant_title" + android:summary="@string/prefs_autofill_assistant_summary" + android:fragment="org.chromium.chrome.browser.autofill_assistant.AutofillAssistantPreferenceFragment" + app:isPreferenceVisible="false"/> + <org.chromium.components.browser_ui.settings.ChromeBasePreference android:key="contextual_search" android:title="@string/contextual_search_title" android:fragment="org.chromium.chrome.browser.contextualsearch.ContextualSearchPreferenceFragment"/>
diff --git a/chrome/android/java/res/xml/sync_and_services_preferences.xml b/chrome/android/java/res/xml/sync_and_services_preferences.xml index 7cd0bf1..3962dbd 100644 --- a/chrome/android/java/res/xml/sync_and_services_preferences.xml +++ b/chrome/android/java/res/xml/sync_and_services_preferences.xml
@@ -7,7 +7,8 @@ |GetSyncedServicePrefNames| in chrome/browser/unified_consent/unified_consent_service_factory.cc has to be updated accordingly. --> -<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> <PreferenceCategory android:key="user_category" android:title="@string/user"/> @@ -84,12 +85,19 @@ android:title="@string/url_keyed_anonymized_data_title" android:summary="@string/url_keyed_anonymized_data_summary" android:persistent="false"/> + <!-- Deprecated, this is being replaced by a dedicated settings subsection for autofill_assistant. There is a finch experiment that ensures that only one of those settings is shown at the same time. --> <org.chromium.components.browser_ui.settings.ChromeSwitchPreference android:key="autofill_assistant" android:title="@string/prefs_autofill_assistant_title" - android:summary="@string/prefs_autofill_assistant_summary" + android:summary="@string/prefs_autofill_assistant_get_help_summary" android:persistent="false"/> <org.chromium.components.browser_ui.settings.ChromeBasePreference + android:key="autofill_assistant_subsection" + android:title="@string/prefs_autofill_assistant_title" + android:summary="@string/prefs_autofill_assistant_summary" + android:fragment="org.chromium.chrome.browser.autofill_assistant.AutofillAssistantPreferenceFragment" + app:isPreferenceVisible="false"/> + <org.chromium.components.browser_ui.settings.ChromeBasePreference android:key="contextual_search" android:title="@string/contextual_search_title" android:fragment="org.chromium.chrome.browser.contextualsearch.ContextualSearchPreferenceFragment"/>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ActivityTabProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/ActivityTabProvider.java index 1dada493..40d688e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ActivityTabProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ActivityTabProvider.java
@@ -11,7 +11,7 @@ import org.chromium.base.ObserverList.RewindableIterator; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.compositor.layouts.Layout; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; import org.chromium.chrome.browser.compositor.layouts.StaticLayout; import org.chromium.chrome.browser.compositor.layouts.phone.SimpleAnimationLayout; @@ -147,10 +147,10 @@ /** The {@link Tab} that is considered to be the activity's tab. */ private Tab mActivityTab; - /** A handle to the {@link LayoutManager} to get the active layout. */ - private LayoutManager mLayoutManager; + /** A handle to the {@link LayoutManagerImpl} to get the active layout. */ + private LayoutManagerImpl mLayoutManager; - /** The observer watching scene changes in the {@link LayoutManager}. */ + /** The observer watching scene changes in the {@link LayoutManagerImpl}. */ private SceneChangeObserver mSceneChangeObserver; /** A handle to the {@link TabModelSelector}. */ @@ -238,9 +238,9 @@ } /** - * @param layoutManager A {@link LayoutManager} for watching for scene changes. + * @param layoutManager A {@link LayoutManagerImpl} for watching for scene changes. */ - public void setLayoutManager(LayoutManager layoutManager) { + public void setLayoutManager(LayoutManagerImpl layoutManager) { assert mLayoutManager == null; mLayoutManager = layoutManager; mLayoutManager.addSceneChangeObserver(mSceneChangeObserver);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 8270719..b6de578 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -60,10 +60,10 @@ import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator; import org.chromium.chrome.browser.compositor.layouts.Layout; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromePhone; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromeTablet; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.OverviewModeController; import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout; @@ -2062,7 +2062,7 @@ assert (mOverviewModeController.overviewVisible()); Layout activeLayout = mLayoutManager.getActiveLayout(); if (activeLayout instanceof StackLayout) { - ((StackLayout) activeLayout).commitOutstandingModelState(LayoutManager.time()); + ((StackLayout) activeLayout).commitOutstandingModelState(LayoutManagerImpl.time()); } if (getCurrentTabModel().getCount() != 0) { // Don't hide overview if current tab stack is empty()
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java index bcefc55..a863df7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -74,7 +74,7 @@ import org.chromium.chrome.browser.bookmarks.BookmarkUtils; import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.layouts.Layout; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; import org.chromium.chrome.browser.compositor.layouts.content.ContentOffsetProvider; @@ -273,7 +273,7 @@ private PictureInPictureController mPictureInPictureController; private CompositorViewHolder mCompositorViewHolder; - private ObservableSupplierImpl<LayoutManager> mLayoutManagerSupplier = + private ObservableSupplierImpl<LayoutManagerImpl> mLayoutManagerSupplier = new ObservableSupplierImpl<>(); private ObservableSupplierImpl<ShareDelegate> mShareDelegateSupplier = new ObservableSupplierImpl<>(); @@ -1732,7 +1732,7 @@ } @Override - public void initializeCompositorContent(LayoutManager layoutManager, View urlBar, + public void initializeCompositorContent(LayoutManagerImpl layoutManager, View urlBar, ViewGroup contentContainer, ControlContainer controlContainer) { mLayoutManagerSupplier.set(layoutManager); @@ -1759,10 +1759,10 @@ } /** - * @return An {@link ObservableSupplier} that will supply the {@link LayoutManager} when it is - * ready. + * @return An {@link ObservableSupplier} that will supply the {@link LayoutManagerImpl} when it + * is ready. */ - public ObservableSupplier<LayoutManager> getLayoutManagerSupplier() { + public ObservableSupplier<LayoutManagerImpl> getLayoutManagerSupplier() { return mLayoutManagerSupplier; } @@ -1885,7 +1885,7 @@ if (arDelegate != null && arDelegate.onBackPressed()) return; if (mCompositorViewHolder != null) { - LayoutManager layoutManager = mCompositorViewHolder.getLayoutManager(); + LayoutManagerImpl layoutManager = mCompositorViewHolder.getLayoutManager(); if (layoutManager != null && layoutManager.onBackPressed()) return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferenceFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferenceFragment.java new file mode 100644 index 0000000..b38cafa --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferenceFragment.java
@@ -0,0 +1,131 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.autofill_assistant; + +import android.os.Bundle; + +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceFragmentCompat; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.settings.SettingsLauncher; +import org.chromium.chrome.browser.settings.SettingsLauncherImpl; +import org.chromium.chrome.browser.signin.UnifiedConsentServiceBridge; +import org.chromium.chrome.browser.sync.settings.GoogleServicesSettings; +import org.chromium.chrome.browser.sync.settings.SyncAndServicesSettings; +import org.chromium.components.browser_ui.settings.ChromeSwitchPreference; +import org.chromium.components.browser_ui.settings.SettingsUtils; +import org.chromium.ui.text.NoUnderlineClickableSpan; +import org.chromium.ui.text.SpanApplier; + +/** + * Settings fragment for Autofill Assistant. + */ +public class AutofillAssistantPreferenceFragment extends PreferenceFragmentCompat { + private static final String PREF_WEB_ASSISTANCE_CATEGORY = "web_assistance"; + @VisibleForTesting + public static final String PREF_AUTOFILL_ASSISTANT = "autofill_assistant_switch"; + @VisibleForTesting + public static final String PREF_ASSISTANT_PROACTIVE_HELP_SWITCH = "proactive_help_switch"; + @VisibleForTesting + public static final String PREF_GOOGLE_SERVICES_SETTINGS_LINK = "google_services_settings_link"; + + private final SharedPreferencesManager mSharedPreferencesManager = + SharedPreferencesManager.getInstance(); + + private PreferenceCategory mWebAssistanceCategory; + private ChromeSwitchPreference mAutofillAssistantPreference; + private ChromeSwitchPreference mProactiveHelpPreference; + private Preference mGoogleServicesSettingsLink; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + SettingsUtils.addPreferencesFromResource(this, R.xml.autofill_assistant_preferences); + getActivity().setTitle(R.string.prefs_autofill_assistant_title); + + mWebAssistanceCategory = (PreferenceCategory) findPreference(PREF_WEB_ASSISTANCE_CATEGORY); + + mAutofillAssistantPreference = + (ChromeSwitchPreference) findPreference(PREF_AUTOFILL_ASSISTANT); + if (shouldShowAutofillAssistantPreference()) { + mAutofillAssistantPreference.setOnPreferenceChangeListener((preference, newValue) -> { + mSharedPreferencesManager.writeBoolean( + ChromePreferenceKeys.AUTOFILL_ASSISTANT_ENABLED, (boolean) newValue); + updatePreferencesState(); + return true; + }); + } else { + mAutofillAssistantPreference.setVisible(false); + } + + mProactiveHelpPreference = + (ChromeSwitchPreference) findPreference(PREF_ASSISTANT_PROACTIVE_HELP_SWITCH); + mProactiveHelpPreference.setOnPreferenceChangeListener((preference, newValue) -> { + mSharedPreferencesManager.writeBoolean( + ChromePreferenceKeys.AUTOFILL_ASSISTANT_PROACTIVE_HELP, (boolean) newValue); + updatePreferencesState(); + return true; + }); + + mGoogleServicesSettingsLink = findPreference(PREF_GOOGLE_SERVICES_SETTINGS_LINK); + NoUnderlineClickableSpan linkSpan = new NoUnderlineClickableSpan(getResources(), view -> { + SettingsLauncher settingsLauncher = new SettingsLauncherImpl(); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY)) { + settingsLauncher.launchSettingsActivity( + getActivity(), GoogleServicesSettings.class); + } else { + settingsLauncher.launchSettingsActivity(getActivity(), + SyncAndServicesSettings.class, + SyncAndServicesSettings.createArguments(false)); + } + }); + mGoogleServicesSettingsLink.setSummary( + SpanApplier.applySpans(getString(R.string.prefs_proactive_help_sync_link), + new SpanApplier.SpanInfo("<link>", "</link>", linkSpan))); + + updatePreferencesState(); + } + + @Override + public void onResume() { + super.onResume(); + updatePreferencesState(); + } + + private boolean shouldShowAutofillAssistantPreference() { + return ChromeFeatureList.isEnabled(ChromeFeatureList.AUTOFILL_ASSISTANT) + && mSharedPreferencesManager.contains( + ChromePreferenceKeys.AUTOFILL_ASSISTANT_ENABLED); + } + + private void updatePreferencesState() { + boolean autofill_assistant_enabled = SharedPreferencesManager.getInstance().readBoolean( + ChromePreferenceKeys.AUTOFILL_ASSISTANT_ENABLED, true); + mAutofillAssistantPreference.setChecked(autofill_assistant_enabled); + + boolean assistant_switch_on_or_missing = + !mAutofillAssistantPreference.isVisible() || autofill_assistant_enabled; + boolean url_keyed_anonymized_data_collection_enabled = + UnifiedConsentServiceBridge.isUrlKeyedAnonymizedDataCollectionEnabled( + Profile.getLastUsedRegularProfile()); + + boolean proactive_toggle_enabled = + url_keyed_anonymized_data_collection_enabled && assistant_switch_on_or_missing; + boolean proactive_help_on = SharedPreferencesManager.getInstance().readBoolean( + ChromePreferenceKeys.AUTOFILL_ASSISTANT_PROACTIVE_HELP, true); + mProactiveHelpPreference.setEnabled(proactive_toggle_enabled); + mProactiveHelpPreference.setChecked(proactive_toggle_enabled && proactive_help_on); + + boolean show_disclaimer = + !url_keyed_anonymized_data_collection_enabled && assistant_switch_on_or_missing; + mGoogleServicesSettingsLink.setVisible(show_disclaimer); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/OWNERS new file mode 100644 index 0000000..f488c82b --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/OWNERS
@@ -0,0 +1,3 @@ +file://components/autofill_assistant/OWNERS + +# COMPONENT: UI>Browser>Autofill>Assistant
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/AcknowledgeConverter.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/AcknowledgeConverter.java index a3eee4b..c331f85 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/AcknowledgeConverter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/AcknowledgeConverter.java
@@ -60,7 +60,7 @@ } int code = args.getInt(RESPONSE_ACKNOWLEDGE_RESPONSE_CODE); - callback.call(convertResponseCode(code)); + callback.call(convertResponseCode(code, args)); } }; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsConverter.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsConverter.java index 0b124f3d..bfb65e1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsConverter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsConverter.java
@@ -26,6 +26,8 @@ public class DigitalGoodsConverter { private static final String TAG = "DigitalGoods"; + static final String KEY_VERSION = "digitalgoods.version"; + // These values are copied from the Play Billing library since Chrome cannot depend on it. // https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode static final int PLAY_BILLING_OK = 0; @@ -35,7 +37,35 @@ private DigitalGoodsConverter() {} - static int convertResponseCode(int responseCode) { + /** Converts the given response code to one suitable for mojo. */ + static int convertResponseCode(int responseCode, Bundle bundle) { + // In the initial development, the TWA shell provided a Play Billing response code, so it + // needs to be converted to a Mojo one. Later on (but still before the feature was publicly + // launched), we decided that the TWA shell should provide data to Chrome already converted + // to a Mojo format. This is because the TWA shell may not be using Play Billing, so it + // doesn't make sense to standardise on that. + + // We kept support for the older version just to make testing and development easier. It may + // be removed once the feature has launched. + int version = bundle.getInt(KEY_VERSION); + if (version == 0) { + return playBillingToMojoResponseCode(responseCode); + } + + if (BillingResponseCode.isKnownValue(responseCode)) { + return responseCode; + } + + Log.w(TAG, "Unexpected response code: " + responseCode); + return BillingResponseCode.ERROR; + } + + /** Convenience method for legacy callers. */ + static int convertResponseCodeV0(int responseCode) { + return convertResponseCode(responseCode, new Bundle()); + } + + private static int playBillingToMojoResponseCode(int responseCode) { switch (responseCode) { case PLAY_BILLING_OK: return BillingResponseCode.OK;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/GetDetailsConverter.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/GetDetailsConverter.java index 6d48335..2d28f5d4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/GetDetailsConverter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/GetDetailsConverter.java
@@ -89,7 +89,7 @@ ItemDetails[] details = convertParcelableArray(array, GetDetailsConverter::convertItemDetails) .toArray(new ItemDetails[0]); - callback.call(convertResponseCode(code), details); + callback.call(convertResponseCode(code, args), details); } }; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/ListPurchasesConverter.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/ListPurchasesConverter.java index c8059bd..7263148 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/ListPurchasesConverter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/ListPurchasesConverter.java
@@ -78,7 +78,7 @@ PurchaseDetails[] details = convertParcelableArray( array, ListPurchasesConverter::convertPurchaseDetails) .toArray(new PurchaseDetails[0]); - callback.call(convertResponseCode(code), details); + callback.call(convertResponseCode(code, args), details); } }; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/digital_goods.md b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/digital_goods.md index 36660dd..5d3f290 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/digital_goods.md +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/digitalgoods/digital_goods.md
@@ -19,5 +19,19 @@ * `TrustedWebActivityClient` is the class that talks to Trusted Web Activities. * `DigitalGoodsAdapter` sits between `DigitalGoodsImpl` and `TrustedWebActivityClient`, transforming between appropriate data types. -* `DigitalGoodsConverter`, `GetDetailsConverter` and `AcknowledgeConverter` contain the lower level - transformations that `DigitalGoodsAdapter` uses. +* `DigitalGoodsConverter`, `GetDetailsConverter` and `AcknowledgeConverter` + contain the lower level transformations that `DigitalGoodsAdapter` uses. + +## Interface versions + +The bundles passed from the TWA shell to Chromium may contain a version code +(see `DigitalGoodsConverter#KEY_VERSION`). If the version code is missing, it +is assumed to be `0`. + +Naturally, version `0` was the first version of the interface, but it was +never used by stable Chromium or Android Browser Helper. + +Version changes: +- Version `1` changed the format of response code. Previously the response code + had been given in the Play Billing format. With version `1` Chromium expects + the TWA client to convert the response code to a Chromium format.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java index 1349ef0..4921a84 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -45,8 +45,8 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.browser_controls.BrowserControlsUtils; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerHost; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost; import org.chromium.chrome.browser.compositor.layouts.content.ContentOffsetProvider; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; @@ -91,7 +91,7 @@ * This class holds a {@link CompositorView}. This level of indirection is needed to benefit from * the {@link android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent)} capability on * available on {@link android.view.ViewGroup}s. - * This class also holds the {@link LayoutManager} responsible to describe the items to be + * This class also holds the {@link LayoutManagerImpl} responsible to describe the items to be * drawn by the UI compositor on the native side. */ public class CompositorViewHolder extends FrameLayout @@ -109,7 +109,7 @@ /** * Initializes the {@link CompositorViewHolder} with the relevant content it needs to * properly show content on the screen. - * @param layoutManager A {@link LayoutManager} instance. This class is + * @param layoutManager A {@link LayoutManagerImpl} instance. This class is * responsible for driving all high level screen content * and determines which {@link Layout} is shown when. * @param urlBar The {@link View} representing the URL bar (must be @@ -118,7 +118,7 @@ * {@link Layout}s. * @param controlContainer A {@link ControlContainer} instance to draw. */ - void initializeCompositorContent(LayoutManager layoutManager, View urlBar, + void initializeCompositorContent(LayoutManagerImpl layoutManager, View urlBar, ViewGroup contentContainer, ControlContainer controlContainer); } @@ -147,7 +147,7 @@ private boolean mIsKeyboardShowing; private final Invalidator mInvalidator = new Invalidator(); - private LayoutManager mLayoutManager; + private LayoutManagerImpl mLayoutManager; private LayerTitleCache mLayerTitleCache; private CompositorView mCompositorView; @@ -480,10 +480,10 @@ } /** - * @param layoutManager The {@link LayoutManager} instance that will be driving what + * @param layoutManager The {@link LayoutManagerImpl} instance that will be driving what * shows in this {@link CompositorViewHolder}. */ - public void setLayoutManager(LayoutManager layoutManager) { + public void setLayoutManager(LayoutManagerImpl layoutManager) { mLayoutManager = layoutManager; onViewportChanged(); } @@ -723,9 +723,9 @@ } /** - * @return The {@link LayoutManager} associated with this view. + * @return The {@link LayoutManagerImpl} associated with this view. */ - public LayoutManager getLayoutManager() { + public LayoutManagerImpl getLayoutManager() { return mLayoutManager; } @@ -1619,7 +1619,7 @@ int virtualViewId, int action, Bundle arguments) { switch (action) { case AccessibilityNodeInfoCompat.ACTION_CLICK: - mVirtualViews.get(virtualViewId).handleClick(LayoutManager.time()); + mVirtualViews.get(virtualViewId).handleClick(LayoutManagerImpl.time()); return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java index 1ffd837..b6d61333 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
@@ -20,7 +20,7 @@ import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager.PanelPriority; import org.chromium.chrome.browser.compositor.layouts.Layout; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; import org.chromium.chrome.browser.compositor.layouts.eventfilter.GestureHandler; @@ -109,7 +109,7 @@ } /** A layout manager for tracking changes in the active layout. */ - private final LayoutManager mLayoutManager; + private final LayoutManagerImpl mLayoutManager; /** The observer that reacts to scene-change events. */ private final SceneChangeObserver mSceneChangeObserver; @@ -160,11 +160,11 @@ /** * @param context The current Android {@link Context}. - * @param layoutManager A {@link LayoutManager} for observing changes in the active layout. + * @param layoutManager A {@link LayoutManagerImpl} for observing changes in the active layout. * @param panelManager The {@link OverlayPanelManager} responsible for showing panels. */ public OverlayPanel( - Context context, LayoutManager layoutManager, OverlayPanelManager panelManager) { + Context context, LayoutManagerImpl layoutManager, OverlayPanelManager panelManager) { super(context, layoutManager); mLayoutManager = layoutManager; mContentFactory = this;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java index 4694f1e..b1e5c794 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -18,7 +18,7 @@ import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager.PanelPriority; import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPromoControl.ContextualSearchPromoHost; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.scene_layer.ContextualSearchSceneLayer; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDelegate; import org.chromium.chrome.browser.contextualsearch.ResolvedSearchTerm.CardTag; @@ -80,7 +80,7 @@ * @param panelManager The object managing the how different panels are shown. */ public ContextualSearchPanel( - Context context, LayoutManager layoutManager, OverlayPanelManager panelManager) { + Context context, LayoutManagerImpl layoutManager, OverlayPanelManager panelManager) { super(context, layoutManager, panelManager); mSceneLayer = createNewContextualSearchSceneLayer(); mPanelMetrics = new ContextualSearchPanelMetrics();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java index ad246c74..e0866ca 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -50,10 +50,10 @@ /** * A {@link Layout} controller for the more complicated Chrome browser. This is currently a - * superset of {@link LayoutManager}. + * superset of {@link LayoutManagerImpl}. */ -public class LayoutManagerChrome - extends LayoutManager implements OverviewModeController, ChromeAccessibilityUtil.Observer { +public class LayoutManagerChrome extends LayoutManagerImpl + implements OverviewModeController, ChromeAccessibilityUtil.Observer { // Layouts /** An {@link Layout} that should be used as the accessibility tab switcher. */ protected OverviewListLayout mOverviewListLayout;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java similarity index 96% rename from chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java rename to chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java index e3c9e937..7108504 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java
@@ -39,6 +39,7 @@ import org.chromium.chrome.browser.gesturenav.HistoryNavigationCoordinator; import org.chromium.chrome.browser.layouts.CompositorModelChangeProcessor; import org.chromium.chrome.browser.layouts.EventFilter; +import org.chromium.chrome.browser.layouts.LayoutManager; import org.chromium.chrome.browser.layouts.LayoutStateProvider; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.layouts.SceneOverlay; @@ -84,8 +85,8 @@ * A class that is responsible for managing an active {@link Layout} to show to the screen. This * includes lifecycle managment like showing/hiding this {@link Layout}. */ -public class LayoutManager implements LayoutUpdateHost, LayoutProvider, - TabModelSelector.CloseAllTabsDelegate, LayoutStateProvider { +public class LayoutManagerImpl implements LayoutManager, LayoutUpdateHost, LayoutProvider, + TabModelSelector.CloseAllTabsDelegate { /** Sampling at 60 fps. */ private static final long FRAME_DELTA_TIME_MS = 16; @@ -181,7 +182,8 @@ /** * Protected class to handle {@link TabModelObserver} related tasks. Extending classes will - * need to override any related calls to add new functionality */ + * need to override any related calls to add new functionality + */ protected class LayoutManagerTabModelObserver implements TabModelObserver { @Override public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { @@ -241,7 +243,7 @@ @Override public void tabClosureCommitted(Tab tab) { - LayoutManager.this.tabClosureCommitted(tab.getId(), tab.isIncognito()); + LayoutManagerImpl.this.tabClosureCommitted(tab.getId(), tab.isIncognito()); } @Override @@ -251,7 +253,7 @@ } /** - * Creates a {@link LayoutManager} instance. + * Creates a {@link LayoutManagerImpl} instance. * @param host A {@link LayoutManagerHost} instance. * @param contentContainer A {@link ViewGroup} for Android views to be bound to. * @param tabContentManagerSupplier Supplier of the {@link TabContentManager} instance. @@ -259,7 +261,7 @@ * @param layoutStateProviderOneshotSupplier Supplier used to supply the {@link * LayoutStateProvider}. */ - public LayoutManager(LayoutManagerHost host, ViewGroup contentContainer, + public LayoutManagerImpl(LayoutManagerHost host, ViewGroup contentContainer, ObservableSupplier<TabContentManager> tabContentManagerSupplier, Supplier<LayerTitleCache> layerTitleCacheSupplier, OneshotSupplierImpl<LayoutStateProvider> layoutStateProviderOneshotSupplier) { @@ -320,7 +322,7 @@ } /** - * Gives the {@link LayoutManager} a chance to intercept and process touch events from the + * Gives the {@link LayoutManagerImpl} a chance to intercept and process touch events from the * Android {@link View} system. * @param e The {@link MotionEvent} that might be intercepted. * @param isKeyboardShowing Whether or not the keyboard is showing. @@ -365,7 +367,7 @@ } /** - * Gives the {@link LayoutManager} a chance to process the touch events from the Android + * Gives the {@link LayoutManagerImpl} a chance to process the touch events from the Android * {@link View} system. * @param e A {@link MotionEvent} instance. * @return Whether or not {@code e} was consumed. @@ -424,7 +426,7 @@ * Updates the state of the layout. * @param timeMs The time in milliseconds. * @param dtMs The delta time since the last update in milliseconds. - * @return Whether or not the {@link LayoutManager} needs more updates. + * @return Whether or not the {@link LayoutManagerImpl} needs more updates. */ @VisibleForTesting boolean onUpdate(long timeMs, long dtMs) { @@ -462,7 +464,7 @@ } /** - * Initializes the {@link LayoutManager}. Must be called before using this object. + * Initializes the {@link LayoutManagerImpl}. Must be called before using this object. * @param selector A {@link TabModelSelector} instance. * @param creator A {@link TabCreatorManager} instance. * @param controlContainer A {@link ControlContainer} for browser controls' layout. @@ -571,14 +573,7 @@ return mHost.getLayoutRenderHost().getResourceManager(); } - /** - * Creates a CompositorModelChangeProcessor observing the given {@code model} that will operate - * on this {@link LayoutManager}'s frame cycle. The model will be bound to the view initially - * and request a new frame. - * @param model The model containing the data to be bound to the view. - * @param view The view which the model will be bound to. - * @param viewBinder This is used to bind the model to the view. - */ + @Override public <V extends SceneLayer> CompositorModelChangeProcessor<V> createCompositorMCP( PropertyModel model, V view, PropertyModelChangeProcessor.ViewBinder<PropertyModel, V, PropertyKey> viewBinder) { @@ -618,9 +613,9 @@ // If the SceneOverlay is not showing, don't bother adding it to the tree. if (!mSceneOverlays.get(i).isSceneOverlayTreeShowing()) continue; - SceneOverlayLayer overlayLayer = mSceneOverlays.get(i).getUpdatedSceneOverlayTree( - mCachedWindowViewport, mCachedVisibleViewport, resourceManager, - offsetPx * mPxToDp); + SceneOverlayLayer overlayLayer = + mSceneOverlays.get(i).getUpdatedSceneOverlayTree(mCachedWindowViewport, + mCachedVisibleViewport, resourceManager, offsetPx * mPxToDp); overlayLayer.setContentTree(layer); layer = overlayLayer; @@ -1059,10 +1054,7 @@ return getActiveLayout() != null && getActiveLayout().onBackPressed(); } - /** - * Add a {@link SceneOverlay} to be drawn on the composited layer of the active layout. - * @param overlay The overlay to add. - */ + @Override public void addSceneOverlay(SceneOverlay overlay) { if (mSceneOverlays.contains(overlay)) throw new RuntimeException("Overlay already added!");
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java index 0486140..cb5e666a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/StackLayoutBase.java
@@ -27,7 +27,7 @@ import org.chromium.chrome.browser.browser_controls.BrowserControlsUtils; import org.chromium.chrome.browser.compositor.LayerTitleCache; import org.chromium.chrome.browser.compositor.layouts.Layout; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost; import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; @@ -372,7 +372,7 @@ } private long time() { - return LayoutManager.time(); + return LayoutManagerImpl.time(); } } @@ -422,7 +422,7 @@ ensureSceneLayerCreated(); if (mShowPending) { mShowPending = false; - show(LayoutManager.time(), false); + show(LayoutManagerImpl.time(), false); } } @@ -548,7 +548,7 @@ @Override public void tabClosureUndone(Tab tab) { if (!isActive()) return; - onTabClosureCancelled(LayoutManager.time(), tab.getId(), tab.isIncognito()); + onTabClosureCancelled(LayoutManagerImpl.time(), tab.getId(), tab.isIncognito()); } }; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java index 96deb282..0e1f75b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
@@ -17,7 +17,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.LayerTitleCache; import org.chromium.chrome.browser.compositor.TitleCache; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost; import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost; import org.chromium.chrome.browser.compositor.layouts.components.CompositorButton; @@ -149,7 +149,7 @@ } private long time() { - return LayoutManager.time(); + return LayoutManagerImpl.time(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayCoordinator.java index 3eecd6b..7705bfb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayCoordinator.java
@@ -8,12 +8,13 @@ import android.graphics.RectF; import org.chromium.base.Callback; +import org.chromium.base.supplier.Supplier; import org.chromium.chrome.R; import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; import org.chromium.chrome.browser.layouts.CompositorModelChangeProcessor; import org.chromium.chrome.browser.layouts.EventFilter; +import org.chromium.chrome.browser.layouts.LayoutManager; import org.chromium.chrome.browser.layouts.SceneOverlay; import org.chromium.chrome.browser.layouts.components.VirtualView; import org.chromium.chrome.browser.layouts.scene_layer.SceneOverlayLayer; @@ -40,7 +41,8 @@ public TopToolbarOverlayCoordinator(Context context, LayoutManager layoutManager, Callback<ClipDrawableProgressBar.DrawingInfo> progressInfoCallback, ActivityTabProvider tabSupplier, - BrowserControlsStateProvider browserControlsStateProvider) { + BrowserControlsStateProvider browserControlsStateProvider, + Supplier<ResourceManager> resourceManagerSupplier) { mModel = new PropertyModel.Builder(TopToolbarOverlayProperties.ALL_KEYS) .with(TopToolbarOverlayProperties.RESOURCE_ID, R.id.control_container) .with(TopToolbarOverlayProperties.URL_BAR_RESOURCE_ID, @@ -49,7 +51,7 @@ .with(TopToolbarOverlayProperties.CONTENT_OFFSET, browserControlsStateProvider.getContentOffset()) .build(); - mSceneLayer = new TopToolbarSceneLayer(() -> layoutManager.getResourceManager()); + mSceneLayer = new TopToolbarSceneLayer(resourceManagerSupplier); mChangeProcessor = layoutManager.createCompositorMCP(mModel, mSceneLayer, TopToolbarSceneLayer::bind);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayMediator.java index 2b7fe3c..3c67170 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayMediator.java
@@ -13,11 +13,9 @@ import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.browser_controls.BrowserControlsUtils; -import org.chromium.chrome.browser.compositor.layouts.Layout; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; -import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; -import org.chromium.chrome.browser.compositor.layouts.ToolbarSwipeLayout; -import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout; +import org.chromium.chrome.browser.layouts.LayoutStateProvider; +import org.chromium.chrome.browser.layouts.LayoutStateProvider.LayoutStateObserver; +import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabObserver; @@ -37,10 +35,10 @@ private final Context mContext; /** A handle to the layout manager for observing scene changes. */ - private final LayoutManager mLayoutManager; + private final LayoutStateProvider mLayoutStateProvider; /** The observer of changes to the active layout. */ - private final SceneChangeObserver mSceneChangeObserver; + private final LayoutStateObserver mSceneChangeObserver; /** A means of populating draw info for the progress bar. */ private final Callback<ClipDrawableProgressBar.DrawingInfo> mProgressInfoCallback; @@ -69,32 +67,29 @@ /** Whether the android view for this overlay is visible. */ private boolean mIsAndroidViewVisible; - TopToolbarOverlayMediator(PropertyModel model, Context context, LayoutManager layoutManager, + TopToolbarOverlayMediator(PropertyModel model, Context context, + LayoutStateProvider layoutStateProvider, Callback<ClipDrawableProgressBar.DrawingInfo> progressInfoCallback, ActivityTabProvider tabSupplier, BrowserControlsStateProvider browserControlsStateProvider) { mContext = context; - mLayoutManager = layoutManager; + mLayoutStateProvider = layoutStateProvider; mProgressInfoCallback = progressInfoCallback; mTabSupplier = tabSupplier; mBrowserControlsStateProvider = browserControlsStateProvider; mModel = model; - mSceneChangeObserver = new SceneChangeObserver() { + mSceneChangeObserver = new LayoutStateObserver() { @Override - public void onTabSelectionHinted(int tabId) {} - - @Override - public void onSceneChange(Layout layout) { - // TODO(1100332): Use layout IDs instead of type checking when they are available. + public void onStartedShowing(@LayoutType int layout, boolean showToolbar) { // TODO(1100332): Once ToolbarSwipeLayout uses a SceneLayer that does not include // its own toolbar, only check for the vertical tab switcher. mLayoutHasOwnToolbar = - layout instanceof StackLayout || layout instanceof ToolbarSwipeLayout; + layout == LayoutType.TAB_SWITCHER || layout == LayoutType.TOOLBAR_SWIPE; updateVisibility(); } }; - mLayoutManager.addSceneChangeObserver(mSceneChangeObserver); + mLayoutStateProvider.addObserver(mSceneChangeObserver); final TabObserver currentTabObserver = new EmptyTabObserver() { @Override @@ -230,7 +225,7 @@ mTabSupplierObserver.onActivityTabChanged(null, false); mLastActiveTab = null; - mLayoutManager.removeSceneChangeObserver(mSceneChangeObserver); + mLayoutStateProvider.removeObserver(mSceneChangeObserver); mBrowserControlsStateProvider.removeObserver(mBrowserControlsObserver); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java index 5a6f7c1..50b7e9d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java
@@ -10,6 +10,7 @@ import android.text.style.SuperscriptSpan; import androidx.annotation.IntDef; +import androidx.annotation.Nullable; import androidx.annotation.StringRes; import org.chromium.base.ApiCompatibilityUtils; @@ -33,9 +34,9 @@ Item.OPEN_IN_BROWSER_ID, Item.OPEN_IN_NEW_TAB, Item.OPEN_IN_INCOGNITO_TAB, Item.OPEN_IN_OTHER_WINDOW, Item.OPEN_IN_EPHEMERAL_TAB, Item.COPY_LINK_ADDRESS, Item.COPY_LINK_TEXT, Item.SAVE_LINK_AS, Item.SHARE_LINK, Item.DIRECT_SHARE_LINK, - Item.LOAD_ORIGINAL_IMAGE, Item.SAVE_IMAGE, Item.OPEN_IMAGE, Item.OPEN_IMAGE_IN_NEW_TAB, - Item.OPEN_IMAGE_IN_EPHEMERAL_TAB, Item.COPY_IMAGE, Item.SEARCH_BY_IMAGE, - Item.SEARCH_WITH_GOOGLE_LENS, Item.SHOP_SIMILAR_PRODUCTS, + Item.READ_LATER, Item.LOAD_ORIGINAL_IMAGE, Item.SAVE_IMAGE, Item.OPEN_IMAGE, + Item.OPEN_IMAGE_IN_NEW_TAB, Item.OPEN_IMAGE_IN_EPHEMERAL_TAB, Item.COPY_IMAGE, + Item.SEARCH_BY_IMAGE, Item.SEARCH_WITH_GOOGLE_LENS, Item.SHOP_SIMILAR_PRODUCTS, Item.SHOP_IMAGE_WITH_GOOGLE_LENS, Item.SEARCH_SIMILAR_PRODUCTS, Item.SHARE_IMAGE, Item.DIRECT_SHARE_IMAGE, Item.CALL, Item.SEND_MESSAGE, Item.ADD_TO_CONTACTS, Item.COPY, Item.SAVE_VIDEO, Item.OPEN_IN_CHROME}) @@ -57,31 +58,32 @@ int SAVE_LINK_AS = 9; int SHARE_LINK = 10; int DIRECT_SHARE_LINK = 11; + int READ_LATER = 12; // Image Group - int LOAD_ORIGINAL_IMAGE = 12; - int SAVE_IMAGE = 13; - int OPEN_IMAGE = 14; - int OPEN_IMAGE_IN_NEW_TAB = 15; - int OPEN_IMAGE_IN_EPHEMERAL_TAB = 16; - int COPY_IMAGE = 17; - int SEARCH_BY_IMAGE = 18; - int SEARCH_WITH_GOOGLE_LENS = 19; - int SHOP_SIMILAR_PRODUCTS = 20; - int SHOP_IMAGE_WITH_GOOGLE_LENS = 21; - int SEARCH_SIMILAR_PRODUCTS = 22; - int SHARE_IMAGE = 23; - int DIRECT_SHARE_IMAGE = 24; + int LOAD_ORIGINAL_IMAGE = 13; + int SAVE_IMAGE = 14; + int OPEN_IMAGE = 15; + int OPEN_IMAGE_IN_NEW_TAB = 16; + int OPEN_IMAGE_IN_EPHEMERAL_TAB = 17; + int COPY_IMAGE = 18; + int SEARCH_BY_IMAGE = 19; + int SEARCH_WITH_GOOGLE_LENS = 20; + int SHOP_SIMILAR_PRODUCTS = 21; + int SHOP_IMAGE_WITH_GOOGLE_LENS = 22; + int SEARCH_SIMILAR_PRODUCTS = 23; + int SHARE_IMAGE = 24; + int DIRECT_SHARE_IMAGE = 25; // Message Group - int CALL = 25; - int SEND_MESSAGE = 26; - int ADD_TO_CONTACTS = 27; - int COPY = 28; + int CALL = 26; + int SEND_MESSAGE = 27; + int ADD_TO_CONTACTS = 28; + int COPY = 29; // Video Group - int SAVE_VIDEO = 29; + int SAVE_VIDEO = 30; // Other - int OPEN_IN_CHROME = 30; + int OPEN_IN_CHROME = 31; // ALWAYS UPDATE! - int NUM_ENTRIES = 31; + int NUM_ENTRIES = 32; } /** @@ -100,6 +102,7 @@ R.id.contextmenu_save_link_as, // Item.SAVE_LINK_AS R.id.contextmenu_share_link, // Item.SHARE_LINK R.id.contextmenu_direct_share_link, // Item.DIRECT_SHARE_LINK + R.id.contextmenu_read_later, // Item.READ_LATER R.id.contextmenu_load_original_image, // Item.LOAD_ORIGINAL_IMAGE R.id.contextmenu_save_image, // Item.SAVE_IMAGE R.id.contextmenu_open_image, // Item.OPEN_IMAGE @@ -137,6 +140,7 @@ R.string.contextmenu_save_link, // Item.SAVE_LINK_AS: R.string.contextmenu_share_link, // Item.SHARE_LINK 0, // Item.DIRECT_SHARE_LINK is not handled by this mapping. + R.string.contextmenu_read_later, // Item.READ_LATER R.string.contextmenu_load_original_image, // Item.LOAD_ORIGINAL_IMAGE: R.string.contextmenu_save_image, // Item.SAVE_IMAGE: R.string.contextmenu_open_image, // Item.OPEN_IMAGE: @@ -201,6 +205,8 @@ TemplateUrlServiceFactory.get() .getDefaultSearchEngineTemplateUrl() .getShortName()); + case Item.READ_LATER: + return addOrRemoveNewLabel(context, item, null, showInProductHelp); case Item.OPEN_IN_EPHEMERAL_TAB: return addOrRemoveNewLabel(context, item, ChromePreferenceKeys.CONTEXT_MENU_OPEN_IN_EPHEMERAL_TAB_CLICKED, @@ -235,9 +241,11 @@ * has already been selected before. */ private static CharSequence addOrRemoveNewLabel( - Context context, @Item int item, String prefKey, boolean showNewLabel) { + Context context, @Item int item, @Nullable String prefKey, boolean showNewLabel) { String menuTitle = context.getString(getStringId(item)); - if (!showNewLabel || SharedPreferencesManager.getInstance().readBoolean(prefKey, false)) { + if (!showNewLabel + || (prefKey != null + && SharedPreferencesManager.getInstance().readBoolean(prefKey, false))) { return SpanApplier.removeSpanText(menuTitle, new SpanInfo("<new>", "</new>")); } return SpanApplier.applySpans(menuTitle,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java index d141da07..c178f74 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -32,6 +32,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator; import org.chromium.chrome.browser.contextmenu.ChromeContextMenuItem.Item; +import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator.ContextMenuUma.Action; import org.chromium.chrome.browser.contextmenu.RevampedContextMenuCoordinator.ListItemType; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; @@ -135,7 +136,7 @@ Action.SHARE_LINK, Action.OPEN_IN_EPHEMERAL_TAB, Action.OPEN_IMAGE_IN_EPHEMERAL_TAB, Action.DIRECT_SHARE_LINK, Action.DIRECT_SHARE_IMAGE, Action.SEARCH_WITH_GOOGLE_LENS, Action.COPY_IMAGE, Action.SHOP_SIMILAR_PRODUCTS, Action.SHOP_IMAGE_WITH_GOOGLE_LENS, - Action.SEARCH_SIMILAR_PRODUCTS}) + Action.SEARCH_SIMILAR_PRODUCTS, Action.READ_LATER}) @Retention(RetentionPolicy.SOURCE) public @interface Action { int OPEN_IN_NEW_TAB = 0; @@ -175,7 +176,8 @@ int SHOP_SIMILAR_PRODUCTS = 30; int SHOP_IMAGE_WITH_GOOGLE_LENS = 31; int SEARCH_SIMILAR_PRODUCTS = 32; - int NUM_ENTRIES = 33; + int READ_LATER = 33; + int NUM_ENTRIES = 34; } // Note: these values must match the ContextMenuSaveLinkType enum in enums.xml. @@ -396,6 +398,10 @@ if (!mItemDelegate.isIncognito() && UrlUtilities.isDownloadableScheme(mParams.getLinkUrl())) { linkGroup.add(createListItem(Item.SAVE_LINK_AS)); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.READ_LATER)) { + linkGroup.add( + createListItem(Item.READ_LATER, shouldTriggerReadLaterHelpUi())); + } } linkGroup.add(createShareListItem(Item.SHARE_LINK, Item.DIRECT_SHARE_LINK)); if (UrlUtilities.isTelScheme(mParams.getLinkUrl())) { @@ -582,6 +588,12 @@ && tracker.shouldTriggerHelpUI(FeatureConstants.EPHEMERAL_TAB_FEATURE); } + private boolean shouldTriggerReadLaterHelpUi() { + Tracker tracker = TrackerFactory.getTrackerForProfile(Profile.getLastUsedRegularProfile()); + return tracker.isInitialized() + && tracker.shouldTriggerHelpUI(FeatureConstants.READ_LATER_CONTEXT_MENU_FEATURE); + } + @Override public boolean isIncognito() { return mItemDelegate.isIncognito(); @@ -680,6 +692,9 @@ .build(); mShareDelegateSupplier.get().share( linkShareParams, new ChromeShareExtras.Builder().setSaveLastUsed(true).build()); + } else if (itemId == R.id.contextmenu_read_later) { + recordContextMenuSelection(ContextMenuUma.Action.READ_LATER); + // TODO(crbug/1145825): Implement backend action. } else if (itemId == R.id.contextmenu_direct_share_link) { recordContextMenuSelection(ContextMenuUma.Action.DIRECT_SHARE_LINK); final ShareParams shareParams =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java index 4fff3ae..6b1dcac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -29,7 +29,7 @@ import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.PanelState; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanel; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.contextualsearch.ContextualSearchFieldTrial.ContextualSearchSetting; import org.chromium.chrome.browser.contextualsearch.ContextualSearchFieldTrial.ContextualSearchSwitch; import org.chromium.chrome.browser.contextualsearch.ContextualSearchInternalStateController.InternalState; @@ -215,7 +215,7 @@ private Supplier<Tab> mTabSupplier; /** A means of observing scene changes and attaching overlays. */ - private LayoutManager mLayoutManager; + private LayoutManagerImpl mLayoutManager; /** * The delegate that is responsible for promoting a {@link WebContents} to a {@link Tab} @@ -285,7 +285,7 @@ * @param parentView The parent view to attach Contextual Search UX to. * @param layoutManager A means of attaching the OverlayPanel to the scene. */ - public void initialize(ViewGroup parentView, LayoutManager layoutManager) { + public void initialize(ViewGroup parentView, LayoutManagerImpl layoutManager) { mNativeContextualSearchManagerPtr = ContextualSearchManagerJni.get().init(this); mParentView = parentView;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java index 566a6863..f2db8a3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java
@@ -28,7 +28,7 @@ import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager.OverlayPanelManagerObserver; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.night_mode.RemoteViewsWithNightModeInflater; import org.chromium.chrome.browser.night_mode.SystemNightModeMonitor; @@ -232,7 +232,7 @@ return mBottomBarView; } - public void addOverlayPanelManagerObserver(LayoutManager layoutDriver) { + public void addOverlayPanelManagerObserver(LayoutManagerImpl layoutDriver) { layoutDriver.getOverlayPanelManager().addObserver(new OverlayPanelManagerObserver() { @Override public void onOverlayPanelShown() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabCompositorContentInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabCompositorContentInitializer.java index f4f3ba5..cb5531b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabCompositorContentInitializer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabCompositorContentInitializer.java
@@ -11,7 +11,7 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.chrome.browser.compositor.CompositorViewHolder; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; @@ -29,7 +29,7 @@ */ @ActivityScope public class CustomTabCompositorContentInitializer implements NativeInitObserver { - private final List<Callback<LayoutManager>> mListeners = new ArrayList<>(); + private final List<Callback<LayoutManagerImpl>> mListeners = new ArrayList<>(); private final ActivityLifecycleDispatcher mLifecycleDispatcher; private final Activity mActivity; @@ -57,7 +57,7 @@ * Adds a callback that will be called once the Compositor View Holder has its content * initialized, or immediately (synchronously) if it is already initialized. */ - public void addCallback(Callback<LayoutManager> callback) { + public void addCallback(Callback<LayoutManagerImpl> callback) { if (mInitialized) { callback.onResult(mCompositorViewHolder.get().getLayoutManager()); } else { @@ -68,19 +68,17 @@ @Override public void onFinishNativeInitialization() { ViewGroup contentContainer = mActivity.findViewById(android.R.id.content); - LayoutManager layoutDriver = new LayoutManager(mCompositorViewHolder.get(), - contentContainer, mTabContentManagerSupplier, - () -> { + LayoutManagerImpl layoutDriver = new LayoutManagerImpl( + mCompositorViewHolder.get(), contentContainer, mTabContentManagerSupplier, () -> { if (mCompositorViewHolder.get() == null) return null; return mCompositorViewHolder.get().getLayerTitleCache(); - }, - new OneshotSupplierImpl<>()); + }, new OneshotSupplierImpl<>()); mCompositorViewHolderInitializer.initializeCompositorContent(layoutDriver, mActivity.findViewById(org.chromium.chrome.R.id.url_bar), contentContainer, mActivity.findViewById(org.chromium.chrome.R.id.control_container)); - for (Callback<LayoutManager> listener : mListeners) { + for (Callback<LayoutManagerImpl> listener : mListeners) { listener.onResult(layoutDriver); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java index 9c18e8e..2eab033 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java
@@ -24,7 +24,7 @@ import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.browser_controls.BrowserControlsVisibilityManager; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.customtabs.CloseButtonVisibilityManager; import org.chromium.chrome.browser.customtabs.CustomButtonParams; import org.chromium.chrome.browser.customtabs.CustomTabCompositorContentInitializer; @@ -172,7 +172,7 @@ } } - private void onCompositorContentInitialized(LayoutManager layoutDriver) { + private void onCompositorContentInitialized(LayoutManagerImpl layoutDriver) { mToolbarManager.initializeWithNative( layoutDriver, null, null, null, v -> onCloseButtonClick(), null); mInitializedToolbarWithNative = true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityCommonsModule.java b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityCommonsModule.java index a17261a..3a001e2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityCommonsModule.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityCommonsModule.java
@@ -20,7 +20,7 @@ import org.chromium.chrome.browser.browser_controls.BrowserControlsSizer; import org.chromium.chrome.browser.browser_controls.BrowserControlsVisibilityManager; import org.chromium.chrome.browser.compositor.CompositorViewHolder; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.fullscreen.BrowserControlsManager; import org.chromium.chrome.browser.fullscreen.FullscreenManager; @@ -53,7 +53,7 @@ private final BrowserControlsVisibilityManager mBrowserControlsVisibilityManager; private final BrowserControlsSizer mBrowserControlsSizer; private final FullscreenManager mFullscreenManager; - private final Supplier<LayoutManager> mLayoutManagerSupplier; + private final Supplier<LayoutManagerImpl> mLayoutManagerSupplier; private final ActivityLifecycleDispatcher mLifecycleDispatcher; private final Supplier<SnackbarManager> mSnackbarManagerSupplier; private final ActivityTabProvider mActivityTabProvider; @@ -77,7 +77,7 @@ BrowserControlsManager browserControlsManager, BrowserControlsVisibilityManager browserControlsVisibilityManager, BrowserControlsSizer browserControlsSizer, FullscreenManager fullscreenManager, - Supplier<LayoutManager> layoutManagerSupplier, + Supplier<LayoutManagerImpl> layoutManagerSupplier, ActivityLifecycleDispatcher lifecycleDispatcher, Supplier<SnackbarManager> snackbarManagerSupplier, ActivityTabProvider activityTabProvider, TabContentManager tabContentManager, @@ -98,7 +98,7 @@ BrowserControlsManager browserControlsManager, BrowserControlsVisibilityManager browserControlsVisibilityManager, BrowserControlsSizer browserControlsSizer, FullscreenManager fullscreenManager, - Supplier<LayoutManager> layoutManagerSupplier, + Supplier<LayoutManagerImpl> layoutManagerSupplier, ActivityLifecycleDispatcher lifecycleDispatcher, Supplier<SnackbarManager> snackbarManagerSupplier, ActivityTabProvider activityTabProvider, TabContentManager tabContentManager, @@ -166,7 +166,7 @@ } @Provides - public LayoutManager provideLayoutManager() { + public LayoutManagerImpl provideLayoutManager() { return mLayoutManagerSupplier.get(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationCoordinator.java index 7c486b1a..3d3584f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationCoordinator.java
@@ -18,7 +18,7 @@ import org.chromium.chrome.browser.ActivityTabProvider.ActivityTabTabObserver; import org.chromium.chrome.browser.SwipeRefreshHandler; import org.chromium.chrome.browser.compositor.CompositorViewHolder; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver; @@ -78,8 +78,9 @@ ActivityLifecycleDispatcher lifecycleDispatcher, CompositorViewHolder compositorViewHolder, ActivityTabProvider tabProvider, InsetObserverView insetObserverView, Function<Tab, Boolean> backShouldCloseTab, - Runnable onBackPressed, LayoutManager layoutManager, Consumer<Tab> showHistoryManager, - String historyMenu, Supplier<BottomSheetController> bottomSheetControllerSupplier) { + Runnable onBackPressed, LayoutManagerImpl layoutManager, + Consumer<Tab> showHistoryManager, String historyMenu, + Supplier<BottomSheetController> bottomSheetControllerSupplier) { if (!isFeatureFlagEnabled()) return null; HistoryNavigationCoordinator coordinator = new HistoryNavigationCoordinator(); coordinator.init(window, lifecycleDispatcher, compositorViewHolder, tabProvider, @@ -99,8 +100,9 @@ private void init(WindowAndroid window, ActivityLifecycleDispatcher lifecycleDispatcher, CompositorViewHolder compositorViewHolder, ActivityTabProvider tabProvider, InsetObserverView insetObserverView, Function<Tab, Boolean> backShouldCloseTab, - Runnable onBackPressed, LayoutManager layoutManager, Consumer<Tab> showHistoryManager, - String historyMenu, Supplier<BottomSheetController> bottomSheetControllerSupplier) { + Runnable onBackPressed, LayoutManagerImpl layoutManager, + Consumer<Tab> showHistoryManager, String historyMenu, + Supplier<BottomSheetController> bottomSheetControllerSupplier) { mOverscrollGlowOverlay = new OverscrollGlowOverlay(window, compositorViewHolder, () -> compositorViewHolder.getLayoutManager().getActiveLayout().requestUpdate()); mNavigationLayout = new HistoryNavigationLayout(compositorViewHolder.getContext(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java index cc3fce5..0e81ff34 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java
@@ -4,19 +4,26 @@ package org.chromium.chrome.browser.infobar; +import android.content.res.Resources; import android.graphics.Bitmap; import android.text.SpannableString; import android.text.Spanned; import android.text.TextUtils; import android.text.style.ClickableSpan; +import android.view.LayoutInflater; import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.R; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.components.browser_ui.widget.RoundedCornerImageView; import org.chromium.components.infobars.ConfirmInfoBar; import org.chromium.components.infobars.InfoBarControlLayout; import org.chromium.components.infobars.InfoBarLayout; +import org.chromium.components.signin.base.AccountInfo; import org.chromium.ui.UiUtils; import java.util.ArrayList; @@ -84,6 +91,7 @@ } } + private final AccountInfo mAccountInfo; private final long mNativeAutofillSaveCardInfoBar; private final List<CardDetail> mCardDetails = new ArrayList<>(); private int mIconDrawableId = -1; @@ -103,10 +111,11 @@ * @param linkText Link text to display in addition to the message. * @param buttonOk String to display on the OK button. * @param buttonCancel String to display on the Cancel button. + * @param accountInfo AccountInfo which includes user's email address and profile picture. */ private AutofillSaveCardInfoBar(long nativeAutofillSaveCardInfoBar, int iconId, Bitmap iconBitmap, String message, String linkText, String buttonOk, - String buttonCancel, boolean isGooglePayBrandingEnabled) { + String buttonCancel, boolean isGooglePayBrandingEnabled, AccountInfo accountInfo) { // If Google Pay branding is enabled, no icon is specified here; it is rather added in // |createContent|. This hides the ImageView that normally shows the icon and gets rid of // the left padding of the infobar content. @@ -117,6 +126,7 @@ mTitleText = message; mIsGooglePayBrandingEnabled = isGooglePayBrandingEnabled; mNativeAutofillSaveCardInfoBar = nativeAutofillSaveCardInfoBar; + mAccountInfo = accountInfo; } /** @@ -129,14 +139,15 @@ * @param linkText Link text to display in addition to the message. * @param buttonOk String to display on the OK button. * @param buttonCancel String to display on the Cancel button. + * @param accountInfo AccountInfo which includes user's email address and profile picture. * @return A new instance of the infobar. */ @CalledByNative private static AutofillSaveCardInfoBar create(long nativeAutofillSaveCardInfoBar, int iconId, Bitmap iconBitmap, String message, String linkText, String buttonOk, - String buttonCancel, boolean isGooglePayBrandingEnabled) { + String buttonCancel, boolean isGooglePayBrandingEnabled, AccountInfo accountInfo) { return new AutofillSaveCardInfoBar(nativeAutofillSaveCardInfoBar, iconId, iconBitmap, - message, linkText, buttonOk, buttonCancel, isGooglePayBrandingEnabled); + message, linkText, buttonOk, buttonCancel, isGooglePayBrandingEnabled, accountInfo); } /** @@ -219,6 +230,31 @@ } control.addDescription(text); } + + if (ChromeFeatureList.isEnabled( + ChromeFeatureList.AUTOFILL_ENABLE_SAVE_CARD_INFO_BAR_ACCOUNT_INDICATION_FOOTER) + && mAccountInfo != null && !TextUtils.isEmpty(mAccountInfo.getEmail()) + && mAccountInfo.getAccountImage() != null) { + Resources res = layout.getResources(); + int smallIconSize = res.getDimensionPixelSize(R.dimen.infobar_small_icon_size); + int padding = res.getDimensionPixelOffset(R.dimen.infobar_padding); + + LinearLayout footer = (LinearLayout) LayoutInflater.from(layout.getContext()) + .inflate(R.layout.infobar_footer, null, false); + + TextView emailView = (TextView) footer.findViewById(R.id.infobar_footer_email); + emailView.setText(mAccountInfo.getEmail()); + + RoundedCornerImageView profilePicView = + (RoundedCornerImageView) footer.findViewById(R.id.infobar_footer_profile_pic); + Bitmap resizedProfilePic = Bitmap.createScaledBitmap( + mAccountInfo.getAccountImage(), smallIconSize, smallIconSize, false); + profilePicView.setRoundedCorners( + smallIconSize / 2, smallIconSize / 2, smallIconSize / 2, smallIconSize / 2); + profilePicView.setImageBitmap(resizedProfilePic); + + layout.addFooterView(footer); + } } @NativeMethods
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java index 22ea9c5..9fe74043 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
@@ -111,9 +111,9 @@ @Override public void inflate() { - OmniboxSuggestionsRecyclerView dropdown; + OmniboxSuggestionsDropdown dropdown; try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) { - dropdown = new OmniboxSuggestionsRecyclerView(context); + dropdown = new OmniboxSuggestionsDropdown(context); } // Start with visibility GONE to ensure that show() is called. @@ -121,8 +121,8 @@ dropdown.getViewGroup().setVisibility(View.GONE); dropdown.getViewGroup().setClipToPadding(false); - OmniboxSuggestionsRecyclerViewAdapter adapter = - new OmniboxSuggestionsRecyclerViewAdapter(modelList); + OmniboxSuggestionsDropdownAdapter adapter = + new OmniboxSuggestionsDropdownAdapter(modelList); dropdown.setAdapter(adapter); // Note: clang-format does a bad job formatting lambdas so we turn it off here.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java index 737c33e..d51026a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdown.java
@@ -4,16 +4,36 @@ package org.chromium.chrome.browser.omnibox.suggestions; +import android.content.Context; +import android.content.res.Resources; +import android.view.KeyEvent; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Px; +import androidx.core.view.ViewCompat; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import org.chromium.base.TraceEvent; +import org.chromium.chrome.R; import org.chromium.chrome.browser.WindowDelegate; +import org.chromium.chrome.browser.util.KeyNavigationUtil; -/** Represents the basic functionality of the Omnibox suggestions dropdown. */ -public interface OmniboxSuggestionsDropdown { +/** + * A widget for showing a list of omnibox suggestions. + */ +public class OmniboxSuggestionsDropdown extends RecyclerView { + private final @NonNull OmniboxSuggestionsDropdownDelegate mDropdownDelegate; + private final @NonNull SuggestionScrollListener mScrollListener; + private @Nullable OmniboxSuggestionsDropdown.Observer mObserver; + private @Nullable OmniboxSuggestionsDropdownAdapter mAdapter; + + private final int[] mTempMeasureSpecs = new int[2]; + /** Provides the capabilities required to embed the omnibox suggestion list into the UI. */ public interface Embedder { /** Return the anchor view the suggestion list should be drawn below. */ @@ -64,36 +84,213 @@ void onGesture(boolean isGestureUp, long timestamp); } + /** Scroll listener that propagates scroll event notification to registered observers. */ + private class SuggestionScrollListener extends RecyclerView.OnScrollListener { + private OmniboxSuggestionsDropdown.Observer mObserver; + + void setObserver(OmniboxSuggestionsDropdown.Observer observer) { + mObserver = observer; + } + + @Override + public void onScrolled(RecyclerView view, int dx, int dy) {} + + @Override + public void onScrollStateChanged(RecyclerView view, int scrollState) { + if (scrollState == SCROLL_STATE_DRAGGING && mObserver != null) { + mObserver.onSuggestionDropdownScroll(); + } + } + + void onOverscrollToTop() { + mObserver.onSuggestionDropdownOverscrolledToTop(); + } + } + + /** + * RecyclerView pool that records performance of the view recycling mechanism. + * @see OmniboxSuggestionsListViewListAdapter#canReuseView(View, int) + */ + private class HistogramRecordingRecycledViewPool extends RecycledViewPool { + HistogramRecordingRecycledViewPool() { + setMaxRecycledViews(OmniboxSuggestionUiType.CLIPBOARD_SUGGESTION, 1); + setMaxRecycledViews(OmniboxSuggestionUiType.EDIT_URL_SUGGESTION, 1); + setMaxRecycledViews(OmniboxSuggestionUiType.ANSWER_SUGGESTION, 1); + setMaxRecycledViews(OmniboxSuggestionUiType.DEFAULT, 15); + setMaxRecycledViews(OmniboxSuggestionUiType.ENTITY_SUGGESTION, 5); + setMaxRecycledViews(OmniboxSuggestionUiType.TAIL_SUGGESTION, 10); + } + + @Override + public ViewHolder getRecycledView(int viewType) { + ViewHolder result = super.getRecycledView(viewType); + SuggestionsMetrics.recordSuggestionViewReused(result != null); + return result; + } + } + + /** + * Constructs a new list designed for containing omnibox suggestions. + * @param context Context used for contained views. + */ + public OmniboxSuggestionsDropdown(Context context) { + super(context, null, android.R.attr.dropDownListViewStyle); + setFocusable(true); + setFocusableInTouchMode(true); + setRecycledViewPool(new HistogramRecordingRecycledViewPool()); + + // By default RecyclerViews come with item animators. + setItemAnimator(null); + + mScrollListener = new SuggestionScrollListener(); + setOnScrollListener(mScrollListener); + setLayoutManager(new LinearLayoutManager(context) { + @Override + public int scrollVerticallyBy( + int deltaY, RecyclerView.Recycler recycler, RecyclerView.State state) { + int scrollY = super.scrollVerticallyBy(deltaY, recycler, state); + if (scrollY == 0 && deltaY < 0) { + mScrollListener.onOverscrollToTop(); + } + return scrollY; + } + }); + + final Resources resources = context.getResources(); + int paddingBottom = + resources.getDimensionPixelOffset(R.dimen.omnibox_suggestion_list_padding_bottom); + ViewCompat.setPaddingRelative(this, 0, 0, 0, paddingBottom); + + mDropdownDelegate = new OmniboxSuggestionsDropdownDelegate(resources, this); + } + /** Get the Android View implementing suggestion list. */ - ViewGroup getViewGroup(); - - /** Show (and properly size) the suggestions list. */ - void show(); - - /** Hide the suggestions list and release any cached resources. */ - void hide(); + public ViewGroup getViewGroup() { + return this; + } /** * Sets the embedder for the list view. * @param embedder the embedder of this list. */ - void setEmbedder(Embedder embedder); + public void setEmbedder(OmniboxSuggestionsDropdown.Embedder embedder) { + mDropdownDelegate.setEmbedder(embedder); + } /** * Sets the observer of suggestion list. * @param observer an observer of this list. */ - void setObserver(Observer observer); + public void setObserver(OmniboxSuggestionsDropdown.Observer observer) { + mObserver = observer; + mScrollListener.setObserver(observer); + mDropdownDelegate.setObserver(observer); + } /** Resets selection typically in response to changes to the list. */ - void resetSelection(); - - /** Update the suggestion popup background to reflect the current state. */ - void refreshPopupBackground(boolean isIncognito); + public void resetSelection() { + if (mAdapter == null) return; + mAdapter.resetSelection(); + } /** @return The number of items in the list. */ - int getDropdownItemViewCountForTest(); + public int getDropdownItemViewCountForTest() { + if (mAdapter == null) return 0; + return mAdapter.getItemCount(); + } /** @return The Suggestion view at specific index. */ - View getDropdownItemViewForTest(int position); + public View getDropdownItemViewForTest(int index) { + final LayoutManager manager = getLayoutManager(); + manager.scrollToPosition(index); + return manager.findViewByPosition(index); + } + + /** Show (and properly size) the suggestions list. */ + public void show() { + if (getVisibility() == VISIBLE) return; + + setVisibility(VISIBLE); + if (mAdapter != null && mAdapter.getSelectedViewIndex() != 0) { + mAdapter.resetSelection(); + } + } + + /** Hide the suggestions list and release any cached resources. */ + public void hide() { + if (getVisibility() != VISIBLE) return; + setVisibility(GONE); + getRecycledViewPool().clear(); + } + + /** Update the suggestion popup background to reflect the current state. */ + public void refreshPopupBackground(boolean isIncognito) { + setBackground(mDropdownDelegate.getPopupBackground(isIncognito)); + } + + @Override + public void setAdapter(Adapter adapter) { + mAdapter = (OmniboxSuggestionsDropdownAdapter) adapter; + super.setAdapter(mAdapter); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + getRecycledViewPool().clear(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + try (TraceEvent tracing = TraceEvent.scoped("OmniboxSuggestionsList.Measure"); + SuggestionsMetrics.TimingMetric metric = + SuggestionsMetrics.recordSuggestionListMeasureTime()) { + mDropdownDelegate.calculateOnMeasureAndTriggerUpdates(mTempMeasureSpecs); + super.onMeasure(mTempMeasureSpecs[0], mTempMeasureSpecs[1]); + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + try (TraceEvent tracing = TraceEvent.scoped("OmniboxSuggestionsList.Layout"); + SuggestionsMetrics.TimingMetric metric = + SuggestionsMetrics.recordSuggestionListLayoutTime()) { + super.onLayout(changed, l, t, r, b); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (!isShown()) return false; + + int selectedPosition = mAdapter.getSelectedViewIndex(); + if (KeyNavigationUtil.isGoDown(event)) { + return mAdapter.setSelectedViewIndex(selectedPosition + 1); + } else if (KeyNavigationUtil.isGoUp(event)) { + return mAdapter.setSelectedViewIndex(selectedPosition - 1); + } else if (KeyNavigationUtil.isGoRight(event) || KeyNavigationUtil.isGoLeft(event)) { + View selectedView = mAdapter.getSelectedView(); + if (selectedView != null) return selectedView.onKeyDown(keyCode, event); + } else if (KeyNavigationUtil.isEnter(event)) { + View selectedView = mAdapter.getSelectedView(); + if (selectedView != null) return selectedView.performClick(); + } + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onGenericMotionEvent(MotionEvent event) { + return mDropdownDelegate.shouldIgnoreGenericMotionEvent(event) + || super.onGenericMotionEvent(event); + } + + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + final int eventType = ev.getActionMasked(); + if ((eventType == MotionEvent.ACTION_UP || eventType == MotionEvent.ACTION_DOWN) + && mObserver != null) { + mObserver.onGesture(eventType == MotionEvent.ACTION_UP, ev.getEventTime()); + } + return super.dispatchTouchEvent(ev); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsRecyclerViewAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownAdapter.java similarity index 93% rename from chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsRecyclerViewAdapter.java rename to chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownAdapter.java index 0c07c9d..0387e03 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsRecyclerViewAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownAdapter.java
@@ -15,14 +15,12 @@ import org.chromium.ui.modelutil.MVCListAdapter.ModelList; import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter; -/** - * ModelListAdapter for SuggestionList. - */ -class OmniboxSuggestionsRecyclerViewAdapter extends SimpleRecyclerViewAdapter { +/** ModelListAdapter for OmniboxSuggestionsDropdown (RecyclerView version). */ +class OmniboxSuggestionsDropdownAdapter extends SimpleRecyclerViewAdapter { private int mSelectedItem = RecyclerView.NO_POSITION; private LayoutManager mLayoutManager; - OmniboxSuggestionsRecyclerViewAdapter(ModelList data) { + OmniboxSuggestionsDropdownAdapter(ModelList data) { super(data); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsRecyclerView.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsRecyclerView.java deleted file mode 100644 index 0f8645b9..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsRecyclerView.java +++ /dev/null
@@ -1,239 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.omnibox.suggestions; - -import android.content.Context; -import android.content.res.Resources; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.view.ViewCompat; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import org.chromium.base.TraceEvent; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.util.KeyNavigationUtil; - -/** - * A widget for showing a list of omnibox suggestions. - */ -public class OmniboxSuggestionsRecyclerView - extends RecyclerView implements OmniboxSuggestionsDropdown { - private final @NonNull OmniboxSuggestionsDropdownDelegate mDropdownDelegate; - private final @NonNull SuggestionScrollListener mScrollListener; - private @Nullable OmniboxSuggestionsDropdown.Observer mObserver; - private @Nullable OmniboxSuggestionsRecyclerViewAdapter mAdapter; - - private final int[] mTempMeasureSpecs = new int[2]; - - /** Scroll listener that propagates scroll event notification to registered observers. */ - private class SuggestionScrollListener extends RecyclerView.OnScrollListener { - private OmniboxSuggestionsDropdown.Observer mObserver; - - void setObserver(OmniboxSuggestionsDropdown.Observer observer) { - mObserver = observer; - } - - @Override - public void onScrolled(RecyclerView view, int dx, int dy) {} - - @Override - public void onScrollStateChanged(RecyclerView view, int scrollState) { - if (scrollState == SCROLL_STATE_DRAGGING && mObserver != null) { - mObserver.onSuggestionDropdownScroll(); - } - } - - void onOverscrollToTop() { - mObserver.onSuggestionDropdownOverscrolledToTop(); - } - } - - /** - * RecyclerView pool that records performance of the view recycling mechanism. - * @see OmniboxSuggestionsListViewListAdapter#canReuseView(View, int) - */ - private class HistogramRecordingRecycledViewPool extends RecycledViewPool { - HistogramRecordingRecycledViewPool() { - setMaxRecycledViews(OmniboxSuggestionUiType.CLIPBOARD_SUGGESTION, 1); - setMaxRecycledViews(OmniboxSuggestionUiType.EDIT_URL_SUGGESTION, 1); - setMaxRecycledViews(OmniboxSuggestionUiType.ANSWER_SUGGESTION, 1); - setMaxRecycledViews(OmniboxSuggestionUiType.DEFAULT, 15); - setMaxRecycledViews(OmniboxSuggestionUiType.ENTITY_SUGGESTION, 5); - setMaxRecycledViews(OmniboxSuggestionUiType.TAIL_SUGGESTION, 10); - } - - @Override - public ViewHolder getRecycledView(int viewType) { - ViewHolder result = super.getRecycledView(viewType); - SuggestionsMetrics.recordSuggestionViewReused(result != null); - return result; - } - } - - /** - * Constructs a new list designed for containing omnibox suggestions. - * @param context Context used for contained views. - */ - public OmniboxSuggestionsRecyclerView(Context context) { - super(context, null, android.R.attr.dropDownListViewStyle); - setFocusable(true); - setFocusableInTouchMode(true); - setRecycledViewPool(new HistogramRecordingRecycledViewPool()); - - // By default RecyclerViews come with item animators. - setItemAnimator(null); - - mScrollListener = new SuggestionScrollListener(); - setOnScrollListener(mScrollListener); - setLayoutManager(new LinearLayoutManager(context) { - @Override - public int scrollVerticallyBy( - int deltaY, RecyclerView.Recycler recycler, RecyclerView.State state) { - int scrollY = super.scrollVerticallyBy(deltaY, recycler, state); - if (scrollY == 0 && deltaY < 0) { - mScrollListener.onOverscrollToTop(); - } - return scrollY; - } - }); - - final Resources resources = context.getResources(); - int paddingBottom = - resources.getDimensionPixelOffset(R.dimen.omnibox_suggestion_list_padding_bottom); - ViewCompat.setPaddingRelative(this, 0, 0, 0, paddingBottom); - - mDropdownDelegate = new OmniboxSuggestionsDropdownDelegate(resources, this); - } - - @Override - public ViewGroup getViewGroup() { - return this; - } - - @Override - public void setEmbedder(OmniboxSuggestionsDropdown.Embedder embedder) { - mDropdownDelegate.setEmbedder(embedder); - } - - @Override - public void setObserver(OmniboxSuggestionsDropdown.Observer observer) { - mObserver = observer; - mScrollListener.setObserver(observer); - mDropdownDelegate.setObserver(observer); - } - - @Override - public void resetSelection() { - if (mAdapter == null) return; - mAdapter.resetSelection(); - } - - @Override - public int getDropdownItemViewCountForTest() { - if (mAdapter == null) return 0; - return mAdapter.getItemCount(); - } - - @Override - public View getDropdownItemViewForTest(int index) { - final LayoutManager manager = getLayoutManager(); - manager.scrollToPosition(index); - return manager.findViewByPosition(index); - } - - @Override - public void show() { - if (getVisibility() == VISIBLE) return; - - setVisibility(VISIBLE); - if (mAdapter != null && mAdapter.getSelectedViewIndex() != 0) { - mAdapter.resetSelection(); - } - } - - @Override - public void hide() { - if (getVisibility() != VISIBLE) return; - setVisibility(GONE); - getRecycledViewPool().clear(); - } - - @Override - public void refreshPopupBackground(boolean isIncognito) { - setBackground(mDropdownDelegate.getPopupBackground(isIncognito)); - } - - @Override - public void setAdapter(Adapter adapter) { - mAdapter = (OmniboxSuggestionsRecyclerViewAdapter) adapter; - super.setAdapter(mAdapter); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - getRecycledViewPool().clear(); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - try (TraceEvent tracing = TraceEvent.scoped("OmniboxSuggestionsList.Measure"); - SuggestionsMetrics.TimingMetric metric = - SuggestionsMetrics.recordSuggestionListMeasureTime()) { - mDropdownDelegate.calculateOnMeasureAndTriggerUpdates(mTempMeasureSpecs); - super.onMeasure(mTempMeasureSpecs[0], mTempMeasureSpecs[1]); - } - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - try (TraceEvent tracing = TraceEvent.scoped("OmniboxSuggestionsList.Layout"); - SuggestionsMetrics.TimingMetric metric = - SuggestionsMetrics.recordSuggestionListLayoutTime()) { - super.onLayout(changed, l, t, r, b); - } - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (!isShown()) return false; - - int selectedPosition = mAdapter.getSelectedViewIndex(); - if (KeyNavigationUtil.isGoDown(event)) { - return mAdapter.setSelectedViewIndex(selectedPosition + 1); - } else if (KeyNavigationUtil.isGoUp(event)) { - return mAdapter.setSelectedViewIndex(selectedPosition - 1); - } else if (KeyNavigationUtil.isGoRight(event) || KeyNavigationUtil.isGoLeft(event)) { - View selectedView = mAdapter.getSelectedView(); - if (selectedView != null) return selectedView.onKeyDown(keyCode, event); - } else if (KeyNavigationUtil.isEnter(event)) { - View selectedView = mAdapter.getSelectedView(); - if (selectedView != null) return selectedView.performClick(); - } - return super.onKeyDown(keyCode, event); - } - - @Override - public boolean onGenericMotionEvent(MotionEvent event) { - return mDropdownDelegate.shouldIgnoreGenericMotionEvent(event) - || super.onGenericMotionEvent(event); - } - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - final int eventType = ev.getActionMasked(); - if ((eventType == MotionEvent.ACTION_UP || eventType == MotionEvent.ACTION_DOWN) - && mObserver != null) { - mObserver.onGesture(eventType == MotionEvent.ACTION_UP, ev.getEventTime()); - } - return super.dispatchTouchEvent(ev); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/GoogleServicesSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/GoogleServicesSettings.java index b1fda6d..a9230a8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/GoogleServicesSettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/GoogleServicesSettings.java
@@ -71,6 +71,8 @@ @VisibleForTesting public static final String PREF_AUTOFILL_ASSISTANT = "autofill_assistant"; @VisibleForTesting + public static final String PREF_AUTOFILL_ASSISTANT_SUBSECTION = "autofill_assistant_subsection"; + @VisibleForTesting public static final String PREF_METRICS_SETTINGS = "metrics_settings"; private final PrefService mPrefService = UserPrefs.get(Profile.getLastUsedRegularProfile()); @@ -159,7 +161,12 @@ mUrlKeyedAnonymizedData.setManagedPreferenceDelegate(mManagedPreferenceDelegate); mAutofillAssistant = (ChromeSwitchPreference) findPreference(PREF_AUTOFILL_ASSISTANT); - if (shouldShowAutofillAssistantPreference()) { + Preference autofillAssistantSubsection = findPreference(PREF_AUTOFILL_ASSISTANT_SUBSECTION); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP)) { + removePreference(getPreferenceScreen(), mAutofillAssistant); + mAutofillAssistant = null; + autofillAssistantSubsection.setVisible(true); + } else if (shouldShowAutofillAssistantPreference()) { mAutofillAssistant.setOnPreferenceChangeListener(this); mAutofillAssistant.setManagedPreferenceDelegate(mManagedPreferenceDelegate); } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncAndServicesSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncAndServicesSettings.java index e293166..db300e37 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncAndServicesSettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncAndServicesSettings.java
@@ -116,6 +116,8 @@ @VisibleForTesting public static final String PREF_AUTOFILL_ASSISTANT = "autofill_assistant"; @VisibleForTesting + public static final String PREF_AUTOFILL_ASSISTANT_SUBSECTION = "autofill_assistant_subsection"; + @VisibleForTesting public static final String PREF_METRICS_SETTINGS = "metrics_settings"; private static final int REQUEST_CODE_TRUSTED_VAULT_KEY_RETRIEVAL = 1; @@ -258,7 +260,12 @@ mUrlKeyedAnonymizedData.setManagedPreferenceDelegate(mManagedPreferenceDelegate); mAutofillAssistant = (ChromeSwitchPreference) findPreference(PREF_AUTOFILL_ASSISTANT); - if (shouldShowAutofillAssistantPreference()) { + Preference autofillAssistantSubsection = findPreference(PREF_AUTOFILL_ASSISTANT_SUBSECTION); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP)) { + removePreference(servicesCategory, mAutofillAssistant); + mAutofillAssistant = null; + autofillAssistantSubsection.setVisible(true); + } else if (shouldShowAutofillAssistantPreference()) { mAutofillAssistant.setOnPreferenceChangeListener(this); mAutofillAssistant.setManagedPreferenceDelegate(mManagedPreferenceDelegate); } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java index 6b709f8..bf9a2b829 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -25,7 +25,7 @@ import org.chromium.chrome.browser.bookmarks.BookmarkBridge; import org.chromium.chrome.browser.browser_controls.BrowserControlsSizer; import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; import org.chromium.chrome.browser.datareduction.DataReductionPromoScreen; @@ -86,7 +86,7 @@ private HistoryNavigationCoordinator mHistoryNavigationCoordinator; private NavigationSheet mNavigationSheet; private ComposedBrowserControlsVisibilityDelegate mAppBrowserControlsVisibilityDelegate; - private LayoutManager mLayoutManager; + private LayoutManagerImpl mLayoutManager; /** * Construct a new TabbedRootUiCoordinator. @@ -257,7 +257,7 @@ // Protected class methods @Override - protected void onLayoutManagerAvailable(LayoutManager layoutManager) { + protected void onLayoutManagerAvailable(LayoutManagerImpl layoutManager) { super.onLayoutManagerAvailable(layoutManager); initStatusIndicatorCoordinator(layoutManager); @@ -340,7 +340,7 @@ mActivity.getWindowAndroid(), mAppBannerInProductHelpController); } - private void initStatusIndicatorCoordinator(LayoutManager layoutManager) { + private void initStatusIndicatorCoordinator(LayoutManagerImpl layoutManager) { // TODO(crbug.com/1035584): Disable on tablets for now as we need to do one or two extra // things for tablets. if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index d24a0e7..8aa9c228 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -44,7 +44,7 @@ import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.Invalidator; import org.chromium.chrome.browser.compositor.layouts.Layout; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbar; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; @@ -171,7 +171,7 @@ private LocationBar mLocationBar; private FindToolbarManager mFindToolbarManager; - private LayoutManager mLayoutManager; + private LayoutManagerImpl mLayoutManager; private final ObservableSupplier<ShareDelegate> mShareDelegateSupplier; private TabObserver mTabObserver; @@ -758,7 +758,7 @@ startSurfaceSupplier, () -> { NewTabPage ntp = getNewTabPageForCurrentTab(); if (ntp != null) mLocationBar.onTabLoadingNTP(ntp); - }); + }, () -> mLayoutManager.getResourceManager()); // clang-format on mHomepageStateListener = () -> { mHomeButtonVisibilitySupplier.set(HomepageManager.isHomepageEnabled()); @@ -945,7 +945,7 @@ * <p> * Calling this must occur after the native library have completely loaded. * - * @param layoutManager A {@link LayoutManager} instance used to watch for scene + * @param layoutManager A {@link LayoutManagerImpl} instance used to watch for scene * changes. * @param tabSwitcherClickHandler The {@link OnClickListener} for the tab switcher button. * @param newTabClickHandler The {@link OnClickListener} for the new tab button. @@ -954,7 +954,7 @@ * button. * @param showStartSurfaceSupplier Supplies if we should show the start surface. */ - public void initializeWithNative(LayoutManager layoutManager, + public void initializeWithNative(LayoutManagerImpl layoutManager, OnClickListener tabSwitcherClickHandler, OnClickListener newTabClickHandler, OnClickListener bookmarkClickHandler, OnClickListener customTabsBackClickHandler, Supplier<Boolean> showStartSurfaceSupplier) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java index d931d5d..84f339bb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java
@@ -19,7 +19,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.browser_controls.BrowserControlsSizer; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.fullscreen.FullscreenManager; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider; @@ -120,7 +120,7 @@ * Calling this must occur after the native library have completely loaded. * @param activity Activity instance to use. * @param resourceManager A {@link ResourceManager} for loading textures into the compositor. - * @param layoutManager A {@link LayoutManager} to attach overlays to. + * @param layoutManager A {@link LayoutManagerImpl} to attach overlays to. * @param tabSwitcherListener An {@link OnClickListener} that is triggered when the * bottom toolbar's tab switcher button is clicked. * @param newTabClickListener An {@link OnClickListener} that is triggered when the @@ -133,7 +133,7 @@ * @param closeAllTabsAction The runnable that closes all tabs in the current tab model. */ public void initializeWithNative(Activity activity, ResourceManager resourceManager, - LayoutManager layoutManager, OnClickListener tabSwitcherListener, + LayoutManagerImpl layoutManager, OnClickListener tabSwitcherListener, OnClickListener newTabClickListener, WindowAndroid windowAndroid, TabCountProvider tabCountProvider, IncognitoStateProvider incognitoStateProvider, ViewGroup topToolbarRoot, Runnable closeAllTabsAction) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsMediator.java index 2544306..e052af5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsMediator.java
@@ -8,7 +8,7 @@ import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager; import org.chromium.chrome.browser.compositor.layouts.Layout; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; import org.chromium.chrome.browser.compositor.layouts.ToolbarSwipeLayout; import org.chromium.chrome.browser.fullscreen.FullscreenManager; @@ -86,7 +86,7 @@ mWindowAndroid.getKeyboardDelegate().addKeyboardVisibilityListener(this); } - void setLayoutManager(LayoutManager layoutManager) { + void setLayoutManager(LayoutManagerImpl layoutManager) { mModel.set(BottomControlsProperties.LAYOUT_MANAGER, layoutManager); layoutManager.addSceneChangeObserver(this); layoutManager.getOverlayPanelManager().addObserver(this); @@ -108,7 +108,7 @@ mWindowAndroid = null; } if (mModel.get(BottomControlsProperties.LAYOUT_MANAGER) != null) { - LayoutManager manager = mModel.get(BottomControlsProperties.LAYOUT_MANAGER); + LayoutManagerImpl manager = mModel.get(BottomControlsProperties.LAYOUT_MANAGER); manager.getOverlayPanelManager().removeObserver(this); manager.removeSceneChangeObserver(this); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsProperties.java index 38498fc..8193cfb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsProperties.java
@@ -4,7 +4,7 @@ package org.chromium.chrome.browser.toolbar.bottom; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableIntPropertyKey; @@ -26,8 +26,8 @@ static final WritableBooleanPropertyKey COMPOSITED_VIEW_VISIBLE = new WritableBooleanPropertyKey(); - /** A {@link LayoutManager} to attach overlays to. */ - static final WritableObjectPropertyKey<LayoutManager> LAYOUT_MANAGER = + /** A {@link LayoutManagerImpl} to attach overlays to. */ + static final WritableObjectPropertyKey<LayoutManagerImpl> LAYOUT_MANAGER = new WritableObjectPropertyKey<>(); /** A {@link ResourceManager} for loading textures into the compositor. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java index 09fd4a7..2720311 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -22,10 +22,10 @@ import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.compositor.Invalidator; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; import org.chromium.chrome.browser.compositor.overlays.toolbar.TopToolbarOverlayCoordinator; import org.chromium.chrome.browser.device.DeviceClassManager; import org.chromium.chrome.browser.findinpage.FindToolbar; +import org.chromium.chrome.browser.layouts.LayoutManager; import org.chromium.chrome.browser.layouts.LayoutStateProvider; import org.chromium.chrome.browser.omnibox.LocationBar; import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider; @@ -45,6 +45,7 @@ import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; import org.chromium.chrome.features.start_surface.StartSurfaceState; import org.chromium.components.browser_ui.widget.ClipDrawableProgressBar; +import org.chromium.ui.resources.ResourceManager; import java.util.List; @@ -91,6 +92,7 @@ private Callback<ClipDrawableProgressBar.DrawingInfo> mProgressDrawInfoCallback; private ToolbarControlContainer mControlContainer; + private Supplier<ResourceManager> mResourceManagerSupplier; /** * Creates a new {@link TopToolbarCoordinator}. @@ -110,6 +112,7 @@ * for the {@link Invalidator} a chance to defer the actual invalidate to sync drawing. * @param identityDiscButtonSupplier Supplier of Identity Disc button. * @param startSurfaceSupplier Supplier of the StartSurface. + * @param resourceManagerSupplier A supplier of a resource manager for native textures. */ public TopToolbarCoordinator(ToolbarControlContainer controlContainer, ToolbarLayout toolbarLayout, ToolbarDataProvider toolbarDataProvider, @@ -125,12 +128,14 @@ ObservableSupplier<Boolean> homeButtonVisibilitySupplier, ObservableSupplier<Boolean> identityDiscStateSupplier, Callback<Runnable> invalidatorCallback, Supplier<ButtonData> identityDiscButtonSupplier, - OneshotSupplier<StartSurface> startSurfaceSupplier, Runnable tabOrModelChangeRunnable) { + OneshotSupplier<StartSurface> startSurfaceSupplier, Runnable tabOrModelChangeRunnable, + Supplier<ResourceManager> resourceManagerSupplier) { mControlContainer = controlContainer; mToolbarLayout = toolbarLayout; mMenuButtonCoordinator = browsingModeMenuButtonCoordinator; mOptionalButtonController = new OptionalBrowsingModeButtonController(buttonDataProviders, userEducationHelper, mToolbarLayout, () -> toolbarDataProvider.getTab()); + mResourceManagerSupplier = resourceManagerSupplier; mProgressDrawInfoCallback = (info) -> { if (controlContainer == null) return; controlContainer.getProgressBarDrawingInfo(info); @@ -217,9 +222,9 @@ // If fullscreen is disabled, don't bother creating this overlay; only the android view will // ever be shown. if (DeviceClassManager.enableFullscreen()) { - mOverlayCoordinator = - new TopToolbarOverlayCoordinator(mToolbarLayout.getContext(), layoutManager, - mProgressDrawInfoCallback, tabProvider, browserControlsStateProvider); + mOverlayCoordinator = new TopToolbarOverlayCoordinator(mToolbarLayout.getContext(), + layoutManager, mProgressDrawInfoCallback, tabProvider, + browserControlsStateProvider, mResourceManagerSupplier); layoutManager.addSceneOverlay(mOverlayCoordinator); mToolbarLayout.setOverlayCoordinator(mOverlayCoordinator); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java index 6773b42..e7860fa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -33,7 +33,7 @@ import org.chromium.chrome.browser.bookmarks.BookmarkBridge; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; import org.chromium.chrome.browser.crash.PureJavaExceptionReporter; import org.chromium.chrome.browser.directactions.DirectActionInitializer; @@ -122,7 +122,7 @@ protected @Nullable FindToolbarManager mFindToolbarManager; private @Nullable FindToolbarObserver mFindToolbarObserver; - private Callback<LayoutManager> mLayoutManagerSupplierCallback; + private Callback<LayoutManagerImpl> mLayoutManagerSupplierCallback; private OverlayPanelManager mOverlayPanelManager; private OverlayPanelManager.OverlayPanelManagerObserver mOverlayPanelManagerObserver; @@ -168,7 +168,7 @@ private MessageContainerCoordinator mMessageContainerCoordinator; @Nullable private ChromeMessageQueueMediator mMessageQueueMediator; - private LayoutManager mLayoutManager; + private LayoutManagerImpl mLayoutManager; protected OneshotSupplier<IntentMetadata> mIntentMetadataOneshotSupplier; // This supplier only ever updated when feature TOOLBAR_IPH_ANDROID is enabled. protected OneshotSupplierImpl<Boolean> mPromoShownOneshotSupplier = new OneshotSupplierImpl<>(); @@ -520,7 +520,7 @@ } // Protected class methods - protected void onLayoutManagerAvailable(LayoutManager layoutManager) { + protected void onLayoutManagerAvailable(LayoutManagerImpl layoutManager) { mLayoutManager = layoutManager; if (mOverlayPanelManager != null) { mOverlayPanelManager.removeObserver(mOverlayPanelManagerObserver);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java index 491c186c..160a00b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java
@@ -23,7 +23,7 @@ import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.UrlUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; import org.chromium.chrome.browser.flags.ChromeSwitches; @@ -123,7 +123,7 @@ }); CriteriaHelper.pollUiThread(() -> { - LayoutManager driver = mActivityTestRule.getActivity().getLayoutManager(); + LayoutManagerImpl driver = mActivityTestRule.getActivity().getLayoutManager(); return !driver.getActiveLayout().shouldDisplayContentOverlay(); }, "Layout still requesting Tab Android view be attached"); @@ -135,7 +135,7 @@ PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> edgeSwipeHandler.swipeFinished()); CriteriaHelper.pollUiThread(() -> { - LayoutManager driver = mActivityTestRule.getActivity().getLayoutManager(); + LayoutManagerImpl driver = mActivityTestRule.getActivity().getLayoutManager(); return driver.getActiveLayout().shouldDisplayContentOverlay(); }, "Layout not requesting Tab Android view be attached");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java index eef6b04..7a05757 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -47,9 +47,9 @@ import org.chromium.base.test.util.UrlUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.layouts.Layout; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromePhone; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; import org.chromium.chrome.browser.compositor.layouts.StaticLayout; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; @@ -1611,7 +1611,7 @@ }); CriteriaHelper.pollUiThread(() -> { - LayoutManager driver = mActivityTestRule.getActivity().getLayoutManager(); + LayoutManagerImpl driver = mActivityTestRule.getActivity().getLayoutManager(); return driver.getActiveLayout().shouldDisplayContentOverlay(); }, "Layout not requesting Tab Android view be attached");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillUpstreamTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillUpstreamTest.java index 3a52540..51715de7 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillUpstreamTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillUpstreamTest.java
@@ -72,6 +72,11 @@ Assert.assertEquals(buttonLabel, primaryButton.getText().toString()); } + private boolean isFooterShown() { + InfoBarLayout view = (InfoBarLayout) getAutofillSaveCardInfoBar().getView(); + return view.hasFooter(); + } + private void waitForSaveCardInfoBar() { CriteriaHelper.pollUiThread( () @@ -222,4 +227,68 @@ // Verify that dialog is not null Assert.assertNotNull(fixflowPromptPropertyModel); } + + @Test + @MediumTest + @Restriction(Restriction.RESTRICTION_TYPE_INTERNET) + public void testSaveCardInfoBar_syncedUser_noAccountIndicationFooter() throws TimeoutException { + mActivityTestRule.loadUrl(mServer.getURL(TEST_FORM_URL)); + final WebContents webContents = mActivityTestRule.getActivity().getCurrentWebContents(); + mActivityTestRule.setUpAccountAndEnableSyncForTesting(); + + DOMUtils.clickNode(webContents, "fill_form"); + DOMUtils.clickNode(webContents, "submit"); + waitForSaveCardInfoBar(); + + Assert.assertFalse(isFooterShown()); + } + + @Test + @MediumTest + @Restriction(Restriction.RESTRICTION_TYPE_INTERNET) + public void testSaveCardInfoBar_loggedInUnsyncedUser_showsAccountIndicationFooter() + throws TimeoutException { + mActivityTestRule.loadUrl(mServer.getURL(TEST_FORM_URL)); + final WebContents webContents = mActivityTestRule.getActivity().getCurrentWebContents(); + mActivityTestRule.setUpTestAccountAndSignInWithSyncSetupAsIncomplete(); + + DOMUtils.clickNode(webContents, "fill_form"); + DOMUtils.clickNode(webContents, "submit"); + waitForSaveCardInfoBar(); + + Assert.assertTrue(isFooterShown()); + } + + @Test + @MediumTest + @Restriction(Restriction.RESTRICTION_TYPE_INTERNET) + public void testSaveCardInfoBar_singleAccountUser_noAccountIndicationFooter() + throws TimeoutException { + mActivityTestRule.loadUrl(mServer.getURL(TEST_FORM_URL)); + final WebContents webContents = mActivityTestRule.getActivity().getCurrentWebContents(); + mActivityTestRule.addAccount("account1"); + + DOMUtils.clickNode(webContents, "fill_form"); + DOMUtils.clickNode(webContents, "submit"); + waitForSaveCardInfoBar(); + + Assert.assertFalse(isFooterShown()); + } + + @Test + @MediumTest + @Restriction(Restriction.RESTRICTION_TYPE_INTERNET) + public void testSaveCardInfoBar_multipleAccountUser_showsAccountIndicationFooter() + throws TimeoutException { + mActivityTestRule.loadUrl(mServer.getURL(TEST_FORM_URL)); + final WebContents webContents = mActivityTestRule.getActivity().getCurrentWebContents(); + mActivityTestRule.addAccount("account1"); + mActivityTestRule.addAccount("account2"); + + DOMUtils.clickNode(webContents, "fill_form"); + DOMUtils.clickNode(webContents, "submit"); + waitForSaveCardInfoBar(); + + Assert.assertTrue(isFooterShown()); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferenceFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferenceFragmentTest.java new file mode 100644 index 0000000..4c2908a --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferenceFragmentTest.java
@@ -0,0 +1,190 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.autofill_assistant; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import androidx.preference.Preference; +import androidx.test.filters.LargeTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; +import org.chromium.chrome.browser.settings.SettingsActivityTestRule; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.util.browser.Features.DisableFeatures; +import org.chromium.chrome.test.util.browser.Features.EnableFeatures; +import org.chromium.components.browser_ui.settings.ChromeSwitchPreference; +import org.chromium.content_public.browser.test.util.TestThreadUtils; + +/** + * Tests for AutofillAssistantPreferenceFragment. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +public class AutofillAssistantPreferenceFragmentTest { + private final SettingsActivityTestRule<AutofillAssistantPreferenceFragment> + mSettingsActivityTestRule = + new SettingsActivityTestRule<>(AutofillAssistantPreferenceFragment.class); + + private final SharedPreferencesManager mSharedPreferencesManager = + SharedPreferencesManager.getInstance(); + + /** + * Test: if the onboarding was never shown or it was shown and not accepted, the AA chrome + * preference should not exist. + * + * Note: the presence of the {@link AutofillAssistantPreferenceFragment.PREF_AUTOFILL_ASSISTANT} + * shared preference indicates whether the onboarding was accepted or not. + */ + @Test + @LargeTest + @Feature({"Sync"}) + @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + public void testAutofillAssistantNoPreferenceIfOnboardingNeverShown() { + final AutofillAssistantPreferenceFragment prefs = + startAutofillAssistantPreferenceFragment(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + assertFalse(prefs.findPreference( + AutofillAssistantPreferenceFragment.PREF_AUTOFILL_ASSISTANT) + .isVisible()); + }); + } + + /** + * Test: if the onboarding was accepted, the AA chrome preference should also exist. + * + * Note: the presence of the {@link AutofillAssistantPreferenceFragment.PREF_AUTOFILL_ASSISTANT} + * shared preference indicates whether the onboarding was accepted or not. + */ + @Test + @LargeTest + @Feature({"Sync"}) + @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + public void testAutofillAssistantPreferenceShownIfOnboardingShown() { + setAutofillAssistantSwitchValue(true); + final AutofillAssistantPreferenceFragment prefs = + startAutofillAssistantPreferenceFragment(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + assertTrue(prefs.findPreference( + AutofillAssistantPreferenceFragment.PREF_AUTOFILL_ASSISTANT) + .isVisible()); + }); + } + + /** + * Ensure that the "Autofill Assistant" setting is not shown when the feature is disabled. + */ + @Test + @LargeTest + @Feature({"Sync"}) + @DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + public void testAutofillAssistantNoPreferenceIfFeatureDisabled() { + setAutofillAssistantSwitchValue(true); + final AutofillAssistantPreferenceFragment prefs = + startAutofillAssistantPreferenceFragment(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + assertFalse(prefs.findPreference( + AutofillAssistantPreferenceFragment.PREF_AUTOFILL_ASSISTANT) + .isVisible()); + }); + } + + /** + * Ensure that the "Autofill Assistant" on/off switch works. + */ + @Test + @LargeTest + @Feature({"Sync"}) + @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + public void testAutofillAssistantSwitchOn() { + TestThreadUtils.runOnUiThreadBlocking(() -> { setAutofillAssistantSwitchValue(true); }); + final AutofillAssistantPreferenceFragment prefs = + startAutofillAssistantPreferenceFragment(); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + ChromeSwitchPreference autofillAssistantSwitch = + (ChromeSwitchPreference) prefs.findPreference( + AutofillAssistantPreferenceFragment.PREF_AUTOFILL_ASSISTANT); + assertTrue(autofillAssistantSwitch.isChecked()); + + autofillAssistantSwitch.performClick(); + assertFalse(mSharedPreferencesManager.readBoolean( + ChromePreferenceKeys.AUTOFILL_ASSISTANT_ENABLED, true)); + autofillAssistantSwitch.performClick(); + assertTrue(mSharedPreferencesManager.readBoolean( + ChromePreferenceKeys.AUTOFILL_ASSISTANT_ENABLED, false)); + }); + } + + @Test + @LargeTest + @Feature({"Sync"}) + @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + public void testProactiveHelpDisabledIfMsbbDisabled() { + final AutofillAssistantPreferenceFragment prefs = + startAutofillAssistantPreferenceFragment(); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + ChromeSwitchPreference proactiveHelpSwitch = + (ChromeSwitchPreference) prefs.findPreference( + AutofillAssistantPreferenceFragment + .PREF_ASSISTANT_PROACTIVE_HELP_SWITCH); + assertFalse(proactiveHelpSwitch.isEnabled()); + + Preference syncAndServicesLink = prefs.findPreference( + AutofillAssistantPreferenceFragment.PREF_GOOGLE_SERVICES_SETTINGS_LINK); + assertNotNull(syncAndServicesLink); + }); + } + + @Test + @LargeTest + @Feature({"Sync"}) + @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + public void testProactiveHelpDisabledIfAutofillAssistantDisabled() { + TestThreadUtils.runOnUiThreadBlocking(() -> { setAutofillAssistantSwitchValue(true); }); + final AutofillAssistantPreferenceFragment prefs = + startAutofillAssistantPreferenceFragment(); + + ChromeSwitchPreference proactiveHelpSwitch = (ChromeSwitchPreference) prefs.findPreference( + AutofillAssistantPreferenceFragment.PREF_ASSISTANT_PROACTIVE_HELP_SWITCH); + Preference syncAndServicesLink = prefs.findPreference( + AutofillAssistantPreferenceFragment.PREF_GOOGLE_SERVICES_SETTINGS_LINK); + TestThreadUtils.runOnUiThreadBlocking(() -> { + assertFalse(proactiveHelpSwitch.isEnabled()); + + assertTrue(syncAndServicesLink.isVisible()); + + ChromeSwitchPreference autofillAssistantSwitch = + (ChromeSwitchPreference) prefs.findPreference( + AutofillAssistantPreferenceFragment.PREF_AUTOFILL_ASSISTANT); + autofillAssistantSwitch.performClick(); + + assertFalse(proactiveHelpSwitch.isEnabled()); + assertFalse(syncAndServicesLink.isVisible()); + }); + } + + private void setAutofillAssistantSwitchValue(boolean newValue) { + SharedPreferencesManager.getInstance().writeBoolean( + ChromePreferenceKeys.AUTOFILL_ASSISTANT_ENABLED, newValue); + } + + private AutofillAssistantPreferenceFragment startAutofillAssistantPreferenceFragment() { + mSettingsActivityTestRule.startSettingsActivity(); + return mSettingsActivityTestRule.getFragment(); + } + + public boolean isAutofillAssistantSwitchOn() { + return mSharedPreferencesManager.readBoolean( + ChromePreferenceKeys.AUTOFILL_ASSISTANT_ENABLED, false); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill_assistant/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill_assistant/OWNERS new file mode 100644 index 0000000..f488c82b --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill_assistant/OWNERS
@@ -0,0 +1,3 @@ +file://components/autofill_assistant/OWNERS + +# COMPONENT: UI>Browser>Autofill>Assistant
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManagerTest.java index d02126ec..25eea98 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManagerTest.java
@@ -21,7 +21,7 @@ import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager.OverlayPanelManagerObserver; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager.PanelPriority; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.ui.resources.dynamics.DynamicResourceLoader; @@ -45,7 +45,7 @@ private ViewGroup mContainerView; private DynamicResourceLoader mResourceLoader; - public MockOverlayPanel(Context context, LayoutManager updateHost, + public MockOverlayPanel(Context context, LayoutManagerImpl updateHost, OverlayPanelManager panelManager, @PanelPriority int priority, boolean canBeSuppressed) { super(context, updateHost, panelManager);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockContextForLayout.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockContextForLayout.java index 609847a..9c3ada86 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockContextForLayout.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockContextForLayout.java
@@ -10,9 +10,9 @@ import android.test.mock.MockResources; /** - * This is the minimal {@link Context} needed by the {@link LayoutManager} to be working properly. - * It points to a {@link MockResources} for anything that is based on xml configurations. For - * everything else the standard provided Context should be sufficient. + * This is the minimal {@link Context} needed by the {@link LayoutManagerImpl} to be working + * properly. It points to a {@link MockResources} for anything that is based on xml configurations. + * For everything else the standard provided Context should be sufficient. */ public class MockContextForLayout extends ContextWrapper { private final MockResourcesForLayout mResources;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockResourcesForLayout.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockResourcesForLayout.java index fc353b9..ae50eb4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockResourcesForLayout.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockResourcesForLayout.java
@@ -18,11 +18,10 @@ import org.chromium.chrome.R; /** - * This is the minimal {@link Resources} needed by the {@link LayoutManager} to be working properly. - * Values Come from the xml files (e.g. dimens.xml, values.xml, ...). - * All the dimension values are in dp. - * For internal structures, not based on xml configurations, a dummy {@link Resources} instance is - * provided. + * This is the minimal {@link Resources} needed by the {@link LayoutManagerImpl} to be working + * properly. Values Come from the xml files (e.g. dimens.xml, values.xml, ...). All the dimension + * values are in dp. For internal structures, not based on xml configurations, a dummy {@link + * Resources} instance is provided. */ public class MockResourcesForLayout extends MockResources { private final Resources mValidResources;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java index 0efdedf89..c8ea57f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
@@ -90,6 +90,7 @@ HashMap<String, Boolean> features = new HashMap<String, Boolean>(); features.put(ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS, false); features.put(ChromeFeatureList.EPHEMERAL_TAB_USING_BOTTOM_SHEET, false); + features.put(ChromeFeatureList.READ_LATER, false); ChromeFeatureList.setTestFeatures(features); } @@ -181,6 +182,7 @@ HashMap<String, Boolean> features = new HashMap<String, Boolean>(); features.put(ChromeFeatureList.EPHEMERAL_TAB_USING_BOTTOM_SHEET, true); + features.put(ChromeFeatureList.READ_LATER, false); ChromeFeatureList.setTestFeatures(features); initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java index 317832b7..051f511 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java
@@ -36,7 +36,7 @@ import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.download.DownloadTestRule; import org.chromium.chrome.browser.firstrun.FirstRunStatus; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -556,7 +556,7 @@ "Number of open tabs does not match", numOpenedTabs, tabModel.getCount()); // Wait for any new tab animation to finish if we're being driven by the compositor. - final LayoutManager layoutDriver = + final LayoutManagerImpl layoutDriver = mDownloadTestRule.getActivity().getCompositorViewHolder().getLayoutManager(); CriteriaHelper.pollUiThread(() -> { return layoutDriver.getActiveLayout().shouldDisplayContentOverlay();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java index 13232e0..8813b7a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java
@@ -26,7 +26,7 @@ import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager; import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManagerWrapper; import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanel; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -67,7 +67,7 @@ private ContextualSearchPanel mPanel; private OverlayPanelManagerWrapper mPanelManager; private SelectionClient mContextualSearchClient; - private LayoutManager mLayoutManager; + private LayoutManagerImpl mLayoutManager; // -------------------------------------------------------------------------------------------- @@ -75,8 +75,8 @@ * ContextualSearchPanel wrapper that prevents native calls. */ private static class ContextualSearchPanelWrapper extends ContextualSearchPanel { - public ContextualSearchPanelWrapper( - Context context, LayoutManager layoutManager, OverlayPanelManager panelManager) { + public ContextualSearchPanelWrapper(Context context, LayoutManagerImpl layoutManager, + OverlayPanelManager panelManager) { super(context, layoutManager, panelManager); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/GoogleServicesSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/GoogleServicesSettingsTest.java index cc1ca65..c556a63 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/GoogleServicesSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/GoogleServicesSettingsTest.java
@@ -137,6 +137,7 @@ @LargeTest @Feature({"Sync"}) @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + @DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP) public void testAutofillAssistantNoPreferenceIfOnboardingNeverShown() { final GoogleServicesSettings googleServicesSettings = startGoogleServicesSettings(); TestThreadUtils.runOnUiThreadBlocking(() -> { @@ -155,6 +156,7 @@ @LargeTest @Feature({"Sync"}) @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + @DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP) public void testAutofillAssistantPreferenceShownIfOnboardingShown() { setAutofillAssistantSwitchValue(true); final GoogleServicesSettings googleServicesSettings = startGoogleServicesSettings(); @@ -170,8 +172,10 @@ @Test @LargeTest @Feature({"Sync"}) - @DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) - public void testAutofillAssistantNoPreferenceIfFeatureDisabled() { + @DisableFeatures({ChromeFeatureList.AUTOFILL_ASSISTANT, + ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP}) + public void + testAutofillAssistantNoPreferenceIfFeatureDisabled() { setAutofillAssistantSwitchValue(true); final GoogleServicesSettings googleServicesSettings = startGoogleServicesSettings(); TestThreadUtils.runOnUiThreadBlocking(() -> { @@ -187,6 +191,7 @@ @LargeTest @Feature({"Sync"}) @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + @DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP) public void testAutofillAssistantSwitchOn() { TestThreadUtils.runOnUiThreadBlocking(() -> { setAutofillAssistantSwitchValue(true); }); final GoogleServicesSettings googleServicesSettings = startGoogleServicesSettings(); @@ -208,6 +213,7 @@ @LargeTest @Feature({"Sync"}) @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + @DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP) public void testAutofillAssistantSwitchOff() { TestThreadUtils.runOnUiThreadBlocking(() -> { setAutofillAssistantSwitchValue(false); }); final GoogleServicesSettings googleServicesSettings = startGoogleServicesSettings(); @@ -222,6 +228,25 @@ @Test @LargeTest + @Feature({"Sync"}) + @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP) + public void testAutofillAssistantProactiveHelp() { + final GoogleServicesSettings googleServicesSettings = startGoogleServicesSettings(); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + Assert.assertNull(googleServicesSettings.findPreference( + GoogleServicesSettings.PREF_AUTOFILL_ASSISTANT)); + + Assert.assertTrue( + googleServicesSettings + .findPreference( + GoogleServicesSettings.PREF_AUTOFILL_ASSISTANT_SUBSECTION) + .isVisible()); + }); + } + + @Test + @LargeTest @Feature({"Preference"}) @EnableFeatures(ChromeFeatureList.SAFE_BROWSING_SECTION_UI) public void testSafeBrowsingSafeBrowsingSectionUiFlagOn() { @@ -279,4 +304,4 @@ mSettingsActivityTestRule.startSettingsActivity(); return mSettingsActivityTestRule.getFragment(); } -} \ No newline at end of file +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncAndServicesSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncAndServicesSettingsTest.java index 3922b34..533fc20b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncAndServicesSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncAndServicesSettingsTest.java
@@ -257,6 +257,7 @@ @LargeTest @Feature({"Sync"}) @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + @DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP) public void testAutofillAssistantNoPreferenceIfOnboardingNeverShown() { final SyncAndServicesSettings syncPrefs = startSyncAndServicesPreferences(); TestThreadUtils.runOnUiThreadBlocking(() -> { @@ -275,6 +276,7 @@ @LargeTest @Feature({"Sync"}) @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + @DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP) public void testAutofillAssistantPreferenceShownIfOnboardingShown() { setAutofillAssistantSwitchValue(true); final SyncAndServicesSettings syncPrefs = startSyncAndServicesPreferences(); @@ -290,8 +292,10 @@ @Test @LargeTest @Feature({"Sync"}) - @DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) - public void testAutofillAssistantNoPreferenceIfFeatureDisabled() { + @DisableFeatures({ChromeFeatureList.AUTOFILL_ASSISTANT, + ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP}) + public void + testAutofillAssistantNoPreferenceIfFeatureDisabled() { setAutofillAssistantSwitchValue(true); final SyncAndServicesSettings syncPrefs = startSyncAndServicesPreferences(); TestThreadUtils.runOnUiThreadBlocking(() -> { @@ -307,6 +311,7 @@ @LargeTest @Feature({"Sync"}) @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + @DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP) public void testAutofillAssistantSwitchOn() { TestThreadUtils.runOnUiThreadBlocking(() -> { setAutofillAssistantSwitchValue(true); }); final SyncAndServicesSettings syncAndServicesSettings = startSyncAndServicesPreferences(); @@ -328,6 +333,7 @@ @LargeTest @Feature({"Sync"}) @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT) + @DisableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP) public void testAutofillAssistantSwitchOff() { TestThreadUtils.runOnUiThreadBlocking(() -> { setAutofillAssistantSwitchValue(false); }); final SyncAndServicesSettings syncAndServicesSettings = startSyncAndServicesPreferences(); @@ -342,6 +348,25 @@ @Test @LargeTest + @Feature({"Sync"}) + @EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP) + public void testAutofillAssistantProactiveHelp() { + final SyncAndServicesSettings syncAndServicesSettings = startSyncAndServicesPreferences(); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + Assert.assertNull(syncAndServicesSettings.findPreference( + SyncAndServicesSettings.PREF_AUTOFILL_ASSISTANT)); + + Assert.assertTrue( + syncAndServicesSettings + .findPreference( + SyncAndServicesSettings.PREF_AUTOFILL_ASSISTANT_SUBSECTION) + .isVisible()); + }); + } + + @Test + @LargeTest @Feature({"Preference"}) @EnableFeatures(ChromeFeatureList.SAFE_BROWSING_SECTION_UI) public void testSafeBrowsingSafeBrowsingSectionUiFlagOn() {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsConverterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsConverterTest.java index a588a0c..3821be3 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsConverterTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsConverterTest.java
@@ -116,7 +116,7 @@ convertedCallback.onExtraCallback(GetDetailsConverter.RESPONSE_COMMAND, args); - assertEquals(convertResponseCode(responseCode), state.responseCode); + assertEquals(DigitalGoodsConverter.convertResponseCodeV0(responseCode), state.responseCode); assertItemDetails(state.results[0], "1", "t1", "d1", "c1", "v1"); assertSubsItemDetails(state.results[0], null, null, null, null, null); assertItemDetails(state.results[1], "2", "t2", "d2", "c2", "v2"); @@ -269,24 +269,42 @@ convertedCallback.onExtraCallback(ListPurchasesConverter.RESPONSE_COMMAND, args); - assertEquals(convertResponseCode(responseCode), state.responseCode); + assertEquals(DigitalGoodsConverter.convertResponseCodeV0(responseCode), state.responseCode); assertPurchaseDetails(state.results[0], "1", "t1", true, 1, 1L, true); assertPurchaseDetails(state.results[1], "2", "t2", false, 2, 2L, false); } @Test public void convertResponseCodes() { - assertEquals(BillingResponseCode.OK, convertResponseCode(PLAY_BILLING_OK)); + assertEquals(BillingResponseCode.OK, + DigitalGoodsConverter.convertResponseCodeV0(PLAY_BILLING_OK)); assertEquals(BillingResponseCode.ITEM_ALREADY_OWNED, - convertResponseCode(PLAY_BILLING_ITEM_ALREADY_OWNED)); + DigitalGoodsConverter.convertResponseCodeV0(PLAY_BILLING_ITEM_ALREADY_OWNED)); assertEquals(BillingResponseCode.ITEM_NOT_OWNED, - convertResponseCode(PLAY_BILLING_ITEM_NOT_OWNED)); + DigitalGoodsConverter.convertResponseCodeV0(PLAY_BILLING_ITEM_NOT_OWNED)); assertEquals(BillingResponseCode.ITEM_UNAVAILABLE, - convertResponseCode(PLAY_BILLING_ITEM_UNAVAILABLE)); + DigitalGoodsConverter.convertResponseCodeV0(PLAY_BILLING_ITEM_UNAVAILABLE)); // Check that other numbers get set to ERROR. - assertEquals(BillingResponseCode.ERROR, convertResponseCode(2)); - assertEquals(BillingResponseCode.ERROR, convertResponseCode(-1)); - assertEquals(BillingResponseCode.ERROR, convertResponseCode(10)); + assertEquals(BillingResponseCode.ERROR, DigitalGoodsConverter.convertResponseCodeV0(2)); + assertEquals(BillingResponseCode.ERROR, DigitalGoodsConverter.convertResponseCodeV0(-1)); + assertEquals(BillingResponseCode.ERROR, DigitalGoodsConverter.convertResponseCodeV0(10)); + } + + @Test + public void convertResponseCodes_v2() { + Bundle args = new Bundle(); + args.putInt(DigitalGoodsConverter.KEY_VERSION, 1); + + assertEquals(BillingResponseCode.OK, convertResponseCode(BillingResponseCode.OK, args)); + assertEquals(BillingResponseCode.ITEM_ALREADY_OWNED, + convertResponseCode(BillingResponseCode.ITEM_ALREADY_OWNED, args)); + assertEquals(BillingResponseCode.ITEM_NOT_OWNED, + convertResponseCode(BillingResponseCode.ITEM_NOT_OWNED, args)); + assertEquals(BillingResponseCode.ITEM_UNAVAILABLE, + convertResponseCode(BillingResponseCode.ITEM_UNAVAILABLE, args)); + + assertEquals(BillingResponseCode.ERROR, convertResponseCode(123, args)); + assertEquals(BillingResponseCode.ERROR, convertResponseCode(-12, args)); } } \ No newline at end of file
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/SceneOverlayTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/SceneOverlayTest.java index 7ef94155..2bbe02b6 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/SceneOverlayTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/SceneOverlayTest.java
@@ -60,7 +60,7 @@ @Mock private OneshotSupplierImpl<LayoutStateProvider> mLayoutStateProviderOneshotSupplier; - private LayoutManager mLayoutManager; + private LayoutManagerImpl mLayoutManager; @Before public void setup() { @@ -71,7 +71,7 @@ when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics); doNothing().when(mLayoutStateProviderOneshotSupplier).set(any()); - mLayoutManager = new LayoutManager(mLayoutManagerHost, mContainerView, + mLayoutManager = new LayoutManagerImpl(mLayoutManagerHost, mContainerView, mTabContentManagerSupplier, null, mLayoutStateProviderOneshotSupplier); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayMediatorTest.java index d875eec..c8265b0 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayMediatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/toolbar/TopToolbarOverlayMediatorTest.java
@@ -23,7 +23,7 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; -import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabObserver; @@ -39,7 +39,7 @@ private Context mContext; @Mock - private LayoutManager mLayoutManager; + private LayoutManagerImpl mLayoutManager; @Mock private BrowserControlsStateProvider mBrowserControlsProvider;
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index f7169ba0..aaf355c3 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -2250,6 +2250,24 @@ <message name="IDS_SETTINGS_INTERNET_LOOKING_FOR_MOBILE_NETWORK" desc="Text shown when viewing the Mobile data page when there are no cellular or tether networks available."> Looking for a mobile network. <ph name="BEGIN_LINK"><a target="_blank" href="$1"></ph>Learn more<ph name="END_LINK"></a></ph> </message> + <message name="IDS_SETTINGS_INTERNET_ESIM_LABEL" desc="Label describing list of cellular networks as eSIM networks"> + eSIM + </message> + <message name="IDS_SETTINGS_INTERNET_PSIM_LABEL" desc="Label on Mobile data page describing list of cellular networks as SIM networks"> + SIM + </message> + <message name="IDS_SETTINGS_INTERNET_TETHER_LABEL" desc="Label on Mobile data page describing list of networks as instant tether networks"> + Instant Tethering + </message> + <message name="IDS_SETTINGS_INTERNET_ESIM_NOT_SETUP_WITH_SETUP_LINK" desc="Text shown when viewing the Mobile data page and no eSIM profile is available"> + No available eSIM profiles. Download a new profile <ph name="BEGIN_LINK"><a href="#" id="cellularEsimLink"></ph>here<ph name="END_LINK"></a></ph> + </message> + <message name="IDS_SETTINGS_INTERNET_PSIM_NOT_SETUP_WITH_SETUP_LINK" desc="Text shown when viewing the Mobile data page and no physical SIM profile is available"> + No available SIM profiles. Setup a new profile <ph name="BEGIN_LINK"><a href="#" id="cellularPsimLink"></ph>here.<ph name="END_LINK"></a></ph> + </message> + <message name="IDS_SETTINGS_INTERNET_TETHER_NOT_SETUP_WITH_LEARN_MORE_LINK" desc="Text shown when viewing the Mobile data page and no instant tether network is available"> + No device detected <ph name="BEGIN_LINK"><a target="_blank" href="$1"></ph>Learn more<ph name="END_LINK"></a></ph> + </message> <!-- Users Page (OS Settings) --> <message name="IDS_SETTINGS_USERS_MODIFIED_BY_OWNER_LABEL" desc="Label saying settings may only be modified by the device owner.">
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_ESIM_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_ESIM_LABEL.png.sha1 new file mode 100644 index 0000000..189cebbe --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_ESIM_LABEL.png.sha1
@@ -0,0 +1 @@ +0e3ce9ab2ed4e17f44de3ba13de3b0038b8f98aa \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_ESIM_NOT_SETUP_WITH_SETUP_LINK.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_ESIM_NOT_SETUP_WITH_SETUP_LINK.png.sha1 new file mode 100644 index 0000000..189cebbe --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_ESIM_NOT_SETUP_WITH_SETUP_LINK.png.sha1
@@ -0,0 +1 @@ +0e3ce9ab2ed4e17f44de3ba13de3b0038b8f98aa \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_PSIM_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_PSIM_LABEL.png.sha1 new file mode 100644 index 0000000..7ccc482 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_PSIM_LABEL.png.sha1
@@ -0,0 +1 @@ +1e1d204443b5b987758569e73f021bc785099902 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_PSIM_NOT_SETUP_WITH_SETUP_LINK.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_PSIM_NOT_SETUP_WITH_SETUP_LINK.png.sha1 new file mode 100644 index 0000000..7ccc482 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_PSIM_NOT_SETUP_WITH_SETUP_LINK.png.sha1
@@ -0,0 +1 @@ +1e1d204443b5b987758569e73f021bc785099902 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_TETHER_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_TETHER_LABEL.png.sha1 new file mode 100644 index 0000000..25fd25b --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_TETHER_LABEL.png.sha1
@@ -0,0 +1 @@ +7e4fad1097250fe446a5f1235e6904bfd92cc7a0 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_TETHER_NOT_SETUP_WITH_LEARN_MORE_LINK.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_TETHER_NOT_SETUP_WITH_LEARN_MORE_LINK.png.sha1 new file mode 100644 index 0000000..25fd25b --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_TETHER_NOT_SETUP_WITH_LEARN_MORE_LINK.png.sha1
@@ -0,0 +1 @@ +7e4fad1097250fe446a5f1235e6904bfd92cc7a0 \ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 6c0ce6c..e606afc 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -1965,21 +1965,6 @@ <message name="IDS_SETTINGS_SITE_SETTINGS_SOUND_BLOCKED_EXCEPTIONS" desc="Label for the blocked exceptions site list of the sound content setting."> Not allowed to play sound </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_DESCRIPTION" desc="Description of the unsandboxed plugins content setting."> - Sites usually use plugins for features like streaming videos or installing apps - </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ALLOWED" desc="Label for the enabled option of the unsandboxed plugins content setting."> - Sites can ask to use a plugin to access your computer (recommended) - </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_BLOCKED" desc="Label for the disabled option of the unsandboxed plugins content setting."> - Block plugins from accessing your computer - </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ALLOWED_EXCEPTIONS" desc="Label for the allowed exceptions site list of the unsandboxed plugins content setting."> - Allowed to use a plugin to access your computer - </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_BLOCKED_EXCEPTIONS" desc="Label for the blocked exceptions site list of the unsandboxed plugins content setting."> - Not allowed to use a plugin to access your computer - </message> <message name="IDS_SETTINGS_SITE_SETTINGS_USB_DESCRIPTION" desc="Description of the USB devices content setting."> Sites usually connect to USB devices for features like printing a document or saving to a storage device </message> @@ -2201,9 +2186,6 @@ <message name="IDS_SETTINGS_SITE_SETTINGS_RECENT_ACTIVITY" desc="Label for the section which contains the user's recent permissions changes"> Recent activity </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS" desc="Label for the unsandboxed plugin access site settings."> - Unsandboxed plugin access - </message> <message name="IDS_SETTINGS_SITE_SETTINGS_MIDI_DEVICES" desc="Label for the MIDI devices in site settings."> MIDI devices </message> @@ -2405,15 +2387,6 @@ <message name="IDS_SETTINGS_SITE_SETTINGS_AUTOMATIC_DOWNLOAD_BLOCK" desc="The block label for automatic download in site settings."> Do not allow any site to download multiple files automatically </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ASK" desc="The allow label for unsandboxed plugins in site settings."> - Ask when a site wants to use a plugin to access your computer - </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ASK_RECOMMENDED" desc="The allow label for unsandboxed plugins in site settings (with the 'recommended' suffix)."> - Ask when a site wants to use a plugin to access your computer (recommended) - </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_BLOCK" desc="The block label for unsandboxed plugins in site settings."> - Do not allow any site to use a plugin to access your computer - </message> <message name="IDS_SETTINGS_SITE_SETTINGS_WINDOW_PLACEMENT" desc="Label for the window placement site settings."> Window placement </message>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ALLOWED.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ALLOWED.png.sha1 deleted file mode 100644 index 432007b7..0000000 --- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ALLOWED.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -c0a918e270c8576e5fbe475d73922aa7149c519a \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ALLOWED_EXCEPTIONS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ALLOWED_EXCEPTIONS.png.sha1 deleted file mode 100644 index a4f10a70..0000000 --- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ALLOWED_EXCEPTIONS.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -96f5ed39dbbb0e92de31fc015b52cdc9342b3a7d \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_BLOCKED.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_BLOCKED.png.sha1 deleted file mode 100644 index 432007b7..0000000 --- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_BLOCKED.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -c0a918e270c8576e5fbe475d73922aa7149c519a \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_BLOCKED_EXCEPTIONS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_BLOCKED_EXCEPTIONS.png.sha1 deleted file mode 100644 index a4f10a70..0000000 --- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_BLOCKED_EXCEPTIONS.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -96f5ed39dbbb0e92de31fc015b52cdc9342b3a7d \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_DESCRIPTION.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_DESCRIPTION.png.sha1 deleted file mode 100644 index 432007b7..0000000 --- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_DESCRIPTION.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -c0a918e270c8576e5fbe475d73922aa7149c519a \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index eacd8a5..be1f230 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1131,6 +1131,8 @@ "permissions/permission_decision_auto_blocker_factory.h", "permissions/permission_manager_factory.cc", "permissions/permission_manager_factory.h", + "permissions/pref_notification_permission_ui_selector.cc", + "permissions/pref_notification_permission_ui_selector.h", "permissions/quiet_notification_permission_ui_config.cc", "permissions/quiet_notification_permission_ui_config.h", "permissions/quiet_notification_permission_ui_state.cc", @@ -5191,13 +5193,6 @@ } } - if (use_x11) { - sources += [ - "password_manager/password_store_x.cc", - "password_manager/password_store_x.h", - ] - } - if (use_x11 || use_ozone) { sources += [ "chrome_browser_main_extra_parts_ozone.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 9b739f46..832c6bc2 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -5158,6 +5158,12 @@ flag_descriptions::kAutofillAssistantDirectActionsDescription, kOsAndroid, FEATURE_VALUE_TYPE( autofill_assistant::features::kAutofillAssistantDirectActions)}, + + {"autofill-assistant-proactive-help", + flag_descriptions::kAutofillAssistantProactiveHelpName, + flag_descriptions::kAutofillAssistantProactiveHelpDescription, kOsAndroid, + FEATURE_VALUE_TYPE( + autofill_assistant::features::kAutofillAssistantProactiveHelp)}, #endif // defined(OS_ANDROID) #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_CHROMEOS) @@ -6659,6 +6665,17 @@ FEATURE_WITH_PARAMS_VALUE_TYPE(blink::features::kCheckOfflineCapability, kCheckOfflineCapabilityVariations, "CheckOfflineCapability")}, +#if defined(OS_ANDROID) + {"enable-autofill-save-card-info-bar-account-indication-footer", + flag_descriptions:: + kEnableAutofillSaveCardInfoBarAccountIndicationFooterName, + flag_descriptions:: + kEnableAutofillSaveCardInfoBarAccountIndicationFooterDescription, + kOsAndroid, + FEATURE_VALUE_TYPE( + autofill::features:: + kAutofillEnableSaveCardInfoBarAccountIndicationFooter)}, +#endif // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag
diff --git a/chrome/browser/apps/app_service/extension_apps_base.cc b/chrome/browser/apps/app_service/extension_apps_base.cc index e07aecf..dc1f0005 100644 --- a/chrome/browser/apps/app_service/extension_apps_base.cc +++ b/chrome/browser/apps/app_service/extension_apps_base.cc
@@ -724,8 +724,7 @@ void ExtensionAppsBase::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { // If content_type is not one of the supported permissions, do nothing. if (!base::Contains(kSupportedPermissionTypes, content_type)) { return;
diff --git a/chrome/browser/apps/app_service/extension_apps_base.h b/chrome/browser/apps/app_service/extension_apps_base.h index 5403139..c7d3f78 100644 --- a/chrome/browser/apps/app_service/extension_apps_base.h +++ b/chrome/browser/apps/app_service/extension_apps_base.h
@@ -154,8 +154,7 @@ // content_settings::Observer overrides. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // extensions::ExtensionPrefsObserver overrides. void OnExtensionLastLaunchTimeChanged(
diff --git a/chrome/browser/apps/app_service/web_apps_base.cc b/chrome/browser/apps/app_service/web_apps_base.cc index 6a24dd9..54cf528 100644 --- a/chrome/browser/apps/app_service/web_apps_base.cc +++ b/chrome/browser/apps/app_service/web_apps_base.cc
@@ -399,8 +399,7 @@ void WebAppsBase::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { // If content_type is not one of the supported permissions, do nothing. if (!base::Contains(kSupportedPermissionTypes, content_type)) { return;
diff --git a/chrome/browser/apps/app_service/web_apps_base.h b/chrome/browser/apps/app_service/web_apps_base.h index bad740a..0002a3c 100644 --- a/chrome/browser/apps/app_service/web_apps_base.h +++ b/chrome/browser/apps/app_service/web_apps_base.h
@@ -125,8 +125,7 @@ // content_settings::Observer overrides. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // web_app::AppRegistrarObserver: void OnWebAppInstalled(const web_app::AppId& app_id) override;
diff --git a/chrome/browser/apps/platform_apps/shortcut_manager.cc b/chrome/browser/apps/platform_apps/shortcut_manager.cc index da83ec2..5e8ebfe 100644 --- a/chrome/browser/apps/platform_apps/shortcut_manager.cc +++ b/chrome/browser/apps/platform_apps/shortcut_manager.cc
@@ -89,8 +89,7 @@ registry->RegisterStringPref(prefs::kAppShortcutsArch, ""); } -AppShortcutManager::AppShortcutManager(Profile* profile) - : profile_(profile), is_profile_attributes_storage_observer_(false) { +AppShortcutManager::AppShortcutManager(Profile* profile) : profile_(profile) { // Use of g_browser_process requires that we are either on the UI thread, or // there are no threads initialized (such as in unit tests). DCHECK(!content::BrowserThread::IsThreadInitialized( @@ -109,19 +108,12 @@ ProfileManager* profile_manager = g_browser_process->profile_manager(); // profile_manager might be NULL in testing environments. if (profile_manager) { - profile_manager->GetProfileAttributesStorage().AddObserver(this); - is_profile_attributes_storage_observer_ = true; + profile_storage_observer_.Add( + &profile_manager->GetProfileAttributesStorage()); } } -AppShortcutManager::~AppShortcutManager() { - if (g_browser_process && is_profile_attributes_storage_observer_) { - ProfileManager* profile_manager = g_browser_process->profile_manager(); - // profile_manager might be NULL in testing environments or during shutdown. - if (profile_manager) - profile_manager->GetProfileAttributesStorage().RemoveObserver(this); - } -} +AppShortcutManager::~AppShortcutManager() = default; void AppShortcutManager::OnExtensionWillBeInstalled( content::BrowserContext* browser_context,
diff --git a/chrome/browser/apps/platform_apps/shortcut_manager.h b/chrome/browser/apps/platform_apps/shortcut_manager.h index 2f408e5..be7bc85 100644 --- a/chrome/browser/apps/platform_apps/shortcut_manager.h +++ b/chrome/browser/apps/platform_apps/shortcut_manager.h
@@ -59,8 +59,8 @@ void DeleteApplicationShortcuts(const extensions::Extension* extension); Profile* profile_; - bool is_profile_attributes_storage_observer_; - + ScopedObserver<ProfileAttributesStorage, ProfileAttributesStorage::Observer> + profile_storage_observer_{this}; ScopedObserver<extensions::ExtensionRegistry, extensions::ExtensionRegistryObserver> extension_registry_observer_{this};
diff --git a/chrome/browser/autofill/form_structure_browsertest.cc b/chrome/browser/autofill/form_structure_browsertest.cc index 26e4c81..56f0ac3 100644 --- a/chrome/browser/autofill/form_structure_browsertest.cc +++ b/chrome/browser/autofill/form_structure_browsertest.cc
@@ -14,6 +14,7 @@ #include "base/no_destructor.h" #include "base/path_service.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" @@ -99,11 +100,28 @@ // deterministic. for (const auto& kv : forms) { const auto* form = kv.second.get(); + std::map<std::string, int> section_to_index; for (const auto& field : *form) { + // Normalize the section by replacing the unique but platform-dependent + // integers in |field->section| with consecutive unique integers. + std::string section = field->section; + size_t last_underscore = section.find_last_of('_'); + size_t next_dash = section.find_first_of('-', last_underscore); + int new_section_index = static_cast<int>(section_to_index.size() + 1); + int section_index = + section_to_index.insert(std::make_pair(section, new_section_index)) + .first->second; + if (last_underscore != std::string::npos && + next_dash != std::string::npos) { + section = base::StringPrintf( + "%s%d%s", section.substr(0, last_underscore + 1).c_str(), + section_index, section.substr(next_dash).c_str()); + } + forms_string += base::JoinString( {field->Type().ToString(), base::UTF16ToUTF8(field->name), base::UTF16ToUTF8(field->label), base::UTF16ToUTF8(field->value), - field->section}, + section}, base::StringPiece(" | ")); forms_string += "\n"; } @@ -155,6 +173,8 @@ autofill::features::kAutofillEnableSupportForMoreStructureInNames, // TODO(crbug.com/1125978): Remove once launched. autofill::features::kAutofillEnableSupportForMoreStructureInAddresses, + // TODO(crbug.com/896689): Remove once launched. + autofill::features::kAutofillNameSectionsWithRendererIds, }, // Disabled {autofill::features::kAutofillRestrictUnownedFieldsToFormlessCheckout});
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index bee6e0c..e116425 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -673,6 +673,8 @@ "arc/input_method_manager/arc_input_method_manager_bridge_impl.h", "arc/input_method_manager/arc_input_method_manager_service.cc", "arc/input_method_manager/arc_input_method_manager_service.h", + "arc/input_method_manager/arc_input_method_state.cc", + "arc/input_method_manager/arc_input_method_state.h", "arc/input_method_manager/input_connection_impl.cc", "arc/input_method_manager/input_connection_impl.h", "arc/instance_throttle/arc_active_window_throttle_observer.cc", @@ -3281,6 +3283,7 @@ "arc/fileapi/chrome_content_provider_url_util_unittest.cc", "arc/fileapi/file_stream_forwarder_unittest.cc", "arc/input_method_manager/arc_input_method_manager_service_unittest.cc", + "arc/input_method_manager/arc_input_method_state_unittest.cc", "arc/input_method_manager/input_connection_impl_unittest.cc", "arc/input_method_manager/test_input_method_manager_bridge.cc", "arc/input_method_manager/test_input_method_manager_bridge.h",
diff --git a/chrome/browser/chromeos/account_manager/account_manager_edu_coexistence_controller_unittest.cc b/chrome/browser/chromeos/account_manager/account_manager_edu_coexistence_controller_unittest.cc index a0103b4..648831f8 100644 --- a/chrome/browser/chromeos/account_manager/account_manager_edu_coexistence_controller_unittest.cc +++ b/chrome/browser/chromeos/account_manager/account_manager_edu_coexistence_controller_unittest.cc
@@ -166,14 +166,13 @@ EXPECT_FALSE(HasInvalidGaiaToken( GetAccountFor(kSecondaryAccount2, kSecondaryAccount2GaiaId))); + UpdateEduCoexistenceToSVersion("5"); + EduCoexistenceConsentInvalidationController edu_coexistence_invalidation_controller(profile(), account_manager(), kDeviceAccount); edu_coexistence_invalidation_controller.Init(); - UpdateEduCoexistenceToSVersion("5"); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(HasInvalidGaiaToken( GetAccountFor(kSecondaryAccount1, kSecondaryAccount1GaiaId))); EXPECT_FALSE(HasInvalidGaiaToken(
diff --git a/chrome/browser/chromeos/arc/arc_util.cc b/chrome/browser/chromeos/arc/arc_util.cc index 4ac0e53..078a0c5d 100644 --- a/chrome/browser/chromeos/arc/arc_util.cc +++ b/chrome/browser/chromeos/arc/arc_util.cc
@@ -72,11 +72,6 @@ base::LazyInstance<std::map<const Profile*, bool>>::DestructorAtExit g_profile_status_check = LAZY_INSTANCE_INITIALIZER; -// The cached value of migration allowed for profile. It is necessary to use -// the same value during a user session. -base::LazyInstance<std::map<base::FilePath, bool>>::DestructorAtExit - g_is_arc_migration_allowed = LAZY_INSTANCE_INITIALIZER; - // Let IsAllowedForProfile() return "false" for any profile. bool g_disallow_for_testing = false; @@ -136,13 +131,6 @@ std::move(callback).Run(); } -bool IsArcMigrationAllowedInternal(const Profile* profile) { - return static_cast<policy_util::EcryptfsMigrationAction>( - profile->GetPrefs()->GetInteger( - prefs::kEcryptfsMigrationStrategy)) != - policy_util::EcryptfsMigrationAction::kDisallowMigration; -} - bool IsUnaffiliatedArcAllowed() { bool arc_allowed; ArcSessionManager* arc_session_manager = ArcSessionManager::Get(); @@ -196,13 +184,6 @@ return false; } - if (IsArcBlockedDueToIncompatibleFileSystem(profile) && - !IsArcMigrationAllowedByPolicyForProfile(profile)) { - VLOG_IF(1, should_report_reason) - << "Incompatible encryption and migration forbidden."; - return false; - } - if (policy_util::IsArcDisabledForEnterprise() && policy_util::IsAccountManaged(profile)) { VLOG_IF(1, should_report_reason) @@ -289,23 +270,6 @@ g_profile_status_check.Get().erase(profile); } -bool IsArcMigrationAllowedByPolicyForProfile(const Profile* profile) { - // Always allow migration for unmanaged users. - if (!profile || !policy_util::IsAccountManaged(profile)) - return true; - - // Use the profile path as unique identifier for profile. - const base::FilePath path = profile->GetPath(); - auto iter = g_is_arc_migration_allowed.Get().find(path); - if (iter == g_is_arc_migration_allowed.Get().end()) { - iter = g_is_arc_migration_allowed.Get() - .emplace(path, IsArcMigrationAllowedInternal(profile)) - .first; - } - - return iter->second; -} - bool IsArcBlockedDueToIncompatibleFileSystem(const Profile* profile) { const user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
diff --git a/chrome/browser/chromeos/arc/arc_util.h b/chrome/browser/chromeos/arc/arc_util.h index 554dbff..57a0a3f 100644 --- a/chrome/browser/chromeos/arc/arc_util.h +++ b/chrome/browser/chromeos/arc/arc_util.h
@@ -74,10 +74,6 @@ // Account has been signed into ARC. bool IsArcProvisioned(const Profile* profile); -// Returns true if the profile is unmanaged or if the policy -// EcryptfsMigrationStrategy for the user doesn't disable the migration. -bool IsArcMigrationAllowedByPolicyForProfile(const Profile* profile); - // Returns true if the profile is temporarily blocked to run ARC in the current // session, because the filesystem storing the profile is incompatible with the // currently installed ARC version.
diff --git a/chrome/browser/chromeos/arc/arc_util_unittest.cc b/chrome/browser/chromeos/arc/arc_util_unittest.cc index 7579e84..c6739c71 100644 --- a/chrome/browser/chromeos/arc/arc_util_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_util_unittest.cc
@@ -737,109 +737,6 @@ EXPECT_FALSE(IsPlayStoreAvailable()); } -using ArcMigrationTest = ChromeArcUtilTest; - -TEST_F(ArcMigrationTest, IsMigrationAllowedUnmanagedUser) { - ScopedLogIn login(GetFakeUserManager(), - AccountId::AdFromUserEmailObjGuid( - profile()->GetProfileUserName(), kTestGaiaId)); - profile()->GetPrefs()->SetInteger(prefs::kEcryptfsMigrationStrategy, 0); - EXPECT_TRUE(IsArcMigrationAllowedByPolicyForProfile(profile())); -} - -TEST_F(ArcMigrationTest, IsMigrationAllowedDefaultManagedUser) { - // Don't set any value for kEcryptfsMigrationStrategy pref. - ScopedLogIn login(GetFakeUserManager(), - AccountId::FromUserEmailGaiaId( - profile()->GetProfileUserName(), kTestGaiaId)); - SetProfileIsManagedForTesting(profile()); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kArcEnabled, std::make_unique<base::Value>(true)); - EXPECT_FALSE(IsArcMigrationAllowedByPolicyForProfile(profile())); -} - -TEST_F(ArcMigrationTest, IsMigrationAllowedForbiddenByPolicy) { - ScopedLogIn login(GetFakeUserManager(), - AccountId::AdFromUserEmailObjGuid( - profile()->GetProfileUserName(), kTestGaiaId)); - SetProfileIsManagedForTesting(profile()); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kArcEnabled, std::make_unique<base::Value>(true)); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kEcryptfsMigrationStrategy, std::make_unique<base::Value>(0)); - EXPECT_FALSE(IsArcMigrationAllowedByPolicyForProfile(profile())); -} - -TEST_F(ArcMigrationTest, IsMigrationAllowedMigrate) { - ScopedLogIn login(GetFakeUserManager(), - AccountId::AdFromUserEmailObjGuid( - profile()->GetProfileUserName(), kTestGaiaId)); - SetProfileIsManagedForTesting(profile()); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kArcEnabled, std::make_unique<base::Value>(true)); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kEcryptfsMigrationStrategy, std::make_unique<base::Value>(1)); - EXPECT_TRUE(IsArcMigrationAllowedByPolicyForProfile(profile())); -} - -TEST_F(ArcMigrationTest, IsMigrationAllowedWipe) { - ScopedLogIn login(GetFakeUserManager(), - AccountId::AdFromUserEmailObjGuid( - profile()->GetProfileUserName(), kTestGaiaId)); - SetProfileIsManagedForTesting(profile()); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kArcEnabled, std::make_unique<base::Value>(true)); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kEcryptfsMigrationStrategy, std::make_unique<base::Value>(2)); - EXPECT_TRUE(IsArcMigrationAllowedByPolicyForProfile(profile())); -} - -TEST_F(ArcMigrationTest, IsMigrationAllowedMinimalMigration) { - ScopedLogIn login(GetFakeUserManager(), - AccountId::AdFromUserEmailObjGuid( - profile()->GetProfileUserName(), kTestGaiaId)); - SetProfileIsManagedForTesting(profile()); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kArcEnabled, std::make_unique<base::Value>(true)); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kEcryptfsMigrationStrategy, std::make_unique<base::Value>(4)); - EXPECT_TRUE(IsArcMigrationAllowedByPolicyForProfile(profile())); -} - -TEST_F(ArcMigrationTest, IsMigrationAllowedCachedValueForbidden) { - ScopedLogIn login(GetFakeUserManager(), - AccountId::AdFromUserEmailObjGuid( - profile()->GetProfileUserName(), kTestGaiaId)); - SetProfileIsManagedForTesting(profile()); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kArcEnabled, std::make_unique<base::Value>(true)); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kEcryptfsMigrationStrategy, std::make_unique<base::Value>(0)); - EXPECT_FALSE(IsArcMigrationAllowedByPolicyForProfile(profile())); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kEcryptfsMigrationStrategy, std::make_unique<base::Value>(1)); - - // The value of IsArcMigrationAllowedByPolicyForProfile() should be cached. - // So, even if the policy is set after the first call, the returned value - // should not be changed. - EXPECT_FALSE(IsArcMigrationAllowedByPolicyForProfile(profile())); -} - -TEST_F(ArcMigrationTest, IsMigrationAllowedCachedValueAllowed) { - ScopedLogIn login(GetFakeUserManager(), - AccountId::AdFromUserEmailObjGuid( - profile()->GetProfileUserName(), kTestGaiaId)); - SetProfileIsManagedForTesting(profile()); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kArcEnabled, std::make_unique<base::Value>(true)); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kEcryptfsMigrationStrategy, std::make_unique<base::Value>(1)); - EXPECT_TRUE(IsArcMigrationAllowedByPolicyForProfile(profile())); - profile()->GetTestingPrefService()->SetManagedPref( - prefs::kEcryptfsMigrationStrategy, std::make_unique<base::Value>(0)); - EXPECT_TRUE(IsArcMigrationAllowedByPolicyForProfile(profile())); -} - class ArcOobeTest : public ChromeArcUtilTest { public: ArcOobeTest() {
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc index 4cb0071..c8d5bc0 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc
@@ -104,6 +104,58 @@ ~ArcInputMethodManagerServiceFactory() override = default; }; +class ArcInputMethodStateDelegateImpl : public ArcInputMethodState::Delegate { + public: + explicit ArcInputMethodStateDelegateImpl(Profile* profile) + : profile_(profile) {} + ArcInputMethodStateDelegateImpl(const ArcInputMethodStateDelegateImpl&) = + delete; + ArcInputMethodStateDelegateImpl& operator=( + const ArcInputMethodStateDelegateImpl& state) = delete; + ~ArcInputMethodStateDelegateImpl() override = default; + + // Returns whether ARC IMEs should be allowed now or not. + // It depends on tablet mode state and a11y keyboard option. + bool ShouldArcIMEAllowed() const override { + const bool is_command_line_flag_enabled = + base::CommandLine::ForCurrentProcess()->HasSwitch( + keyboard::switches::kEnableVirtualKeyboard); + const bool is_normal_vk_enabled = + !profile_->GetPrefs()->GetBoolean( + ash::prefs::kAccessibilityVirtualKeyboardEnabled) && + ash::TabletMode::Get()->InTabletMode(); + return is_command_line_flag_enabled || is_normal_vk_enabled; + } + + chromeos::input_method::InputMethodDescriptor BuildInputMethodDescriptor( + const mojom::ImeInfoPtr& info) const override { + // We don't care too much about |layouts| at this point since the feature is + // for tablet mode. + const std::vector<std::string> layouts{"us"}; + + // Set the fake language so that the IME is shown in the special section in + // chrome://settings. + const std::vector<std::string> languages{ + chromeos::extension_ime_util::kArcImeLanguage}; + + const std::string display_name = info->display_name; + + const std::string proxy_ime_extension_id = + crx_file::id_util::GenerateId(kArcIMEProxyExtensionName); + const std::string& input_method_id = + chromeos::extension_ime_util::GetArcInputMethodID( + proxy_ime_extension_id, info->ime_id); + // TODO(yhanada): Set the indicator string after the UI spec is finalized. + return chromeos::input_method::InputMethodDescriptor( + input_method_id, display_name, std::string() /* indicator */, layouts, + languages, false /* is_login_keyboard */, GURL(info->settings_url), + GURL() /* input_view_url */); + } + + private: + Profile* const profile_; +}; + } // namespace class ArcInputMethodManagerService::ArcInputMethodBoundsObserver @@ -275,6 +327,9 @@ imm_bridge_( std::make_unique<ArcInputMethodManagerBridgeImpl>(this, bridge_service)), + arc_ime_state_delegate_( + std::make_unique<ArcInputMethodStateDelegateImpl>(profile_)), + arc_ime_state_(arc_ime_state_delegate_.get()), is_virtual_keyboard_shown_(false), is_updating_imm_entry_(false), proxy_ime_extension_id_( @@ -371,15 +426,20 @@ } void ArcInputMethodManagerService::OnImeDisabled(const std::string& ime_id) { - const std::string component_id = - chromeos::extension_ime_util::GetArcInputMethodID(proxy_ime_extension_id_, - ime_id); + arc_ime_state_.DisableInputMethod(ime_id); + // Remove the IME from the prefs to disable it. const std::string active_ime_ids = profile_->GetPrefs()->GetString(prefs::kLanguageEnabledImes); - std::vector<base::StringPiece> active_ime_list = base::SplitStringPiece( + std::vector<std::string> active_ime_list = base::SplitString( active_ime_ids, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - base::Erase(active_ime_list, component_id); + + base::EraseIf(active_ime_list, [](const auto& id) { + return chromeos::extension_ime_util::IsArcIME(id); + }); + for (const auto& descriptor : arc_ime_state_.GetEnabledInputMethods()) + active_ime_list.push_back(descriptor.id()); + profile_->GetPrefs()->SetString(prefs::kLanguageEnabledImes, base::JoinString(active_ime_list, ",")); @@ -389,13 +449,11 @@ void ArcInputMethodManagerService::OnImeInfoChanged( std::vector<mojom::ImeInfoPtr> ime_info_array) { - latest_ime_info_ = std::move(ime_info_array); - + arc_ime_state_.InitializeWithImeInfo(proxy_ime_extension_id_, ime_info_array); UpdateInputMethodEntryWithImeInfo(); } void ArcInputMethodManagerService::UpdateInputMethodEntryWithImeInfo() { - using chromeos::extension_ime_util::GetArcInputMethodID; using chromeos::input_method::InputMethodDescriptor; using chromeos::input_method::InputMethodDescriptors; using chromeos::input_method::InputMethodManager; @@ -413,61 +471,42 @@ // Remove the old registered entry. state->RemoveInputMethodExtension(proxy_ime_extension_id_); - // Convert ime_info_array to InputMethodDescriptors. - InputMethodDescriptors descriptors; - std::vector<std::string> enabled_input_method_ids; - ime_ids_allowed_in_clamshell_mode_.clear(); - for (const auto& ime_info : latest_ime_info_) { - const InputMethodDescriptor& descriptor = - BuildInputMethodDescriptor(ime_info.get()); - descriptors.push_back(descriptor); - if (ime_info->enabled) - enabled_input_method_ids.push_back(descriptor.id()); - if (ime_info->is_allowed_in_clamshell_mode) - ime_ids_allowed_in_clamshell_mode_.insert(descriptor.id()); - } - if (descriptors.empty()) { - // If no ARC IME is installed, remove ARC IME entry from preferences. + const InputMethodDescriptors installed_imes = + arc_ime_state_.GetActiveInputMethods(); + if (installed_imes.empty()) { + // If no ARC IME is installed or allowed, remove ARC IME entry from + // preferences. RemoveArcIMEFromPrefs(); return; } - if (!ShouldArcIMEAllowed() && ime_ids_allowed_in_clamshell_mode_.empty()) { - // ARC IME is disallowed, remove ARC IME entry from preferences. - RemoveArcIMEFromPrefs(); - return; - } + // Add the proxy IME entry to InputMethodManager if any ARC IME is installed. - state->AddInputMethodExtension(proxy_ime_extension_id_, descriptors, + state->AddInputMethodExtension(proxy_ime_extension_id_, installed_imes, proxy_ime_engine_.get()); // Enable IMEs that are already enabled in the container. + // TODO(crbug.com/845079): We should keep the order of the IMEs as same as in + // chrome://settings + const std::string active_ime_ids = profile_->GetPrefs()->GetString(prefs::kLanguageEnabledImes); std::vector<std::string> active_ime_list = base::SplitString( active_ime_ids, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - // TODO(crbug.com/845079): We should keep the order of the IMEs as same as in - // chrome://settings - for (const auto& input_method_id : enabled_input_method_ids) { - if (!base::Contains(active_ime_list, input_method_id) && - (ShouldArcIMEAllowed() || - ime_ids_allowed_in_clamshell_mode_.count(input_method_id))) { - active_ime_list.push_back(input_method_id); - } - } - // Disable IMEs that are already disable in the container. - base::EraseIf(active_ime_list, [&enabled_input_method_ids](const auto& id) { - return chromeos::extension_ime_util::IsArcIME(id) && - !base::Contains(enabled_input_method_ids, id); + + // Remove all ARC IMEs at first. + base::EraseIf(active_ime_list, [](const auto& id) { + return chromeos::extension_ime_util::IsArcIME(id); }); + // Re-add enabled and allowed IMEs. + for (const auto& descriptor : arc_ime_state_.GetEnabledInputMethods()) + active_ime_list.push_back(descriptor.id()); + + // Set the pref. profile_->GetPrefs()->SetString(prefs::kLanguageEnabledImes, base::JoinString(active_ime_list, ",")); - for (const auto& input_method_id : enabled_input_method_ids) { - if (ShouldArcIMEAllowed() || - ime_ids_allowed_in_clamshell_mode_.count(input_method_id)) { - state->EnableInputMethod(input_method_id); - } - } + for (const auto& descriptor : arc_ime_state_.GetEnabledInputMethods()) + state->EnableInputMethod(descriptor.id()); state->ChangeInputMethod(active_ime_id, false); is_updating_imm_entry_ = false; @@ -478,7 +517,7 @@ if (active_ime_id != state->GetCurrentInputMethod().id()) InputMethodChanged(InputMethodManager::Get(), nullptr, false); - UMA_HISTOGRAM_COUNTS_100("Arc.ImeCount", descriptors.size()); + UMA_HISTOGRAM_COUNTS_100("Arc.ImeCount", installed_imes.size()); } void ArcInputMethodManagerService::OnConnectionClosed() { @@ -676,30 +715,6 @@ false /* is_input_state_update_requested */); } -chromeos::input_method::InputMethodDescriptor -ArcInputMethodManagerService::BuildInputMethodDescriptor( - const mojom::ImeInfo* info) { - // We don't care too much about |layouts| at this point since the feature is - // for tablet mode. - const std::vector<std::string> layouts{"us"}; - - // Set the fake language so that the IME is shown in the special section in - // chrome://settings. - const std::vector<std::string> languages{ - chromeos::extension_ime_util::kArcImeLanguage}; - - const std::string display_name = info->display_name; - - const std::string& input_method_id = - chromeos::extension_ime_util::GetArcInputMethodID(proxy_ime_extension_id_, - info->ime_id); - // TODO(yhanada): Set the indicator string after the UI spec is finalized. - return chromeos::input_method::InputMethodDescriptor( - input_method_id, display_name, std::string() /* indicator */, layouts, - languages, false /* is_login_keyboard */, GURL(info->settings_url), - GURL() /* input_view_url */); -} - void ArcInputMethodManagerService::RemoveArcIMEFromPrefs() { RemoveArcIMEFromPref(prefs::kLanguageEnabledImes); RemoveArcIMEFromPref(prefs::kLanguagePreloadEngines); @@ -726,17 +741,6 @@ base::JoinString(ime_id_list, ",")); } -bool ArcInputMethodManagerService::ShouldArcIMEAllowed() const { - const bool is_command_line_flag_enabled = - base::CommandLine::ForCurrentProcess()->HasSwitch( - keyboard::switches::kEnableVirtualKeyboard); - const bool is_normal_vk_enabled = - !profile_->GetPrefs()->GetBoolean( - ash::prefs::kAccessibilityVirtualKeyboardEnabled) && - ash::TabletMode::Get()->InTabletMode(); - return is_command_line_flag_enabled || is_normal_vk_enabled; -} - void ArcInputMethodManagerService::OnTabletModeToggled(bool /* enabled */) { UpdateInputMethodEntryWithImeInfo(); }
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.h b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.h index 37c8d89..7c6dfaf0 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.h +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.h
@@ -14,6 +14,7 @@ #include "base/observer_list_types.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_bridge.h" +#include "chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state.h" #include "chrome/browser/chromeos/arc/input_method_manager/input_connection_impl.h" #include "chrome/browser/chromeos/input_method/input_method_engine.h" #include "components/arc/mojom/input_method_manager.mojom-forward.h" @@ -120,14 +121,10 @@ void RemoveArcIMEFromPrefs(); void RemoveArcIMEFromPref(const char* pref_name); - // Returns whether ARC IMEs should be allowed now or not. - // It depends on tablet mode state and a11y keyboard option. - bool ShouldArcIMEAllowed() const; - void OnTabletModeToggled(bool enabled); // Update the descriptors in IMM and the prefs according to - // |latest_ime_info_|. + // |arc_ime_state_|. void UpdateInputMethodEntryWithImeInfo(); // Notifies InputMethodManager's observers of possible ARC IME state changes. @@ -142,8 +139,8 @@ std::unique_ptr<ArcInputMethodManagerBridge> imm_bridge_; std::set<std::string> active_arc_ime_ids_; - std::set<std::string> ime_ids_allowed_in_clamshell_mode_; - std::vector<mojom::ImeInfoPtr> latest_ime_info_; + std::unique_ptr<ArcInputMethodState::Delegate> arc_ime_state_delegate_; + ArcInputMethodState arc_ime_state_; bool is_virtual_keyboard_shown_; // This flag is set to true while updating ARC IMEs entries in IMM to avoid // exposing incomplete state.
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc index 4c8d82d..f63b013 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc
@@ -44,6 +44,20 @@ namespace im = chromeos::input_method; +mojom::ImeInfoPtr GenerateImeInfo(const std::string& id, + const std::string& name, + const std::string& url, + bool enabled, + bool always_allowed) { + mojom::ImeInfoPtr info = mojom::ImeInfo::New(); + info->ime_id = id; + info->display_name = name; + info->settings_url = url; + info->enabled = enabled; + info->is_allowed_in_clamshell_mode = always_allowed; + return info; +} + class FakeTabletMode : public ash::TabletMode { public: FakeTabletMode() = default; @@ -440,6 +454,18 @@ ceiu::GetArcInputMethodID(proxy_ime_extension_id, kArcImeX); const std::string arc_ime_y_component = ceiu::GetArcInputMethodID(proxy_ime_extension_id, kArcImeY); + mojom::ImeInfoPtr arc_ime_x = GenerateImeInfo(kArcImeX, "", "", false, false); + mojom::ImeInfoPtr arc_ime_y = GenerateImeInfo(kArcImeY, "", "", false, false); + + ToggleTabletMode(true); + + // Adding two ARC IMEs. + { + std::vector<mojom::ImeInfoPtr> info_array; + info_array.emplace_back(arc_ime_x.Clone()); + info_array.emplace_back(arc_ime_y.Clone()); + service()->OnImeInfoChanged(std::move(info_array)); + } // Enable one non-ARC IME, then remove an ARC IME. This usually does not // happen, but confirm that OnImeDisabled() does not do anything bad even @@ -451,18 +477,35 @@ // Enable two IMEs (one non-ARC and one ARC), remove the ARC IME, and then // confirm the non-ARC one remains. + arc_ime_x->enabled = true; + { + std::vector<mojom::ImeInfoPtr> info_array; + info_array.emplace_back(arc_ime_x.Clone()); + info_array.emplace_back(arc_ime_y.Clone()); + service()->OnImeInfoChanged(std::move(info_array)); + } std::string pref_str = base::StringPrintf("%s,%s", kNonArcIme, arc_ime_x_component.c_str()); - profile()->GetPrefs()->SetString(prefs::kLanguageEnabledImes, pref_str); + EXPECT_EQ(pref_str, + profile()->GetPrefs()->GetString(prefs::kLanguageEnabledImes)); service()->OnImeDisabled(kArcImeX); EXPECT_EQ(kNonArcIme, profile()->GetPrefs()->GetString(prefs::kLanguageEnabledImes)); // Enable two ARC IMEs along with one non-ARC one, remove one of two ARC IMEs, // then confirm one non-ARC IME and one ARC IME still remain. - pref_str = base::StringPrintf("%s,%s,%s", arc_ime_x_component.c_str(), - kNonArcIme, arc_ime_y_component.c_str()); - profile()->GetPrefs()->SetString(prefs::kLanguageEnabledImes, pref_str); + arc_ime_y->enabled = true; + { + std::vector<mojom::ImeInfoPtr> info_array; + info_array.emplace_back(arc_ime_x.Clone()); + info_array.emplace_back(arc_ime_y.Clone()); + service()->OnImeInfoChanged(std::move(info_array)); + } + pref_str = + base::StringPrintf("%s,%s,%s", kNonArcIme, arc_ime_x_component.c_str(), + arc_ime_y_component.c_str()); + EXPECT_EQ(pref_str, + profile()->GetPrefs()->GetString(prefs::kLanguageEnabledImes)); service()->OnImeDisabled(kArcImeX); pref_str = base::StringPrintf("%s,%s", kNonArcIme, arc_ime_y_component.c_str()); @@ -479,20 +522,14 @@ const std::string android_ime_id1 = "test.arc.ime"; const std::string display_name1 = "DisplayName"; const std::string settings_url1 = "url_to_settings"; - mojom::ImeInfoPtr info1 = mojom::ImeInfo::New(); - info1->ime_id = android_ime_id1; - info1->display_name = display_name1; - info1->enabled = false; - info1->settings_url = settings_url1; + mojom::ImeInfoPtr info1 = GenerateImeInfo(android_ime_id1, display_name1, + settings_url1, false, false); const std::string android_ime_id2 = "test.arc.ime2"; const std::string display_name2 = "DisplayName2"; const std::string settings_url2 = "url_to_settings2"; - mojom::ImeInfoPtr info2 = mojom::ImeInfo::New(); - info2->ime_id = android_ime_id2; - info2->display_name = display_name2; - info2->enabled = true; - info2->settings_url = settings_url2; + mojom::ImeInfoPtr info2 = GenerateImeInfo(android_ime_id2, display_name2, + settings_url2, true, false); std::vector< std::tuple<std::string, chromeos::input_method::InputMethodDescriptors, @@ -595,9 +632,8 @@ // Enable the ARC IME. { - mojom::ImeInfoPtr info = mojom::ImeInfo::New(); - info->ime_id = android_ime_id; - info->enabled = true; + mojom::ImeInfoPtr info = + GenerateImeInfo(android_ime_id, "", "", true, false); std::vector<mojom::ImeInfoPtr> info_array{}; info_array.emplace_back(info.Clone()); service()->OnImeInfoChanged(std::move(info_array)); @@ -706,9 +742,8 @@ // All IMEs are allowed to use. // Enable the ARC IME. { - mojom::ImeInfoPtr info = mojom::ImeInfo::New(); - info->ime_id = android_ime_id; - info->enabled = true; + mojom::ImeInfoPtr info = + GenerateImeInfo(android_ime_id, "", "", true, false); std::vector<mojom::ImeInfoPtr> info_array{}; info_array.emplace_back(info.Clone()); service()->OnImeInfoChanged(std::move(info_array)); @@ -809,9 +844,8 @@ // Enable the ARC IME. { - mojom::ImeInfoPtr info = mojom::ImeInfo::New(); - info->ime_id = android_ime_id; - info->enabled = true; + mojom::ImeInfoPtr info = + GenerateImeInfo(android_ime_id, "", "", true, false); std::vector<mojom::ImeInfoPtr> info_array{}; info_array.emplace_back(info.Clone()); service()->OnImeInfoChanged(std::move(info_array)); @@ -853,11 +887,8 @@ const std::string android_ime_id = "test.arc.ime"; const std::string display_name = "DisplayName"; const std::string settings_url = "url_to_settings"; - mojom::ImeInfoPtr info = mojom::ImeInfo::New(); - info->ime_id = android_ime_id; - info->display_name = display_name; - info->enabled = false; - info->settings_url = settings_url; + mojom::ImeInfoPtr info = GenerateImeInfo(android_ime_id, display_name, + settings_url, false, false); std::vector<mojom::ImeInfoPtr> info_array; info_array.emplace_back(std::move(info)); @@ -947,11 +978,8 @@ const std::string android_ime_id = "test.arc.ime"; const std::string display_name = "DisplayName"; const std::string settings_url = "url_to_settings"; - mojom::ImeInfoPtr info = mojom::ImeInfo::New(); - info->ime_id = android_ime_id; - info->display_name = display_name; - info->enabled = false; - info->settings_url = settings_url; + mojom::ImeInfoPtr info = GenerateImeInfo(android_ime_id, display_name, + settings_url, false, false); std::vector<mojom::ImeInfoPtr> info_array; info_array.emplace_back(std::move(info)); @@ -1017,7 +1045,8 @@ const std::string android_ime_id = "test.arc.ime"; const std::string display_name = "DisplayName"; const std::string settings_url = "url_to_settings"; - mojom::ImeInfoPtr info = mojom::ImeInfo::New(); + mojom::ImeInfoPtr info = GenerateImeInfo(android_ime_id, display_name, + settings_url, false, false); info->ime_id = android_ime_id; info->display_name = display_name; info->enabled = false;
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state.cc new file mode 100644 index 0000000..b022336 --- /dev/null +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state.cc
@@ -0,0 +1,78 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state.h" + +#include <algorithm> + +#include "ash/public/cpp/ash_pref_names.h" +#include "ash/public/cpp/keyboard/keyboard_switches.h" +#include "ash/public/cpp/tablet_mode.h" +#include "base/command_line.h" +#include "components/arc/mojom/input_method_manager.mojom.h" +#include "components/prefs/pref_service.h" +#include "mojo/public/cpp/bindings/struct_ptr.h" +#include "ui/base/ime/chromeos/extension_ime_util.h" + +namespace arc { + +using InputMethodDescriptor = ::chromeos::input_method::InputMethodDescriptor; +using InputMethodDescriptors = ::chromeos::input_method::InputMethodDescriptors; + +ArcInputMethodState::ArcInputMethodState(const Delegate* const delegate) + : delegate_(delegate) {} +ArcInputMethodState::~ArcInputMethodState() = default; + +void ArcInputMethodState::InitializeWithImeInfo( + const std::string& proxy_ime_extension_id, + const std::vector<mojom::ImeInfoPtr>& ime_info_array) { + installed_imes_.clear(); + for (const auto& info : ime_info_array) { + installed_imes_.push_back({info->ime_id, info->enabled, + info->is_allowed_in_clamshell_mode, + delegate_->BuildInputMethodDescriptor(info)}); + } +} + +void ArcInputMethodState::DisableInputMethod(const std::string& ime_id) { + SetInputMethodEnabled(ime_id, false); +} + +InputMethodDescriptors ArcInputMethodState::GetActiveInputMethods() const { + const bool all_allowed = delegate_->ShouldArcIMEAllowed(); + + InputMethodDescriptors result; + for (const auto& entry : installed_imes_) { + if (all_allowed || entry.always_allowed_) + result.push_back(entry.descriptor_); + } + return result; +} + +InputMethodDescriptors ArcInputMethodState::GetEnabledInputMethods() const { + const bool all_allowed = delegate_->ShouldArcIMEAllowed(); + + InputMethodDescriptors result; + for (const auto& entry : installed_imes_) { + if (entry.enabled_ && (all_allowed || entry.always_allowed_)) + result.push_back(entry.descriptor_); + } + return result; +} + +void ArcInputMethodState::SetInputMethodEnabled(const std::string& ime_id, + bool enabled) { + auto it = std::find_if(installed_imes_.begin(), installed_imes_.end(), + [&ime_id](const InputMethodEntry& entry) { + return ime_id == entry.ime_id_; + }); + if (it == installed_imes_.end()) { + // Ignore the request to enable/disable not-installed IME. + return; + } + + it->enabled_ = enabled; +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state.h b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state.h new file mode 100644 index 0000000..bdafe65 --- /dev/null +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state.h
@@ -0,0 +1,64 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_INPUT_METHOD_MANAGER_ARC_INPUT_METHOD_STATE_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_INPUT_METHOD_MANAGER_ARC_INPUT_METHOD_STATE_H_ + +#include <set> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "components/arc/mojom/input_method_manager.mojom-forward.h" +#include "ui/base/ime/chromeos/input_method_descriptor.h" + +namespace arc { + +// Model to state ARC IME's state (installed/enabled/allowed). +class ArcInputMethodState { + public: + class Delegate { + public: + virtual ~Delegate() = default; + virtual bool ShouldArcIMEAllowed() const = 0; + virtual chromeos::input_method::InputMethodDescriptor + BuildInputMethodDescriptor(const mojom::ImeInfoPtr& info) const = 0; + }; + + explicit ArcInputMethodState(const Delegate* const delegate); + ~ArcInputMethodState(); + + ArcInputMethodState(const ArcInputMethodState& state) = delete; + ArcInputMethodState& operator=(const ArcInputMethodState& state) = delete; + + // State updating methods: + void InitializeWithImeInfo( + const std::string& proxy_ime_extension_id, + const std::vector<mojom::ImeInfoPtr>& ime_info_array); + void DisableInputMethod(const std::string& ime_id); + + // Return the InputMethodDescriptors which are installed and allowed. + chromeos::input_method::InputMethodDescriptors GetActiveInputMethods() const; + // Return the InputMethodDescriptors which are enabled and allowed. + chromeos::input_method::InputMethodDescriptors GetEnabledInputMethods() const; + + private: + class InputMethodEntry { + public: + std::string ime_id_; + bool enabled_{false}; + bool always_allowed_{false}; + chromeos::input_method::InputMethodDescriptor descriptor_; + }; + + void SetInputMethodEnabled(const std::string& ime_id, bool enabled); + + const Delegate* const delegate_; + + std::vector<InputMethodEntry> installed_imes_; +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_INPUT_METHOD_MANAGER_ARC_INPUT_METHOD_STATE_H_
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state_unittest.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state_unittest.cc new file mode 100644 index 0000000..c26bce0 --- /dev/null +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state_unittest.cc
@@ -0,0 +1,111 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state.h" + +#include <memory> + +#include "ash/public/cpp/tablet_mode.h" +#include "base/test/bind.h" +#include "chrome/test/base/testing_profile.h" +#include "components/arc/mojom/input_method_manager.mojom.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/ime/chromeos/extension_ime_util.h" + +namespace arc { + +using ::chromeos::extension_ime_util::GetArcInputMethodID; +using ::chromeos::input_method::InputMethodDescriptor; +using ::chromeos::input_method::InputMethodDescriptors; + +namespace { + +mojom::ImeInfoPtr GenerateImeInfo(const std::string& id, + bool enabled, + bool always_allowed) { + mojom::ImeInfoPtr info = mojom::ImeInfo::New(); + info->ime_id = id; + info->enabled = enabled; + info->is_allowed_in_clamshell_mode = always_allowed; + return info; +} + +class FakeDelegate : public ArcInputMethodState::Delegate { + public: + bool ShouldArcIMEAllowed() const override { return allowed; } + InputMethodDescriptor BuildInputMethodDescriptor( + const mojom::ImeInfoPtr& info) const override { + return InputMethodDescriptor(info->ime_id, "", "", {}, {}, false, GURL(), + GURL()); + } + bool allowed = false; +}; + +} // namespace + +TEST(ArcInputMethodState, Constructor) { + FakeDelegate delegate; + + ArcInputMethodState empty_state(&delegate); + InputMethodDescriptors empty_vector; + EXPECT_EQ(0u, empty_state.GetActiveInputMethods().size()); + EXPECT_EQ(0u, empty_state.GetEnabledInputMethods().size()); +} + +TEST(ArcInputMethodState, InstallInputMethod) { + FakeDelegate delegate; + + ArcInputMethodState state(&delegate); + std::vector<mojom::ImeInfoPtr> imes; + imes.push_back(GenerateImeInfo("ime_a", true, false)); + imes.push_back(GenerateImeInfo("ime_b", true, true)); + imes.push_back(GenerateImeInfo("ime_c", false, false)); + imes.push_back(GenerateImeInfo("ime_d", false, true)); + state.InitializeWithImeInfo("ime_id", imes); + + InputMethodDescriptors active_imes = state.GetActiveInputMethods(); + EXPECT_EQ(2u, active_imes.size()); + EXPECT_EQ("ime_b", active_imes[0].id()); + EXPECT_EQ("ime_d", active_imes[1].id()); + + InputMethodDescriptors enabled_imes = state.GetEnabledInputMethods(); + EXPECT_EQ(1u, enabled_imes.size()); + EXPECT_EQ("ime_b", enabled_imes[0].id()); +} + +TEST(ArcInputMethodState, DisableInputMethod) { + FakeDelegate delegate; + + ArcInputMethodState state(&delegate); + std::vector<mojom::ImeInfoPtr> imes; + imes.push_back(GenerateImeInfo("ime_a", true, true)); + state.InitializeWithImeInfo("ime_id", imes); + EXPECT_EQ(1u, state.GetEnabledInputMethods().size()); + + state.DisableInputMethod("ime_a"); + EXPECT_EQ(0u, state.GetEnabledInputMethods().size()); +} + +TEST(ArcInputMethodState, AllowDisallowInputMethods) { + FakeDelegate delegate; + + ArcInputMethodState state(&delegate); + std::vector<mojom::ImeInfoPtr> imes; + imes.push_back(GenerateImeInfo("ime_a", true, true)); + imes.push_back(GenerateImeInfo("ime_b", true, false)); + state.InitializeWithImeInfo("ime_id", imes); + + EXPECT_EQ(1u, state.GetActiveInputMethods().size()); + EXPECT_EQ("ime_a", state.GetActiveInputMethods()[0].id()); + + delegate.allowed = true; + EXPECT_EQ(2u, state.GetActiveInputMethods().size()); + + delegate.allowed = false; + EXPECT_EQ(1u, state.GetActiveInputMethods().size()); + EXPECT_EQ("ime_a", state.GetActiveInputMethods()[0].id()); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_util.cc b/chrome/browser/chromeos/arc/policy/arc_policy_util.cc index 2519fa64..c1f09e3 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_util.cc +++ b/chrome/browser/chromeos/arc/policy/arc_policy_util.cc
@@ -42,32 +42,6 @@ chromeos::switches::kEnterpriseDisableArc); } -base::Optional<EcryptfsMigrationAction> DecodeMigrationActionFromPolicy( - const enterprise_management::CloudPolicySettings& policy) { - if (!policy.has_ecryptfsmigrationstrategy()) - return base::nullopt; - const enterprise_management::IntegerPolicyProto& policy_proto = - policy.ecryptfsmigrationstrategy(); - if (!policy_proto.has_value()) - return base::nullopt; - - // Use |policy::EcryptfsMigrationStrategyPolicyHandler| to translate from - // policy to enum, as some obsolete policy settings need to be aliased to - // other enum values. - policy::PolicyMap policy_map; - policy_map.Set(policy::key::kEcryptfsMigrationStrategy, - policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, - base::Value(static_cast<int>(policy_proto.value())), nullptr); - PrefValueMap prefs; - policy::EcryptfsMigrationStrategyPolicyHandler handler; - handler.ApplyPolicySettings(policy_map, &prefs); - int strategy = 0; - if (!prefs.GetInteger(arc::prefs::kEcryptfsMigrationStrategy, &strategy)) - return base::nullopt; - return static_cast<EcryptfsMigrationAction>(strategy); -} - std::set<std::string> GetRequestedPackagesFromArcPolicy( const std::string& arc_policy) { base::Optional<base::Value> dict = base::JSONReader::Read(
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_util.h b/chrome/browser/chromeos/arc/policy/arc_policy_util.h index a18c5a9..9756fd77 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_util.h +++ b/chrome/browser/chromeos/arc/policy/arc_policy_util.h
@@ -14,47 +14,15 @@ class Profile; -namespace enterprise_management { -class CloudPolicySettings; -} - namespace arc { namespace policy_util { -// The action that should be taken when an ecryptfs user home which needs -// migration is detected. Each valid value of the -// EcryptfsMigrationStrategy policy must either map directly to one of these -// entries (by having the same numerical value) or be aliased to one of them by -// the EcryptfsMigrationStrategyPolicyHandler. -enum class EcryptfsMigrationAction : int32_t { - // Don't migrate. - kDisallowMigration = 0, - // Migrate without asking the user. - kMigrate = 1, - // Wipe the user home and start again. - kWipe = 2, - // Ask the user if migration should be performed (available to consumers - // only). - kAskUser = 3, - // Minimal migration - similar to kWipe, but runs migration code with a small - // allowlist of files to preserve authentication data. - kMinimalMigrate = 4, - // No longer supported. - kAskForEcryptfsArcUsersNoLongerSupported = 5, -}; - // Returns true if the account is managed. Otherwise false. bool IsAccountManaged(const Profile* profile); // Returns true if ARC is disabled by --enterprise-disable-arc flag. bool IsArcDisabledForEnterprise(); -// Decodes the EcryptfsMigrationStrategy user policy into the -// EcryptfsMigrationAction enum. If the policy is present and has a valid value, -// returns the value. Otherwise returns base::nullopt. -base::Optional<EcryptfsMigrationAction> DecodeMigrationActionFromPolicy( - const enterprise_management::CloudPolicySettings& policy); - // Returns set of packages requested to install from |arc_policy|. |arc_policy| // has JSON blob format, see // https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ArcPolicy
diff --git a/chrome/browser/chromeos/child_accounts/edu_coexistence_tos_store_utils.cc b/chrome/browser/chromeos/child_accounts/edu_coexistence_tos_store_utils.cc index 04f193c..6db7842 100644 --- a/chrome/browser/chromeos/child_accounts/edu_coexistence_tos_store_utils.cc +++ b/chrome/browser/chromeos/child_accounts/edu_coexistence_tos_store_utils.cc
@@ -16,10 +16,7 @@ namespace edu_coexistence { -// TODO(yilkal): Update the "0" below to the terms of service version number -// that will first be sent via policy inorder to ensure that we will not -// invalidate pre-existing edu-coexistence accounts. -const char kMinTOSVersionNumber[] = "0"; +const char kMinTOSVersionNumber[] = "337351677"; UserConsentInfo::UserConsentInfo(const std::string& gaia_id, const std::string& version) @@ -27,15 +24,15 @@ bool IsConsentVersionLessThan(const std::string& lhs_version, const std::string& rhs_version) { - int lhs_version_int; - if (!base::StringToInt(lhs_version, &lhs_version_int)) { + uint64_t lhs_version_int; + if (!base::StringToUint64(lhs_version, &lhs_version_int)) { LOG(ERROR) << " TermsOfService |lhs_version| string is not a number" << lhs_version; return false; } - int rhs_version_int; - if (!base::StringToInt(rhs_version, &rhs_version_int)) { + uint64_t rhs_version_int; + if (!base::StringToUint64(rhs_version, &rhs_version_int)) { LOG(ERROR) << " TermsOfService |rhs_version| string is not a number" << rhs_version; return false;
diff --git a/chrome/browser/chromeos/file_manager/devtools_listener.cc b/chrome/browser/chromeos/file_manager/devtools_listener.cc index 4fdb036..a4746da 100644 --- a/chrome/browser/chromeos/file_manager/devtools_listener.cc +++ b/chrome/browser/chromeos/file_manager/devtools_listener.cc
@@ -85,6 +85,19 @@ return result; } +void DevToolsListener::SetupCoverageStore(const base::FilePath& store_path) { + if (!base::PathExists(store_path)) + CHECK(base::CreateDirectory(store_path)); + + base::FilePath tests = store_path.AppendASCII("tests"); + if (!base::PathExists(tests)) + CHECK(base::CreateDirectory(tests)); + + base::FilePath scripts = store_path.AppendASCII("scripts"); + if (!base::PathExists(scripts)) + CHECK(base::CreateDirectory(scripts)); +} + void DevToolsListener::Start(content::DevToolsAgentHost* host) { std::string enable_runtime = "{\"id\":10,\"method\":\"Runtime.enable\"}"; SendCommandMessage(host, enable_runtime);
diff --git a/chrome/browser/chromeos/file_manager/devtools_listener.h b/chrome/browser/chromeos/file_manager/devtools_listener.h index 39d369d..d81c9bd 100644 --- a/chrome/browser/chromeos/file_manager/devtools_listener.h +++ b/chrome/browser/chromeos/file_manager/devtools_listener.h
@@ -42,6 +42,9 @@ static std::string HostString(content::DevToolsAgentHost* host, const std::string& prefix = {}); + // Creates coverage output directory and subdirectories. + static void SetupCoverageStore(const base::FilePath& store_path); + private: // Starts CDP session on host. void Start(content::DevToolsAgentHost* host);
diff --git a/chrome/browser/chromeos/file_manager/devtools_listener_browsertest.cc b/chrome/browser/chromeos/file_manager/devtools_listener_browsertest.cc index 424beb58..6876f995 100644 --- a/chrome/browser/chromeos/file_manager/devtools_listener_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/devtools_listener_browsertest.cc
@@ -78,15 +78,7 @@ CHECK(tmp_dir_.CreateUniqueTempDir()); base::FilePath coverage_store = tmp_dir_.GetPath().AppendASCII("devtools_listener_browser_test"); - CHECK(base::CreateDirectory(coverage_store)); - - base::FilePath tests = coverage_store.AppendASCII("tests"); - if (!base::PathExists(tests)) - CHECK(base::CreateDirectory(tests)); - - base::FilePath scripts = coverage_store.AppendASCII("scripts"); - if (!base::PathExists(scripts)) - CHECK(base::CreateDirectory(scripts)); + DevToolsListener::SetupCoverageStore(coverage_store); for (auto& agent : devtools_agent_) { auto* host = agent.first;
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc index 65af8e0..ab61fde 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -1917,15 +1917,7 @@ base::FilePath store; CHECK(base::PathService::Get(base::DIR_EXE, &store)); store = store.AppendASCII("devtools_code_coverage"); - CHECK(base::CreateDirectory(store)); - - base::FilePath tests = store.AppendASCII("tests"); - if (!base::PathExists(tests)) - CHECK(base::CreateDirectory(tests)); - - base::FilePath scripts = store.AppendASCII("scripts"); - if (!base::PathExists(scripts)) - CHECK(base::CreateDirectory(scripts)); + DevToolsListener::SetupCoverageStore(store); for (auto& agent : devtools_agent_) { auto* host = agent.first;
diff --git a/chrome/browser/chromeos/login/encryption_migration_browsertest.cc b/chrome/browser/chromeos/login/encryption_migration_browsertest.cc index 8eaca24f..35f2e9c 100644 --- a/chrome/browser/chromeos/login/encryption_migration_browsertest.cc +++ b/chrome/browser/chromeos/login/encryption_migration_browsertest.cc
@@ -8,8 +8,6 @@ #include "base/command_line.h" #include "base/optional.h" #include "base/strings/string_piece.h" -#include "base/test/simple_test_tick_clock.h" -#include "base/time/time.h" #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h" #include "chrome/browser/chromeos/login/login_wizard.h" #include "chrome/browser/chromeos/login/oobe_screen.h" @@ -32,6 +30,7 @@ #include "chromeos/login/auth/stub_authenticator_builder.h" #include "chromeos/login/auth/user_context.h" #include "components/account_id/account_id.h" +#include "components/user_manager/known_user.h" #include "content/public/test/browser_test.h" #include "third_party/cros_system_api/dbus/cryptohome/dbus-constants.h" @@ -83,7 +82,6 @@ // Configure encryption migration screen for test. EncryptionMigrationScreen* screen = EncryptionMigrationScreen::Get( WizardController::default_controller()->screen_manager()); - screen->set_tick_clock_for_testing(&tick_clock_); screen->set_free_disk_space_fetcher_for_testing(base::BindRepeating( &EncryptionMigrationTest::GetFreeSpace, base::Unretained(this))); } @@ -108,12 +106,10 @@ test_user_.account_id); } - void SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction action) { - std::unique_ptr<ScopedUserPolicyUpdate> updater = - user_policy_mixin_.RequestPolicyUpdate(); - updater->policy_payload()->mutable_ecryptfsmigrationstrategy()->set_value( - static_cast<int>(action)); + void MarkUserHasEnterprisePolicy() { + user_manager::known_user::SetProfileRequiresPolicy( + test_user_.account_id, + user_manager::known_user::ProfileRequiresPolicy::kPolicyRequired); } // Runs a successful full migration flow, and tests that UI is updated as @@ -169,8 +165,6 @@ void set_free_space(int64_t free_space) { free_space_ = free_space; } - void AdvanceTime(base::TimeDelta delta) { tick_clock_.Advance(delta); } - private: int64_t GetFreeSpace() const { return free_space_; } @@ -178,8 +172,6 @@ // free space to an arbitrary amount above that limit. int64_t free_space_ = 200 * 1024 * 1024; - base::SimpleTestTickClock tick_clock_; - const LoginManagerMixin::TestUserInfo test_user_{ AccountId::FromUserEmailGaiaId("user@gmail.com", "user")}; LoginManagerMixin login_manager_{&mixin_host_, {test_user_}}; @@ -247,8 +239,7 @@ } IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, MigratePolicy) { - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMigrate); + MarkUserHasEnterprisePolicy(); SetUpStubAuthenticatorAndAttemptLogin(false /* has_incomplete_migration */); OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); @@ -259,183 +250,13 @@ IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, ResumeMigrationWithMigratePolicy) { - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMigrate); - + MarkUserHasEnterprisePolicy(); SetUpStubAuthenticatorAndAttemptLogin(true /* has_incomplete_migration */); OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); RunFullMigrationFlowTest(); } -// The "ask user" mode should be available to consumer users only - is set as a -// policy value, it should be treated the same as migrate. -IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, AskUserPolicy) { - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kAskUser); - - SetUpStubAuthenticatorAndAttemptLogin(false /* has_incomplete_migration */); - OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); - - // Verify that ready dialog is not shown, and that the migration started - // without ask user for confirmation. - test::OobeJS().CreateVisibilityWaiter(true, kMigratingDialog)->Wait(); - test::OobeJS().ExpectHiddenPath(kReadyDialog); - - EXPECT_EQ( - GetTestCryptohomeId(), - FakeCryptohomeClient::Get()->get_id_for_disk_migrated_to_dircrypto()); - EXPECT_FALSE(FakeCryptohomeClient::Get()->minimal_migration()); -} - -IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, MinimalMigration) { - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMinimalMigrate); - - SetUpStubAuthenticatorAndAttemptLogin(false /* has_incomplete_migration */); - OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); - - test::OobeJS().CreateVisibilityWaiter(true, kMinimalMigrationDialog)->Wait(); - - test::OobeJS().ExpectHiddenPath(kReadyDialog); - test::OobeJS().ExpectHiddenPath(kMigratingDialog); - test::OobeJS().ExpectHiddenPath(kErrorDialog); - test::OobeJS().ExpectHiddenPath(kInsufficientSpaceDialog); - - EXPECT_EQ(0, FakePowerManagerClient::Get()->num_request_restart_calls()); - - EXPECT_EQ( - GetTestCryptohomeId(), - FakeCryptohomeClient::Get()->get_id_for_disk_migrated_to_dircrypto()); - EXPECT_TRUE(FakeCryptohomeClient::Get()->minimal_migration()); - - // Simulate migration success - restart should be requested immediately after. - FakeCryptohomeClient::Get()->NotifyDircryptoMigrationProgress( - cryptohome::DIRCRYPTO_MIGRATION_SUCCESS, 5 /*current*/, 5 /*total*/); - EXPECT_EQ(0, FakePowerManagerClient::Get()->num_request_restart_calls()); - - WaitForActiveSession(); -} - -IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, MinimalMigrationWithTimeout) { - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMinimalMigrate); - - SetUpStubAuthenticatorAndAttemptLogin(false /* has_incomplete_migration */); - OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); - - test::OobeJS().CreateVisibilityWaiter(true, kMinimalMigrationDialog)->Wait(); - - test::OobeJS().ExpectHiddenPath(kReadyDialog); - test::OobeJS().ExpectHiddenPath(kMigratingDialog); - test::OobeJS().ExpectHiddenPath(kErrorDialog); - test::OobeJS().ExpectHiddenPath(kInsufficientSpaceDialog); - - EXPECT_EQ(0, FakePowerManagerClient::Get()->num_request_restart_calls()); - - EXPECT_EQ( - GetTestCryptohomeId(), - FakeCryptohomeClient::Get()->get_id_for_disk_migrated_to_dircrypto()); - EXPECT_TRUE(FakeCryptohomeClient::Get()->minimal_migration()); - - // Simulate time passage during migration - enough for the user to get asked - // to reauthenticate upon migration completion.. - AdvanceTime(base::TimeDelta::FromMinutes(3)); - - FakeCryptohomeClient::Get()->NotifyDircryptoMigrationProgress( - cryptohome::DIRCRYPTO_MIGRATION_SUCCESS, 5 /*current*/, 5 /*total*/); - EXPECT_EQ(0, FakePowerManagerClient::Get()->num_request_restart_calls()); - - OobeScreenWaiter(GetFirstSigninScreen()).Wait(); -} - -IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, - PRE_MinimalMigrationPolicyWithIncompleteFullMigration) { - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMigrate); - - SetUpStubAuthenticatorAndAttemptLogin(false /* has_incomplete_migration */); - OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); - - test::OobeJS() - .CreateWaiter(test::GetOobeElementPath(kMigratingDialog)) - ->Wait(); -} - -// Tests that attempted full migration is continued, even if the migration mode -// changes to minimal in mean time. -IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, - MinimalMigrationPolicyWithIncompleteFullMigration) { - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMinimalMigrate); - - SetUpStubAuthenticatorAndAttemptLogin(true /* has_incomplete_migration */); - OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); - - RunFullMigrationFlowTest(); -} - -IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, PRE_ResumeMinimalMigration) { - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMinimalMigrate); - - SetUpStubAuthenticatorAndAttemptLogin(false /* has_incomplete_migration */); - OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); - - test::OobeJS() - .CreateWaiter(test::GetOobeElementPath(kMinimalMigrationDialog)) - ->Wait(); -} - -IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, ResumeMinimalMigration) { - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMigrate); - - SetUpStubAuthenticatorAndAttemptLogin(true /* has_incomplete_migration */); - OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); - - test::OobeJS().CreateVisibilityWaiter(true, kMinimalMigrationDialog)->Wait(); - - EXPECT_EQ(0, FakePowerManagerClient::Get()->num_request_restart_calls()); - - EXPECT_EQ( - GetTestCryptohomeId(), - FakeCryptohomeClient::Get()->get_id_for_disk_migrated_to_dircrypto()); - EXPECT_TRUE(FakeCryptohomeClient::Get()->minimal_migration()); - - // Simulate migration success - restart should be requested immediately after. - FakeCryptohomeClient::Get()->NotifyDircryptoMigrationProgress( - cryptohome::DIRCRYPTO_MIGRATION_SUCCESS, 5 /*current*/, 5 /*total*/); - EXPECT_EQ(0, FakePowerManagerClient::Get()->num_request_restart_calls()); - - WaitForActiveSession(); -} - -IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, MigrationDisallowedByPolicy) { - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kDisallowMigration); - - SetUpStubAuthenticatorAndAttemptLogin(false /* has_incomplete_migration */); - WaitForActiveSession(); - EXPECT_FALSE(FakeCryptohomeClient::Get() - ->get_id_for_disk_migrated_to_dircrypto() - .has_account_id()); -} - -IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, WipeMigrationActionPolicy) { - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kWipe); - - SetUpStubAuthenticatorAndAttemptLogin(false /* has_incomplete_migration */); - - // Wipe is expected to wipe the cryptohome, and force online login. - OobeScreenWaiter(GetFirstSigninScreen()).Wait(); - - EXPECT_FALSE(FakeCryptohomeClient::Get() - ->get_id_for_disk_migrated_to_dircrypto() - .has_account_id()); -} - IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, InsufficientSpaceWithNoUserPolicy) { set_free_space(5 * 1000 * 1000); @@ -462,8 +283,7 @@ IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, MigrateWithInsuficientSpace) { set_free_space(5 * 1000 * 1000); - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMigrate); + MarkUserHasEnterprisePolicy(); SetUpStubAuthenticatorAndAttemptLogin(false /* has_incomplete_migration */); OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); @@ -488,8 +308,7 @@ IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, InsufficientSpaceOnResume) { set_free_space(5 * 1000 * 1000); - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMigrate); + MarkUserHasEnterprisePolicy(); SetUpStubAuthenticatorAndAttemptLogin(true /* has_incomplete_migration */); OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); @@ -513,8 +332,7 @@ } IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, MigrationFailure) { - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMigrate); + MarkUserHasEnterprisePolicy(); SetUpStubAuthenticatorAndAttemptLogin(false /* has_incomplete_migration */); OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); @@ -546,8 +364,7 @@ IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, LowBattery) { SetBatteryPercent(5); - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMigrate); + MarkUserHasEnterprisePolicy(); SetUpStubAuthenticatorAndAttemptLogin(false /* has_incomplete_migration */); OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); @@ -576,8 +393,7 @@ IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, CannotSkipWithLowBatteryOnMigrationResume) { SetBatteryPercent(5); - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMigrate); + MarkUserHasEnterprisePolicy(); SetUpStubAuthenticatorAndAttemptLogin(true /* has_incomplete_migration */); OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait(); @@ -600,8 +416,7 @@ IN_PROC_BROWSER_TEST_F(EncryptionMigrationTest, StartMigrationWhenEnoughBattery) { SetBatteryPercent(5); - SetUpEncryptionMigrationActionPolicy( - arc::policy_util::EcryptfsMigrationAction::kMigrate); + MarkUserHasEnterprisePolicy(); SetUpStubAuthenticatorAndAttemptLogin(false /* has_incomplete_migration */); OobeScreenWaiter(EncryptionMigrationScreenView::kScreenId).Wait();
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc index 25c644e..dd0499c0 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.cc +++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -34,7 +34,6 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h" #include "chrome/browser/chromeos/arc/arc_util.h" -#include "chrome/browser/chromeos/arc/policy/arc_policy_util.h" #include "chrome/browser/chromeos/authpolicy/authpolicy_helper.h" #include "chrome/browser/chromeos/boot_times_recorder.h" #include "chrome/browser/chromeos/customization/customization_document.h" @@ -44,6 +43,7 @@ #include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/login/quick_unlock/pin_storage_cryptohome.h" #include "chrome/browser/chromeos/login/reauth_stats.h" +#include "chrome/browser/chromeos/login/screens/encryption_migration_mode.h" #include "chrome/browser/chromeos/login/screens/encryption_migration_screen.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/login/signin/oauth2_token_initializer.h" @@ -52,7 +52,6 @@ #include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/ui/user_adding_screen.h" #include "chrome/browser/chromeos/login/user_flow.h" -#include "chrome/browser/chromeos/login/users/affiliation.h" #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" @@ -97,7 +96,6 @@ #include "components/arc/arc_util.h" #include "components/arc/enterprise/arc_data_snapshotd_manager.h" #include "components/google/core/common/google_util.h" -#include "components/policy/core/common/cloud/cloud_policy_client.h" #include "components/policy/core/common/cloud/cloud_policy_core.h" #include "components/policy/core/common/cloud/cloud_policy_store.h" #include "components/policy/core/common/cloud/device_management_service.h" @@ -120,7 +118,6 @@ #include "content/public/browser/storage_partition.h" #include "google_apis/gaia/gaia_auth_util.h" #include "google_apis/gaia/google_service_auth_error.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/mojom/network_context.mojom.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/l10n/l10n_util.h" @@ -128,12 +125,9 @@ #include "ui/message_center/public/cpp/notification_delegate.h" #include "ui/views/widget/widget.h" -using PolicyFetchResult = policy::PreSigninPolicyFetcher::PolicyFetchResult; using RebootOnSignOutPolicy = enterprise_management::DeviceRebootOnUserSignoutProto; -namespace apu = arc::policy_util; - namespace chromeos { namespace { @@ -276,40 +270,6 @@ return true; } -// Decides which EcryptfsMigrationAction should be used based on policy fetch -// result, policy payload and user type. `policy_payload` is only dereferenced -// if `policy_fetch_result` is PolicyFetchResult::SUCCESS. -apu::EcryptfsMigrationAction GetEcryptfsMigrationAction( - PolicyFetchResult policy_fetch_result, - enterprise_management::CloudPolicySettings* policy_payload) { - if (IsTestingMigrationUI()) - return apu::EcryptfsMigrationAction::kAskUser; - - switch (policy_fetch_result) { - case PolicyFetchResult::NO_POLICY: - // There was no policy, the user is unmanaged. They get to choose - // themselves if they'd like to migrate. - VLOG(1) << "Policy pre-fetch result: No user policy present"; - return apu::EcryptfsMigrationAction::kAskUser; - case PolicyFetchResult::SUCCESS: { - // User policy was retreived, adhere to it if it contains the - // EcryptfsMigrationStrategy policy value. - VLOG(1) << "Policy pre-fetch result: User policy fetched"; - base::Optional<apu::EcryptfsMigrationAction> action = - apu::DecodeMigrationActionFromPolicy(*policy_payload); - if (action) - return action.value(); - break; - } - case PolicyFetchResult::ERROR: - // We don't know if the user has policy or not. Stay on the safe side - // and stick to the default for this user type. - VLOG(1) << "Policy pre-fetch: User policy could not be fetched."; - break; - } - return apu::EcryptfsMigrationAction::kDisallowMigration; -} - // Returns true if the device is enrolled to an Active Directory domain // according to InstallAttributes (proxied through BrowserPolicyConnector). bool IsActiveDirectoryManaged() { @@ -347,6 +307,33 @@ return offline_signin_limit - (now - last_online_signin); } +base::Optional<EncryptionMigrationMode> GetEncryptionMigrationMode( + const UserContext& user_context, + bool has_incomplete_migration) { + if (has_incomplete_migration) { + // If migration was incomplete, continue migration automatically. + return EncryptionMigrationMode::RESUME_MIGRATION; + } + + if (user_context.GetUserType() == user_manager::USER_TYPE_CHILD) { + // TODO(https://crbug.com/1147009): Remove child user special case or + // implement finch experiment for child user migration mode. + return base::nullopt; + } + + const bool profile_has_policy = + user_manager::known_user::GetProfileRequiresPolicy( + user_context.GetAccountId()) == + user_manager::known_user::ProfileRequiresPolicy::kPolicyRequired || + base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kProfileRequiresPolicy); + + // Force-migrate all home directories if the user is known to have enterprise + // policy, otherwise ask the user. + return profile_has_policy ? EncryptionMigrationMode::START_MIGRATION + : EncryptionMigrationMode::ASK_USER; +} + // Returns account ID of a public session account if it is unique, otherwise // returns invalid account ID. AccountId GetArcDataSnapshotAutoLoginAccountId( @@ -1266,132 +1253,15 @@ void ExistingUserController::OnOldEncryptionDetected( const UserContext& user_context, bool has_incomplete_migration) { - if (has_incomplete_migration) { - // If migration was incomplete, continue migration without checking user - // policy. - // If the last attempted migration was a minimal migration, try to resume - // minimal migration. - const EncryptionMigrationMode mode = - user_manager::known_user::WasUserHomeMinimalMigrationAttempted( - user_context.GetAccountId()) - ? EncryptionMigrationMode::RESUME_MINIMAL_MIGRATION - : EncryptionMigrationMode::RESUME_MIGRATION; - ShowEncryptionMigrationScreen(user_context, mode); + base::Optional<EncryptionMigrationMode> encryption_migration_mode = + GetEncryptionMigrationMode(user_context, has_incomplete_migration); + if (!encryption_migration_mode.has_value()) { + ContinuePerformLoginWithoutMigration(login_performer_->auth_mode(), + user_context); return; } - - if (user_context.GetUserType() == user_manager::USER_TYPE_ARC_KIOSK_APP) { - // For ARC kiosk, don't check user policy. - ShowEncryptionMigrationScreen(user_context, - EncryptionMigrationMode::START_MIGRATION); - return; - } - - // Fetch user policy. - policy::DeviceManagementService* const device_management_service = - g_browser_process->platform_part() - ->browser_policy_connector_chromeos() - ->device_management_service(); - // Use signin profile URL loader factory - scoped_refptr<network::SharedURLLoaderFactory> - sigin_profile_url_loader_factory = - content::BrowserContext::GetDefaultStoragePartition( - ProfileHelper::GetSigninProfile()) - ->GetURLLoaderFactoryForBrowserProcess(); - - auto cloud_policy_client = std::make_unique<policy::CloudPolicyClient>( - device_management_service, sigin_profile_url_loader_factory, - chromeos::GetDeviceDMTokenForUserPolicyGetter( - user_context.GetAccountId())); - pre_signin_policy_fetcher_ = std::make_unique<policy::PreSigninPolicyFetcher>( - CryptohomeClient::Get(), SessionManagerClient::Get(), - std::move(cloud_policy_client), IsActiveDirectoryManaged(), - user_context.GetAccountId(), - cryptohome::KeyDefinition::CreateForPassword( - user_context.GetKey()->GetSecret(), std::string(), - cryptohome::PRIV_DEFAULT)); - pre_signin_policy_fetcher_->FetchPolicy( - base::BindOnce(&ExistingUserController::OnPolicyFetchResult, - weak_factory_.GetWeakPtr(), user_context)); -} - -void ExistingUserController::OnPolicyFetchResult( - const UserContext& user_context, - PolicyFetchResult policy_fetch_result, - std::unique_ptr<enterprise_management::CloudPolicySettings> - policy_payload) { - const apu::EcryptfsMigrationAction action = - GetEcryptfsMigrationAction(policy_fetch_result, policy_payload.get()); - VLOG(1) << "Migration action: " << static_cast<int>(action); - - switch (action) { - case apu::EcryptfsMigrationAction::kDisallowMigration: - ContinuePerformLoginWithoutMigration(login_performer_->auth_mode(), - user_context); - break; - - case apu::EcryptfsMigrationAction::kAskForEcryptfsArcUsersNoLongerSupported: - NOTREACHED(); - FALLTHROUGH; - - case apu::EcryptfsMigrationAction::kMigrate: - user_manager::known_user::SetUserHomeMinimalMigrationAttempted( - user_context.GetAccountId(), false); - user_manager::UserManager::Get()->GetLocalState()->CommitPendingWrite( - base::BindOnce(&ExistingUserController::ShowEncryptionMigrationScreen, - weak_factory_.GetWeakPtr(), user_context, - EncryptionMigrationMode::START_MIGRATION)); - break; - - case apu::EcryptfsMigrationAction::kAskUser: - user_manager::known_user::SetUserHomeMinimalMigrationAttempted( - user_context.GetAccountId(), false); - user_manager::UserManager::Get()->GetLocalState()->CommitPendingWrite( - base::BindOnce(&ExistingUserController::ShowEncryptionMigrationScreen, - weak_factory_.GetWeakPtr(), user_context, - EncryptionMigrationMode::ASK_USER)); - break; - - case apu::EcryptfsMigrationAction::kWipe: { - cryptohome::AccountIdentifier account_identifier; - account_identifier.set_account_id( - cryptohome::Identification(user_context.GetAccountId()).id()); - - CryptohomeClient::Get()->RemoveEx( - account_identifier, - base::BindOnce(&ExistingUserController::WipePerformed, - weak_factory_.GetWeakPtr(), user_context)); - - break; - } - - case apu::EcryptfsMigrationAction::kMinimalMigrate: - user_manager::known_user::SetUserHomeMinimalMigrationAttempted( - user_context.GetAccountId(), true); - user_manager::UserManager::Get()->GetLocalState()->CommitPendingWrite( - base::BindOnce(&ExistingUserController::ShowEncryptionMigrationScreen, - weak_factory_.GetWeakPtr(), user_context, - EncryptionMigrationMode::START_MINIMAL_MIGRATION)); - break; - } -} - -void ExistingUserController::WipePerformed( - const UserContext& user_context, - base::Optional<cryptohome::BaseReply> reply) { - const cryptohome::MountError error = BaseReplyToMountError(reply); - if (error != cryptohome::MOUNT_ERROR_NONE) { - LOG(ERROR) << "Removal of cryptohome for " - << user_context.GetAccountId().Serialize() - << " failed, return code: " - << BaseReplyToMountError(reply.value()); - } - - // Let the user authenticate online because we lose the OAuth token by - // removing the user's cryptohome. Without this, the user can sign-in offline - // but after sign-in would immediately see the "sign-in details are out of - // date" error message and be prompted to sign out. - ForceOnlineLoginForAccountId(user_context.GetAccountId()); + ShowEncryptionMigrationScreen(user_context, + encryption_migration_mode.value()); } void ExistingUserController::ForceOnlineLoginForAccountId(
diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h index 0a90d08d..dfa81c7 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.h +++ b/chrome/browser/chromeos/login/existing_user_controller.h
@@ -27,7 +27,6 @@ #include "chrome/browser/chromeos/login/screens/encryption_migration_mode.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/login/ui/login_display.h" -#include "chrome/browser/chromeos/policy/pre_signin_policy_fetcher.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" #include "chromeos/login/auth/login_performer.h" @@ -48,10 +47,6 @@ class ListValue; } -namespace enterprise_management { -class CloudPolicySettings; -} - namespace chromeos { class CrosSettings; @@ -304,18 +299,6 @@ // Callback invoked when `oauth2_token_initializer_` has finished. void OnOAuth2TokensFetched(bool success, const UserContext& user_context); - // Called on completition of a pre-signin policy fetch, which is performed to - // check if there is a user policy governing migration action. - void OnPolicyFetchResult( - const UserContext& user_context, - policy::PreSigninPolicyFetcher::PolicyFetchResult result, - std::unique_ptr<enterprise_management::CloudPolicySettings> - policy_payload); - - // Called when cryptohome wipe has finished. - void WipePerformed(const UserContext& user_context, - base::Optional<cryptohome::BaseReply> reply); - // Triggers online login for the given `account_id`. void ForceOnlineLoginForAccountId(const AccountId& account_id); @@ -420,8 +403,6 @@ std::unique_ptr<OAuth2TokenInitializer> oauth2_token_initializer_; - std::unique_ptr<policy::PreSigninPolicyFetcher> pre_signin_policy_fetcher_; - // Used to wait for cloud policy store load during public session login, if // the store is not yet initialized when the login is attempted. std::unique_ptr<PolicyStoreLoadWaiter> policy_store_waiter_;
diff --git a/chrome/browser/chromeos/login/password_change_browsertest.cc b/chrome/browser/chromeos/login/password_change_browsertest.cc index d172727..f5d4f9ba 100644 --- a/chrome/browser/chromeos/login/password_change_browsertest.cc +++ b/chrome/browser/chromeos/login/password_change_browsertest.cc
@@ -83,7 +83,7 @@ // Sets up UserSessionManager to use stub authenticator that reports a // password change, and attempts login. // Password changed OOBE dialog is expected to show up after calling this. - void SetUpStubAuthentcatorAndAttemptLogin(const std::string& old_password) { + void SetUpStubAuthenticatorAndAttemptLogin(const std::string& old_password) { EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible()); UserContext user_context = GetTestUserContext(); @@ -132,7 +132,7 @@ OpenGaiaDialog(test_account_id_); base::HistogramTester histogram_tester; - SetUpStubAuthentcatorAndAttemptLogin("old user password"); + SetUpStubAuthenticatorAndAttemptLogin("old user password"); WaitForPasswordChangeScreen(); histogram_tester.ExpectBucketCount("Login.PasswordChanged.ReauthReason", ReauthReason::OTHER, 1); @@ -153,7 +153,7 @@ IN_PROC_BROWSER_TEST_F(PasswordChangeTest, RetryOnWrongPassword) { OpenGaiaDialog(test_account_id_); - SetUpStubAuthentcatorAndAttemptLogin("old user password"); + SetUpStubAuthenticatorAndAttemptLogin("old user password"); WaitForPasswordChangeScreen(); test::OobeJS().CreateVisibilityWaiter(true, kPasswordStep)->Wait(); @@ -185,7 +185,7 @@ IN_PROC_BROWSER_TEST_F(PasswordChangeTest, SkipDataRecovery) { OpenGaiaDialog(test_account_id_); - SetUpStubAuthentcatorAndAttemptLogin("old user password"); + SetUpStubAuthenticatorAndAttemptLogin("old user password"); WaitForPasswordChangeScreen(); test::OobeJS().CreateVisibilityWaiter(true, kPasswordStep)->Wait(); @@ -210,7 +210,7 @@ IN_PROC_BROWSER_TEST_F(PasswordChangeTest, TryAgainAfterForgetLinkClick) { OpenGaiaDialog(test_account_id_); - SetUpStubAuthentcatorAndAttemptLogin("old user password"); + SetUpStubAuthenticatorAndAttemptLogin("old user password"); WaitForPasswordChangeScreen(); test::OobeJS().CreateDisplayedWaiter(true, kPasswordStep)->Wait(); @@ -241,7 +241,7 @@ IN_PROC_BROWSER_TEST_F(PasswordChangeTest, ClosePasswordChangedDialog) { OpenGaiaDialog(test_account_id_); - SetUpStubAuthentcatorAndAttemptLogin("old user password"); + SetUpStubAuthenticatorAndAttemptLogin("old user password"); WaitForPasswordChangeScreen(); test::OobeJS().CreateVisibilityWaiter(true, kPasswordStep)->Wait(); @@ -297,7 +297,7 @@ OpenGaiaDialog(user_with_invalid_token_); base::HistogramTester histogram_tester; - SetUpStubAuthentcatorAndAttemptLogin("old user password"); + SetUpStubAuthenticatorAndAttemptLogin("old user password"); WaitForPasswordChangeScreen(); histogram_tester.ExpectBucketCount("Login.PasswordChanged.ReauthReason", ReauthReason::INVALID_TOKEN_HANDLE, 1); @@ -383,7 +383,7 @@ OpenGaiaDialog(user_with_invalid_token_); base::HistogramTester histogram_tester; - SetUpStubAuthentcatorAndAttemptLogin("old user password"); + SetUpStubAuthenticatorAndAttemptLogin("old user password"); WaitForPasswordChangeScreen(); histogram_tester.ExpectBucketCount("Login.PasswordChanged.ReauthReason", ReauthReason::INVALID_TOKEN_HANDLE, 1);
diff --git a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc index c94e188..cb1fe897 100644 --- a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc +++ b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
@@ -22,14 +22,12 @@ #include "base/strings/string_util.h" #include "base/values.h" #include "chrome/browser/chromeos/accessibility/magnifier_type.h" -#include "chrome/browser/chromeos/arc/policy/arc_policy_util.h" #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" #include "chrome/common/pref_names.h" #include "chromeos/dbus/power/power_policy_controller.h" #include "chromeos/network/onc/onc_signature.h" #include "chromeos/network/onc/onc_utils.h" #include "chromeos/network/onc/onc_validator.h" -#include "components/arc/arc_prefs.h" #include "components/crx_file/id_util.h" #include "components/onc/onc_constants.h" #include "components/onc/onc_pref_names.h" @@ -43,8 +41,6 @@ #include "crypto/sha2.h" #include "url/gurl.h" -namespace apu = arc::policy_util; - namespace policy { namespace { @@ -556,32 +552,4 @@ } } -EcryptfsMigrationStrategyPolicyHandler::EcryptfsMigrationStrategyPolicyHandler() - : IntRangePolicyHandlerBase( - key::kEcryptfsMigrationStrategy, - static_cast<int>(apu::EcryptfsMigrationAction::kDisallowMigration), - static_cast<int>(apu::EcryptfsMigrationAction:: - kAskForEcryptfsArcUsersNoLongerSupported), - false /* clamp */) {} - -void EcryptfsMigrationStrategyPolicyHandler::ApplyPolicySettings( - const PolicyMap& policies, - PrefValueMap* prefs) { - const base::Value* const value = policies.GetValue(policy_name()); - if (!value || !EnsureInRange(value, nullptr, nullptr)) { - return; - } - if (value->GetInt() == - static_cast<int>(apu::EcryptfsMigrationAction::kAskUser) || - value->GetInt() == - static_cast<int>(apu::EcryptfsMigrationAction:: - kAskForEcryptfsArcUsersNoLongerSupported)) { - // Alias obsolete values to apu::kMigrate. - prefs->SetInteger(arc::prefs::kEcryptfsMigrationStrategy, - static_cast<int>(apu::EcryptfsMigrationAction::kMigrate)); - } else { - prefs->SetValue(arc::prefs::kEcryptfsMigrationStrategy, value->Clone()); - } -} - } // namespace policy
diff --git a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.h b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.h index d0059ef..75cc924 100644 --- a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.h +++ b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.h
@@ -211,21 +211,6 @@ DISALLOW_COPY_AND_ASSIGN(ArcServicePolicyHandler); }; -// Handles the |EcryptfsMigrationStrategy| policy, aliasing policy values that -// are no longer supported to the "migrate" option. -class EcryptfsMigrationStrategyPolicyHandler - : public IntRangePolicyHandlerBase { - public: - EcryptfsMigrationStrategyPolicyHandler(); - - // IntRangePolicyHandlerBase: - void ApplyPolicySettings(const PolicyMap& policies, - PrefValueMap* prefs) override; - - private: - DISALLOW_COPY_AND_ASSIGN(EcryptfsMigrationStrategyPolicyHandler); -}; - } // namespace policy #endif // CHROME_BROWSER_CHROMEOS_POLICY_CONFIGURATION_POLICY_HANDLER_CHROMEOS_H_
diff --git a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc index e2a7410..bdbd953e 100644 --- a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc +++ b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc
@@ -12,7 +12,6 @@ #include "base/json/json_reader.h" #include "base/macros.h" #include "base/values.h" -#include "chrome/browser/chromeos/arc/policy/arc_policy_util.h" #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" #include "chrome/common/pref_names.h" #include "components/arc/arc_prefs.h" @@ -25,8 +24,6 @@ #include "components/prefs/pref_value_map.h" #include "testing/gtest/include/gtest/gtest.h" -namespace apu = arc::policy_util; - namespace policy { namespace { @@ -500,107 +497,4 @@ EXPECT_FALSE(prefs.GetValue(arc::prefs::kArcBackupRestoreEnabled, &enabled)); } -TEST(EcryptfsMigrationStrategyPolicyHandlerTest, Empty) { - PolicyMap policy_map; - EcryptfsMigrationStrategyPolicyHandler handler; - PolicyErrorMap errors; - EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); - EXPECT_TRUE(errors.GetErrors(key::kEcryptfsMigrationStrategy).empty()); -} - -TEST(EcryptfsMigrationStrategyPolicyHandlerTest, ValidPolicy) { - PolicyMap policy_map; - policy_map.Set( - key::kEcryptfsMigrationStrategy, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - base::Value(static_cast<int>(apu::EcryptfsMigrationAction::kMigrate)), - nullptr); - EcryptfsMigrationStrategyPolicyHandler handler; - PolicyErrorMap errors; - EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); - EXPECT_TRUE(errors.GetErrors(key::kEcryptfsMigrationStrategy).empty()); -} - -TEST(EcryptfsMigrationStrategyPolicyHandlerTest, WrongType) { - PolicyMap policy_map; - policy_map.Set(key::kEcryptfsMigrationStrategy, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(false), - nullptr); - EcryptfsMigrationStrategyPolicyHandler handler; - PolicyErrorMap errors; - EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors)); - EXPECT_FALSE(errors.GetErrors(key::kEcryptfsMigrationStrategy).empty()); -} - -TEST(EcryptfsMigrationStrategyPolicyHandlerTest, OutOfRange) { - PolicyMap policy_map; - policy_map.Set(key::kEcryptfsMigrationStrategy, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(6), - nullptr); - EcryptfsMigrationStrategyPolicyHandler handler; - PolicyErrorMap errors; - EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors)); - EXPECT_FALSE(errors.GetErrors(key::kEcryptfsMigrationStrategy).empty()); -} - -TEST(EcryptfsMigrationStrategyPolicyHandlerTest, SupportedValue) { - // Values of the EcryptfsMigrationStrategy policy to be tested. - std::vector<base::Value> test_policy_values; - test_policy_values.emplace_back( - static_cast<int>(apu::EcryptfsMigrationAction::kDisallowMigration)); - test_policy_values.emplace_back( - static_cast<int>(apu::EcryptfsMigrationAction::kMigrate)); - test_policy_values.emplace_back( - static_cast<int>(apu::EcryptfsMigrationAction::kWipe)); - test_policy_values.emplace_back( - static_cast<int>(apu::EcryptfsMigrationAction::kMinimalMigrate)); - - PolicyMap policy_map; - EcryptfsMigrationStrategyPolicyHandler handler; - PolicyErrorMap errors; - PrefValueMap prefs; - for (const auto& test_policy_value : test_policy_values) { - policy_map.Set(key::kEcryptfsMigrationStrategy, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - test_policy_value.Clone(), nullptr); - ASSERT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); - EXPECT_TRUE(errors.empty()); - handler.ApplyPolicySettings(policy_map, &prefs); - const base::Value* strategy = nullptr; - EXPECT_TRUE( - prefs.GetValue(arc::prefs::kEcryptfsMigrationStrategy, &strategy)); - ASSERT_TRUE(strategy); - EXPECT_EQ(test_policy_value, *strategy); - } -} - -TEST(EcryptfsMigrationStrategyPolicyHandlerTest, ObsoleteValue) { - // Values of the EcryptfsMigrationStrategy policy to be tested. - std::vector<base::Value> test_policy_values; - test_policy_values.emplace_back( - static_cast<int>(apu::EcryptfsMigrationAction::kAskUser)); - test_policy_values.emplace_back(static_cast<int>( - apu::EcryptfsMigrationAction::kAskForEcryptfsArcUsersNoLongerSupported)); - - PolicyMap policy_map; - EcryptfsMigrationStrategyPolicyHandler handler; - PolicyErrorMap errors; - PrefValueMap prefs; - for (const auto& test_policy_value : test_policy_values) { - policy_map.Set(key::kEcryptfsMigrationStrategy, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - test_policy_value.Clone(), nullptr); - ASSERT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); - EXPECT_TRUE(errors.empty()); - handler.ApplyPolicySettings(policy_map, &prefs); - const base::Value* strategy = nullptr; - EXPECT_TRUE( - prefs.GetValue(arc::prefs::kEcryptfsMigrationStrategy, &strategy)); - ASSERT_TRUE(strategy); - EXPECT_EQ( - base::Value(static_cast<int>(apu::EcryptfsMigrationAction::kMigrate)), - *strategy); - } -} - } // namespace policy
diff --git a/chrome/browser/chromeos/policy/extension_install_event_log_collector.cc b/chrome/browser/chromeos/policy/extension_install_event_log_collector.cc index 61adf3f..1b99049f 100644 --- a/chrome/browser/chromeos/policy/extension_install_event_log_collector.cc +++ b/chrome/browser/chromeos/policy/extension_install_event_log_collector.cc
@@ -485,8 +485,24 @@ } } +void AddErrorCodesToFailureEvent( + const extensions::InstallStageTracker::InstallationData& data, + em::ExtensionInstallReportLogEvent* event) { + if (data.response_code) { + event->set_fetch_error_code(data.response_code.value()); + } else { + DCHECK(data.network_error_code); + event->set_fetch_error_code(data.network_error_code.value()); + } + + DCHECK(data.fetch_tries); + event->set_fetch_tries(data.fetch_tries.value_or(0)); +} + } // namespace +using FailureReason = extensions::InstallStageTracker::FailureReason; + ExtensionInstallEventLogCollector::ExtensionInstallEventLogCollector( extensions::ExtensionRegistry* registry, Delegate* delegate, @@ -564,7 +580,7 @@ void ExtensionInstallEventLogCollector::OnExtensionInstallationFailed( const extensions::ExtensionId& extension_id, - extensions::InstallStageTracker::FailureReason reason) { + FailureReason reason) { if (!delegate_->IsExtensionPending(extension_id)) return; auto event = std::make_unique<em::ExtensionInstallReportLogEvent>(); @@ -598,6 +614,12 @@ event->set_crx_install_error_detail( ConvertCrxInstallErrorDetailToProto(data.install_error_detail.value())); } + + if (reason == FailureReason::CRX_FETCH_FAILED || + reason == FailureReason::MANIFEST_FETCH_FAILED) { + AddErrorCodesToFailureEvent(data, event.get()); + } + extensions::ForceInstalledTracker* force_installed_tracker = extensions::ExtensionSystem::Get(profile_) ->extension_service()
diff --git a/chrome/browser/chromeos/policy/extension_install_event_log_collector_unittest.cc b/chrome/browser/chromeos/policy/extension_install_event_log_collector_unittest.cc index 12759bd4..99bb9f43 100644 --- a/chrome/browser/chromeos/policy/extension_install_event_log_collector_unittest.cc +++ b/chrome/browser/chromeos/policy/extension_install_event_log_collector_unittest.cc
@@ -28,6 +28,7 @@ #include "content/public/test/browser_task_environment.h" #include "extensions/browser/extension_system.h" #include "extensions/common/extension_builder.h" +#include "net/base/net_errors.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/cros_system_api/dbus/service_constants.h" @@ -47,6 +48,10 @@ constexpr char kEmailId[] = "test@example.com"; constexpr char kGaiaId[] = "12345"; +const int kFetchTries = 5; +// HTTP_UNAUTHORIZED +const int kResponseCode = 401; + class FakeExtensionInstallEventLogCollectorDelegate : public ExtensionInstallEventLogCollector::Delegate { public: @@ -555,6 +560,59 @@ delegate()->last_request().event.manifest_invalid_error()); } +// Verifies that a new event with error codes and number of fetch tries is +// created when the extension failed with error MANFIEST_FETCH_FAILED. +TEST_F(ExtensionInstallEventLogCollectorTest, + ExtensionInstallFailedWithManifestFetchFailed) { + auto collector = std::make_unique<ExtensionInstallEventLogCollector>( + registry(), delegate(), profile()); + + extensions::InstallStageTracker* tracker = + extensions::InstallStageTracker::Get(profile()); + + // One extension failed. + extensions::ExtensionDownloaderDelegate::FailureData data( + net::Error::OK, kResponseCode, kFetchTries); + tracker->ReportFetchError( + kExtensionId1, + extensions::InstallStageTracker::FailureReason::MANIFEST_FETCH_FAILED, + data); + ASSERT_TRUE(VerifyEventAddedSuccessfully(1 /*expected_add_count*/, + 0 /*expected_add_all_count*/)); + EXPECT_EQ(em::ExtensionInstallReportLogEvent::INSTALLATION_FAILED, + delegate()->last_request().event.event_type()); + EXPECT_EQ(em::ExtensionInstallReportLogEvent::MANIFEST_FETCH_FAILED, + delegate()->last_request().event.failure_reason()); + EXPECT_EQ(kResponseCode, delegate()->last_request().event.fetch_error_code()); + EXPECT_EQ(kFetchTries, delegate()->last_request().event.fetch_tries()); +} + +// Verifies that a new event with fetch error code and number of fetch tries is +// created when the extension failed with error CRX_FETCH_FAILED. +TEST_F(ExtensionInstallEventLogCollectorTest, + ExtensionInstallFailedWithCrxFetchFailed) { + auto collector = std::make_unique<ExtensionInstallEventLogCollector>( + registry(), delegate(), profile()); + + extensions::InstallStageTracker* tracker = + extensions::InstallStageTracker::Get(profile()); + + // One extension failed. + extensions::ExtensionDownloaderDelegate::FailureData data( + net::Error::OK, kResponseCode, kFetchTries); + tracker->ReportFetchError( + kExtensionId1, + extensions::InstallStageTracker::FailureReason::CRX_FETCH_FAILED, data); + ASSERT_TRUE(VerifyEventAddedSuccessfully(1 /*expected_add_count*/, + 0 /*expected_add_all_count*/)); + EXPECT_EQ(em::ExtensionInstallReportLogEvent::INSTALLATION_FAILED, + delegate()->last_request().event.event_type()); + EXPECT_EQ(em::ExtensionInstallReportLogEvent::CRX_FETCH_FAILED, + delegate()->last_request().event.failure_reason()); + EXPECT_EQ(kResponseCode, delegate()->last_request().event.fetch_error_code()); + EXPECT_EQ(kFetchTries, delegate()->last_request().event.fetch_tries()); +} + // Verifies that a new event is created when an extension is successfully // installed. TEST_F(ExtensionInstallEventLogCollectorTest, InstallExtension) {
diff --git a/chrome/browser/chromeos/policy/install_event_log_util.cc b/chrome/browser/chromeos/policy/install_event_log_util.cc index 864542a..d765b82d 100644 --- a/chrome/browser/chromeos/policy/install_event_log_util.cc +++ b/chrome/browser/chromeos/policy/install_event_log_util.cc
@@ -53,6 +53,8 @@ constexpr char kUnpackerFailureReason[] = "unpackerFailureReason"; constexpr char kManifestInvalidError[] = "manifestInvalidError"; constexpr char kCrxInstallErrorDetail[] = "crxInstallErrorDetail"; +constexpr char kFetchErrorCode[] = "fetchErrorCode"; +constexpr char kFetchTries[] = "fetchTries"; // Calculates hash for the given |event| and |context|, and stores the hash in // |hash|. Returns true if |event| and |context| are json serializable and @@ -229,6 +231,16 @@ extension_install_report_log_event.manifest_invalid_error()); } + if (extension_install_report_log_event.has_fetch_error_code()) { + event.SetIntKey(kFetchErrorCode, + extension_install_report_log_event.fetch_error_code()); + } + + if (extension_install_report_log_event.has_fetch_tries()) { + event.SetIntKey(kFetchTries, + extension_install_report_log_event.fetch_tries()); + } + if (extension_install_report_log_event.has_crx_install_error_detail()) { event.SetIntKey( kCrxInstallErrorDetail,
diff --git a/chrome/browser/chromeos/policy/install_event_log_util_unittest.cc b/chrome/browser/chromeos/policy/install_event_log_util_unittest.cc index a5bb5da..d696332 100644 --- a/chrome/browser/chromeos/policy/install_event_log_util_unittest.cc +++ b/chrome/browser/chromeos/policy/install_event_log_util_unittest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/profiles/reporting_util.h" #include "chromeos/system/fake_statistics_provider.h" #include "components/policy/proto/device_management_backend.pb.h" +#include "net/base/net_errors.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,6 +26,10 @@ constexpr int64_t kDiskSpaceTotalBytes = 5 * 1024 * 1024; const int64_t kDiskSpaceFreeBytes = 2 * 1024 * 1024; +const int kExampleFetchTries = 5; +// HTTP_UNAUTHORIZED +const int kExampleResponseCode = 401; + // Common key names used when building the dictionary to pass to the Chrome // Reporting API. These must be same as ones mentioned in // install_event_log_util.cc. @@ -52,6 +57,8 @@ constexpr char kUnpackerFailureReason[] = "unpackerFailureReason"; constexpr char kManifestInvalidError[] = "manifestInvalidError"; constexpr char kCrxInstallErrorDetail[] = "crxInstallErrorDetail"; +constexpr char kFetchErrorCode[] = "fetchErrorCode"; +constexpr char kFetchTries[] = "fetchTries"; void ConvertToValueAndVerify(const em::ExtensionInstallReportLogEvent& event, const std::vector<std::string>& keys) { @@ -152,6 +159,22 @@ kStatefulTotal, kStatefulFree}); } +// Verifies that an event reporting error codes and number of fetch tries when +// extension failed to install with error MANIFEST_FETCH_FAILED is successfully +// parsed. +TEST_F(ExtensionInstallEventLogUtilTest, ManifestFetchFailedEvent) { + event_.set_event_type( + em::ExtensionInstallReportLogEvent::INSTALLATION_FAILED); + event_.set_failure_reason( + em::ExtensionInstallReportLogEvent::MANIFEST_FETCH_FAILED); + event_.set_fetch_error_code(kExampleResponseCode); + event_.set_fetch_tries(kExampleFetchTries); + event_.set_stateful_total(kDiskSpaceTotalBytes); + event_.set_stateful_free(kDiskSpaceFreeBytes); + ConvertToValueAndVerify(event_, {kEventType, kFailureReason, kFetchErrorCode, + kFetchTries, kStatefulTotal, kStatefulFree}); +} + // Verifies that an event reporting extension installation stage is successfully // parsed. TEST_F(ExtensionInstallEventLogUtilTest, InstallationStageEvent) {
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc index 793322c6..99702ed 100644 --- a/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc +++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc
@@ -499,7 +499,7 @@ kFakeBatteryModel, kFakeBatteryChargeNow, kFakeBatteryCurrentNow, kFakeBatteryTechnology, kFakeBatteryStatus, kFakeSmartBatteryManufactureDate, - cros_healthd::UInt64Value::New(kFakeSmartBatteryTemperature))); + cros_healthd::NullableUint64::New(kFakeSmartBatteryTemperature))); } cros_healthd::NonRemovableBlockDeviceResultPtr CreateBlockDeviceResult() { @@ -508,7 +508,7 @@ kFakeStorageBytesRead, kFakeStorageBytesWritten, kFakeStorageReadTimeSeconds, kFakeStorageWriteTimeSeconds, kFakeStorageIoTimeSeconds, - cros_healthd::UInt64Value::New(kFakeStorageDiscardTimeSeconds), + cros_healthd::NullableUint64::New(kFakeStorageDiscardTimeSeconds), cros_healthd::BlockDeviceVendor::NewEmmcOemid(kFakeOemid), cros_healthd::BlockDeviceProduct::NewEmmcPnm(kFakePnm), cros_healthd::BlockDeviceRevision::NewEmmcPrv(kFakePrv), kFakeStorageName, @@ -526,7 +526,7 @@ kFakeFirstPowerDate, kFakeManufactureDate, kFakeSkuNumber, kFakeSerialNumber, kFakeMarketingName, kFakeBiosVersion, kFakeBoardName, kFakeBoardVersion, - cros_healthd::UInt64Value::New(kFakeChassisType), kFakeProductName, + cros_healthd::NullableUint64::New(kFakeChassisType), kFakeProductName, cros_healthd::OsVersion::New( kFakeVersionMilestone, kFakeVersionBuildNumber, kFakeVersionPatchNumber, kFakeVersionReleaseChannel)));
diff --git a/chrome/browser/content_settings/content_settings_default_provider_unittest.cc b/chrome/browser/content_settings/content_settings_default_provider_unittest.cc index c7edbc0..b4c2e54 100644 --- a/chrome/browser/content_settings/content_settings_default_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_default_provider_unittest.cc
@@ -95,15 +95,15 @@ TEST_F(ContentSettingsDefaultProviderTest, Observer) { MockObserver mock_observer; EXPECT_CALL(mock_observer, - OnContentSettingChanged(_, _, ContentSettingsType::COOKIES, "")); + OnContentSettingChanged(_, _, ContentSettingsType::COOKIES)); provider_.AddObserver(&mock_observer); provider_.SetWebsiteSetting( ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(), ContentSettingsType::COOKIES, std::string(), std::make_unique<base::Value>(CONTENT_SETTING_BLOCK)); - EXPECT_CALL(mock_observer, OnContentSettingChanged( - _, _, ContentSettingsType::GEOLOCATION, "")); + EXPECT_CALL(mock_observer, + OnContentSettingChanged(_, _, ContentSettingsType::GEOLOCATION)); provider_.SetWebsiteSetting( ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(), ContentSettingsType::GEOLOCATION, std::string(),
diff --git a/chrome/browser/content_settings/content_settings_mock_observer.h b/chrome/browser/content_settings/content_settings_mock_observer.h index 060c1826..ea43403d 100644 --- a/chrome/browser/content_settings/content_settings_mock_observer.h +++ b/chrome/browser/content_settings/content_settings_mock_observer.h
@@ -18,11 +18,10 @@ MockObserver(); ~MockObserver() override; - MOCK_METHOD4(OnContentSettingChanged, + MOCK_METHOD3(OnContentSettingChanged, void(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier)); + ContentSettingsType content_type)); private: DISALLOW_COPY_AND_ASSIGN(MockObserver);
diff --git a/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc b/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc index a7ce69d..afbf6fee 100644 --- a/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc
@@ -97,7 +97,7 @@ MockObserver mock_observer; EXPECT_CALL(mock_observer, - OnContentSettingChanged(_, _, ContentSettingsType::DEFAULT, "")); + OnContentSettingChanged(_, _, ContentSettingsType::DEFAULT)); provider.AddObserver(&mock_observer); // Set the managed default-content-setting. @@ -105,7 +105,7 @@ std::make_unique<base::Value>(CONTENT_SETTING_BLOCK)); ::testing::Mock::VerifyAndClearExpectations(&mock_observer); EXPECT_CALL(mock_observer, - OnContentSettingChanged(_, _, ContentSettingsType::DEFAULT, "")); + OnContentSettingChanged(_, _, ContentSettingsType::DEFAULT)); // Remove the managed default-content-setting. prefs->RemoveManagedPref(prefs::kManagedDefaultCookiesSetting); provider.ShutdownOnUIThread();
diff --git a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc index 394c3fd..6c4cc4c 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
@@ -149,7 +149,7 @@ MockObserver mock_observer; EXPECT_CALL(mock_observer, OnContentSettingChanged( pattern, ContentSettingsPattern::Wildcard(), - ContentSettingsType::COOKIES, "")); + ContentSettingsType::COOKIES)); pref_content_settings_provider.AddObserver(&mock_observer);
diff --git a/chrome/browser/content_settings/content_settings_supervised_provider_unittest.cc b/chrome/browser/content_settings/content_settings_supervised_provider_unittest.cc index 3cc6941..64d6ea3b 100644 --- a/chrome/browser/content_settings/content_settings_supervised_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_supervised_provider_unittest.cc
@@ -56,8 +56,7 @@ // Disable the default geolocation setting. EXPECT_CALL(mock_observer_, - OnContentSettingChanged(_, _, ContentSettingsType::GEOLOCATION, - std::string())); + OnContentSettingChanged(_, _, ContentSettingsType::GEOLOCATION)); service_.SetLocalSetting(supervised_users::kGeolocationDisabled, std::make_unique<base::Value>(true)); @@ -73,8 +72,7 @@ // Re-enable the default geolocation setting. EXPECT_CALL(mock_observer_, - OnContentSettingChanged(_, _, ContentSettingsType::GEOLOCATION, - std::string())); + OnContentSettingChanged(_, _, ContentSettingsType::GEOLOCATION)); service_.SetLocalSetting(supervised_users::kGeolocationDisabled, std::make_unique<base::Value>(false)); @@ -90,8 +88,7 @@ // Allow cookies everywhere. EXPECT_CALL(mock_observer_, - OnContentSettingChanged(_, _, ContentSettingsType::COOKIES, - std::string())); + OnContentSettingChanged(_, _, ContentSettingsType::COOKIES)); service_.SetLocalSetting(supervised_users::kCookiesAlwaysAllowed, std::make_unique<base::Value>(true)); @@ -107,8 +104,7 @@ // Re-enable the default cookie setting. EXPECT_CALL(mock_observer_, - OnContentSettingChanged(_, _, ContentSettingsType::COOKIES, - std::string())); + OnContentSettingChanged(_, _, ContentSettingsType::COOKIES)); service_.SetLocalSetting(supervised_users::kCookiesAlwaysAllowed, std::make_unique<base::Value>(false)); @@ -126,12 +122,11 @@ EXPECT_FALSE(rule_iterator); // Disable the default camera and microphone setting. + EXPECT_CALL( + mock_observer_, + OnContentSettingChanged(_, _, ContentSettingsType::MEDIASTREAM_CAMERA)); EXPECT_CALL(mock_observer_, OnContentSettingChanged( - _, _, ContentSettingsType::MEDIASTREAM_CAMERA, - std::string())); - EXPECT_CALL(mock_observer_, - OnContentSettingChanged( - _, _, ContentSettingsType::MEDIASTREAM_MIC, std::string())); + _, _, ContentSettingsType::MEDIASTREAM_MIC)); service_.SetLocalSetting(supervised_users::kCameraMicDisabled, std::make_unique<base::Value>(true)); @@ -156,12 +151,11 @@ EXPECT_EQ(CONTENT_SETTING_BLOCK, ValueToContentSetting(&rule.value)); // Re-enable the default camera and microphone setting. + EXPECT_CALL( + mock_observer_, + OnContentSettingChanged(_, _, ContentSettingsType::MEDIASTREAM_CAMERA)); EXPECT_CALL(mock_observer_, OnContentSettingChanged( - _, _, ContentSettingsType::MEDIASTREAM_CAMERA, - std::string())); - EXPECT_CALL(mock_observer_, - OnContentSettingChanged( - _, _, ContentSettingsType::MEDIASTREAM_MIC, std::string())); + _, _, ContentSettingsType::MEDIASTREAM_MIC)); service_.SetLocalSetting(supervised_users::kCameraMicDisabled, std::make_unique<base::Value>(false));
diff --git a/chrome/browser/content_settings/generated_cookie_prefs.cc b/chrome/browser/content_settings/generated_cookie_prefs.cc index 9d33bc35..ca85a5d7 100644 --- a/chrome/browser/content_settings/generated_cookie_prefs.cc +++ b/chrome/browser/content_settings/generated_cookie_prefs.cc
@@ -98,8 +98,7 @@ void GeneratedCookiePrefBase::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { if (content_type == ContentSettingsType::COOKIES) { NotifyObservers(pref_name_); }
diff --git a/chrome/browser/content_settings/generated_cookie_prefs.h b/chrome/browser/content_settings/generated_cookie_prefs.h index 7b63e46..f0e8331 100644 --- a/chrome/browser/content_settings/generated_cookie_prefs.h +++ b/chrome/browser/content_settings/generated_cookie_prefs.h
@@ -38,8 +38,7 @@ void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; void OnCookiePreferencesChanged(); protected:
diff --git a/chrome/browser/content_settings/generated_notification_pref.cc b/chrome/browser/content_settings/generated_notification_pref.cc index 386896c..63c690b 100644 --- a/chrome/browser/content_settings/generated_notification_pref.cc +++ b/chrome/browser/content_settings/generated_notification_pref.cc
@@ -51,8 +51,7 @@ void GeneratedNotificationPref::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { if (content_type == ContentSettingsType::NOTIFICATIONS) { NotifyObservers(kGeneratedNotificationPref); }
diff --git a/chrome/browser/content_settings/generated_notification_pref.h b/chrome/browser/content_settings/generated_notification_pref.h index d65a8c2a..dff8bb8d 100644 --- a/chrome/browser/content_settings/generated_notification_pref.h +++ b/chrome/browser/content_settings/generated_notification_pref.h
@@ -44,8 +44,7 @@ void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; void OnNotificationPreferencesChanged();
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc index f8574987..c24ed82 100644 --- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc +++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -1337,7 +1337,7 @@ ContentSettingsPattern::FromString("[*.]example.com"); EXPECT_CALL(mock_observer, OnContentSettingChanged( pattern, ContentSettingsPattern::Wildcard(), - ContentSettingsType::COOKIES, "")); + ContentSettingsType::COOKIES)); host_content_settings_map->AddObserver(&mock_observer);
diff --git a/chrome/browser/content_settings/mock_settings_observer.cc b/chrome/browser/content_settings/mock_settings_observer.cc index ef0eb098..1666f07 100644 --- a/chrome/browser/content_settings/mock_settings_observer.cc +++ b/chrome/browser/content_settings/mock_settings_observer.cc
@@ -18,10 +18,9 @@ void MockSettingsObserver::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { - const ContentSettingsDetails details( - primary_pattern, secondary_pattern, content_type, resource_identifier); + ContentSettingsType content_type) { + const ContentSettingsDetails details(primary_pattern, secondary_pattern, + content_type, std::string()); OnContentSettingsChanged(map_, details.type(), details.update_all_types(),
diff --git a/chrome/browser/content_settings/mock_settings_observer.h b/chrome/browser/content_settings/mock_settings_observer.h index dfd3172..68b82c85 100644 --- a/chrome/browser/content_settings/mock_settings_observer.h +++ b/chrome/browser/content_settings/mock_settings_observer.h
@@ -21,8 +21,7 @@ void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; MOCK_METHOD6(OnContentSettingsChanged, void(HostContentSettingsMap*,
diff --git a/chrome/browser/content_settings/sound_content_setting_observer.cc b/chrome/browser/content_settings/sound_content_setting_observer.cc index 8bffc74..fe784bb 100644 --- a/chrome/browser/content_settings/sound_content_setting_observer.cc +++ b/chrome/browser/content_settings/sound_content_setting_observer.cc
@@ -102,15 +102,13 @@ void SoundContentSettingObserver::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { if (content_type != ContentSettingsType::SOUND) return; #if !defined(OS_ANDROID) if (primary_pattern == ContentSettingsPattern() && - secondary_pattern == ContentSettingsPattern() && - resource_identifier.empty()) { + secondary_pattern == ContentSettingsPattern()) { UpdateAutoplayPolicy(); } #endif
diff --git a/chrome/browser/content_settings/sound_content_setting_observer.h b/chrome/browser/content_settings/sound_content_setting_observer.h index 0844f68..1f8c405 100644 --- a/chrome/browser/content_settings/sound_content_setting_observer.h +++ b/chrome/browser/content_settings/sound_content_setting_observer.h
@@ -39,8 +39,7 @@ // content_settings::Observer implementation. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; private: explicit SoundContentSettingObserver(content::WebContents* web_contents);
diff --git a/chrome/browser/download/download_request_limiter.cc b/chrome/browser/download/download_request_limiter.cc index a5feeca1..3f8ed249 100644 --- a/chrome/browser/download/download_request_limiter.cc +++ b/chrome/browser/download/download_request_limiter.cc
@@ -337,8 +337,7 @@ void DownloadRequestLimiter::TabDownloadState::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { if (content_type != ContentSettingsType::AUTOMATIC_DOWNLOADS) return; @@ -348,7 +347,7 @@ GURL origin = origin_.GetURL(); // Analogous to PageSpecificContentSettings::OnContentSettingChanged: const ContentSettingsDetails details(primary_pattern, secondary_pattern, - content_type, resource_identifier); + content_type, std::string()); // Check if the settings change affects the most recent origin passed // to SetDownloadStatusAndNotify(). If so, we need to update the omnibox
diff --git a/chrome/browser/download/download_request_limiter.h b/chrome/browser/download/download_request_limiter.h index ffcb95c..dfb79b34 100644 --- a/chrome/browser/download/download_request_limiter.h +++ b/chrome/browser/download/download_request_limiter.h
@@ -161,8 +161,7 @@ void OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // Remember to either block or allow automatic downloads from // |request_origin|.
diff --git a/chrome/browser/engagement/site_engagement_service_unittest.cc b/chrome/browser/engagement/site_engagement_service_unittest.cc index bb1fbb1b..3b25db5 100644 --- a/chrome/browser/engagement/site_engagement_service_unittest.cc +++ b/chrome/browser/engagement/site_engagement_service_unittest.cc
@@ -69,11 +69,9 @@ } // Overridden from content_settings::Observer: - void OnContentSettingChanged( - const ContentSettingsPattern& primary_pattern, - const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override { + void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, + const ContentSettingsPattern& secondary_pattern, + ContentSettingsType content_type) override { if (content_type == ContentSettingsType::SITE_ENGAGEMENT) Proceed(); }
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc b/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc index 644852b..adab5cb 100644 --- a/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc +++ b/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc
@@ -114,9 +114,6 @@ ContentSettingsType::MEDIASTREAM_CAMERA)); EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting(example_url, example_url, - ContentSettingsType::PPAPI_BROKER)); - EXPECT_EQ(CONTENT_SETTING_ASK, - map->GetContentSetting(example_url, example_url, ContentSettingsType::AUTOMATIC_DOWNLOADS)); EXPECT_EQ(CONTENT_SETTING_ALLOW, map->GetContentSetting(example_url, example_url, @@ -146,9 +143,6 @@ EXPECT_EQ(CONTENT_SETTING_BLOCK, map->GetContentSetting(url, url, ContentSettingsType::MEDIASTREAM_CAMERA)); - EXPECT_EQ( - CONTENT_SETTING_BLOCK, - map->GetContentSetting(url, url, ContentSettingsType::PPAPI_BROKER)); EXPECT_EQ(CONTENT_SETTING_BLOCK, map->GetContentSetting(url, url, ContentSettingsType::AUTOMATIC_DOWNLOADS)); @@ -187,9 +181,6 @@ EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting(url, url, ContentSettingsType::MEDIASTREAM_CAMERA)); - EXPECT_EQ( - CONTENT_SETTING_ASK, - map->GetContentSetting(url, url, ContentSettingsType::PPAPI_BROKER)); EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting(url, url, ContentSettingsType::AUTOMATIC_DOWNLOADS)); @@ -225,8 +216,6 @@ map->GetContentSetting(url, url, ContentSettingsType::MEDIASTREAM_MIC)); content_settings.push_back(map->GetContentSetting( url, url, ContentSettingsType::MEDIASTREAM_CAMERA)); - content_settings.push_back( - map->GetContentSetting(url, url, ContentSettingsType::PPAPI_BROKER)); content_settings.push_back(map->GetContentSetting( url, url, ContentSettingsType::AUTOMATIC_DOWNLOADS)); content_settings.push_back(
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.cc b/chrome/browser/extensions/api/terminal/terminal_private_api.cc index b81e985..26124426 100644 --- a/chrome/browser/extensions/api/terminal/terminal_private_api.cc +++ b/chrome/browser/extensions/api/terminal/terminal_private_api.cc
@@ -13,6 +13,7 @@ #include "ash/public/cpp/ash_pref_names.h" #include "base/bind.h" #include "base/command_line.h" +#include "base/containers/flat_set.h" #include "base/json/json_writer.h" #include "base/lazy_instance.h" #include "base/memory/scoped_refptr.h" @@ -37,6 +38,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_user_data.h" #include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/event_router.h" @@ -75,6 +77,43 @@ int32_t g_last_active_pid = 0; +class TerminalTabHelper + : public content::WebContentsUserData<TerminalTabHelper> { + public: + void AddTerminalId(const std::string& terminal_id) { + if (!terminal_ids_.insert(terminal_id).second) { + LOG(ERROR) << "terminal id already exists" << terminal_id; + } + } + + void RemoveTerminalId(const std::string& terminal_id) { + if (terminal_ids_.erase(terminal_id) == 0) { + LOG(ERROR) << "terminal id does not exists" << terminal_id; + } + } + + static bool ValidateTerminalId(const content::WebContents* contents, + const std::string& terminal_id) { + if (contents != nullptr) { + auto* helper = TerminalTabHelper::FromWebContents(contents); + if (helper != nullptr) { + return helper->terminal_ids_.contains(terminal_id); + } + } + return false; + } + + private: + explicit TerminalTabHelper(content::WebContents* contents) {} + + friend class content::WebContentsUserData<TerminalTabHelper>; + WEB_CONTENTS_USER_DATA_KEY_DECL(); + + base::flat_set<std::string> terminal_ids_; +}; + +WEB_CONTENTS_USER_DATA_KEY_IMPL(TerminalTabHelper) + // Copies the value of |switch_name| if present from |src| to |dst|. If not // present, uses |default_value| if nonempty. Returns the value set into |dst|. std::string GetSwitch(const base::CommandLine& src, @@ -91,19 +130,17 @@ } void NotifyProcessOutput(content::BrowserContext* browser_context, - int tab_id, const std::string& terminal_id, const std::string& output_type, const std::string& output) { if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&NotifyProcessOutput, browser_context, tab_id, + FROM_HERE, base::BindOnce(&NotifyProcessOutput, browser_context, terminal_id, output_type, output)); return; } std::unique_ptr<base::ListValue> args(new base::ListValue()); - args->AppendInteger(tab_id); args->AppendString(terminal_id); args->AppendString(output_type); args->AppendString(output); @@ -118,18 +155,6 @@ } } -// Returns tab ID, or window session ID (for platform apps) for |web_contents|. -int GetTabOrWindowSessionId(content::BrowserContext* browser_context, - content::WebContents* web_contents) { - int tab_id = extensions::ExtensionTabUtil::GetTabId(web_contents); - if (tab_id >= 0) - return tab_id; - extensions::AppWindow* window = - extensions::AppWindowRegistry::Get(browser_context) - ->GetAppWindowForWebContents(web_contents); - return window ? window->session_id().id() : -1; -} - void PreferenceChanged(Profile* profile, const std::string& pref_name, extensions::events::HistogramValue histogram, @@ -145,9 +170,7 @@ } void SetLastActiveTerminal(const std::string& terminal_id) { - // The terminal_id is <pid>-<guid>. We will parse it to get the pid. - // atoi will read all leading digits and stop at any non-digit such as '-'. - g_last_active_pid = atoi(terminal_id.c_str()); + // TODO(crbug.com/1113207): disable this until we have a better cwd solution. } } // namespace @@ -209,35 +232,21 @@ if (!caller_contents) return RespondNow(Error("No web contents.")); - // Passed to terminalPrivate.ackOutput, which is called from the API's custom - // bindings after terminalPrivate.onProcessOutput is dispatched. It is used to - // determine whether ackOutput call should be handled or not. ackOutput will - // be called from every web contents in which a onProcessOutput listener - // exists (because the API custom bindings hooks are run in every web contents - // with a listener). Only ackOutput called from the web contents that has the - // target terminal instance should be handled. - // TODO(tbarzic): Instead of passing tab/app window session id around, keep - // mapping from web_contents to terminal ID running in it. This will be - // needed to fix crbug.com/210295. - int tab_id = GetTabOrWindowSessionId(browser_context(), caller_contents); - if (tab_id < 0) - return RespondNow(Error("Not called from a tab or app window")); - // Passing --crosh-command overrides any JS process name. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kCroshCommand)) { OpenProcess( - user_id_hash, tab_id, + user_id_hash, base::CommandLine(base::FilePath( command_line->GetSwitchValueASCII(switches::kCroshCommand)))); } else if (process_name == kCroshName) { // command=crosh: use '/usr/bin/crosh' on a device, 'cat' otherwise. if (base::SysInfo::IsRunningOnChromeOS()) { - OpenProcess(user_id_hash, tab_id, + OpenProcess(user_id_hash, base::CommandLine(base::FilePath(kCroshCommand))); } else { - OpenProcess(user_id_hash, tab_id, + OpenProcess(user_id_hash, base::CommandLine(base::FilePath(kStubbedCroshCommand))); } @@ -268,8 +277,7 @@ auto* mgr = crostini::CrostiniManager::GetForProfile(profile); bool verbose = !mgr->GetContainerInfo(container_id).has_value(); auto observer = std::make_unique<CrostiniStartupStatus>( - base::BindRepeating(&NotifyProcessOutput, browser_context(), tab_id, - startup_id, + base::BindRepeating(&NotifyProcessOutput, browser_context(), startup_id, api::terminal_private::ToString( api::terminal_private::OUTPUT_TYPE_STDOUT)), verbose); @@ -280,8 +288,7 @@ container_id, base::BindOnce( &TerminalPrivateOpenTerminalProcessFunction::OnCrostiniRestarted, - this, std::move(observer), user_id_hash, tab_id, - std::move(cmdline)), + this, std::move(observer), user_id_hash, std::move(cmdline)), observer_ptr); } else { // command=[unrecognized]. @@ -293,7 +300,6 @@ void TerminalPrivateOpenTerminalProcessFunction::OnCrostiniRestarted( std::unique_ptr<CrostiniStartupStatus> startup_status, const std::string& user_id_hash, - int tab_id, base::CommandLine cmdline, crostini::CrostiniResult result) { if (crostini::MaybeShowCrostiniDialogBeforeLaunch( @@ -305,7 +311,7 @@ } startup_status->OnCrostiniRestarted(result); if (result == crostini::CrostiniResult::SUCCESS) { - OpenVmshellProcess(user_id_hash, tab_id, std::move(cmdline)); + OpenVmshellProcess(user_id_hash, std::move(cmdline)); } else { const std::string msg = base::StringPrintf("Error starting crostini for terminal: %d", result); @@ -316,11 +322,10 @@ void TerminalPrivateOpenTerminalProcessFunction::OpenVmshellProcess( const std::string& user_id_hash, - int tab_id, base::CommandLine cmdline) { // If cwd is already set in cmdline, or this is the first terminal, open now. if (cmdline.HasSwitch(kSwitchCurrentWorkingDir) || !g_last_active_pid) { - return OpenProcess(user_id_hash, tab_id, std::move(cmdline)); + return OpenProcess(user_id_hash, std::move(cmdline)); } // Lookup container shell pid from cicierone to use for cwd. @@ -330,13 +335,11 @@ crostini::ContainerId::GetDefault(), g_last_active_pid, base::BindOnce( &TerminalPrivateOpenTerminalProcessFunction::OnGetVshSession, - this, user_id_hash, tab_id, std::move(cmdline), - g_last_active_pid)); + this, user_id_hash, std::move(cmdline), g_last_active_pid)); } void TerminalPrivateOpenTerminalProcessFunction::OnGetVshSession( const std::string& user_id_hash, - int tab_id, base::CommandLine cmdline, int32_t vsh_pid, bool success, @@ -349,12 +352,11 @@ cmdline.AppendSwitchASCII(kSwitchCurrentWorkingDir, base::NumberToString(container_shell_pid)); } - OpenProcess(user_id_hash, tab_id, std::move(cmdline)); + OpenProcess(user_id_hash, std::move(cmdline)); } void TerminalPrivateOpenTerminalProcessFunction::OpenProcess( const std::string& user_id_hash, - int tab_id, base::CommandLine cmdline) { DCHECK(!cmdline.argv().empty()); // Registry lives on its own task runner. @@ -362,7 +364,7 @@ FROM_HERE, base::BindOnce( &TerminalPrivateOpenTerminalProcessFunction::OpenOnRegistryTaskRunner, - this, base::Bind(&NotifyProcessOutput, browser_context(), tab_id), + this, base::Bind(&NotifyProcessOutput, browser_context()), base::Bind( &TerminalPrivateOpenTerminalProcessFunction::RespondOnUIThread, this), @@ -387,12 +389,31 @@ void TerminalPrivateOpenTerminalProcessFunction::RespondOnUIThread( bool success, const std::string& terminal_id) { + auto* contents = GetSenderWebContents(); + if (!contents) { + LOG(WARNING) << "content is closed before returning opened process"; + chromeos::ProcessProxyRegistry::GetTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + [](const std::string& terminal_id) { + if (!chromeos::ProcessProxyRegistry::Get()->CloseProcess( + terminal_id)) { + LOG(ERROR) << "Unable to close terminal " << terminal_id; + } + }, + terminal_id)); + return; + } + if (!success) { Respond(Error("Failed to open process.")); return; } SetLastActiveTerminal(terminal_id); Respond(OneArgument(base::Value(terminal_id))); + + TerminalTabHelper::CreateForWebContents(contents); + TerminalTabHelper::FromWebContents(contents)->AddTerminalId(terminal_id); } TerminalPrivateOpenVmshellProcessFunction:: @@ -413,6 +434,13 @@ ExtensionFunction::ResponseAction TerminalPrivateSendInputFunction::Run() { std::unique_ptr<SendInput::Params> params(SendInput::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); + + if (!TerminalTabHelper::ValidateTerminalId(GetSenderWebContents(), + params->id)) { + LOG(ERROR) << "invalid terminal id " << params->id; + return RespondNow(Error("invalid terminal id")); + } + SetLastActiveTerminal(params->id); // Registry lives on its own task runner. @@ -449,6 +477,12 @@ CloseTerminalProcess::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); + if (!TerminalTabHelper::ValidateTerminalId(GetSenderWebContents(), + params->id)) { + LOG(ERROR) << "invalid terminal id " << params->id; + return RespondNow(Error("invalid terminal id")); + } + // Registry lives on its own task runner. chromeos::ProcessProxyRegistry::GetTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&TerminalPrivateCloseTerminalProcessFunction:: @@ -483,6 +517,13 @@ std::unique_ptr<OnTerminalResize::Params> params( OnTerminalResize::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); + + if (!TerminalTabHelper::ValidateTerminalId(GetSenderWebContents(), + params->id)) { + LOG(ERROR) << "invalid terminal id " << params->id; + return RespondNow(Error("invalid terminal id")); + } + SetLastActiveTerminal(params->id); // Registry lives on its own task runner. @@ -519,23 +560,17 @@ std::unique_ptr<AckOutput::Params> params(AckOutput::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - content::WebContents* caller_contents = GetSenderWebContents(); - if (!caller_contents) - return RespondNow(Error("No web contents.")); - - int tab_id = GetTabOrWindowSessionId(browser_context(), caller_contents); - if (tab_id < 0) - return RespondNow(Error("Not called from a tab or app window")); - - if (tab_id != params->tab_id) - return RespondNow(NoArguments()); - - // Registry lives on its own task runner. - chromeos::ProcessProxyRegistry::GetTaskRunner()->PostTask( - FROM_HERE, - base::BindOnce( - &TerminalPrivateAckOutputFunction::AckOutputOnRegistryTaskRunner, - this, params->id)); + // Every running terminal page will call ackOutput(), but we should only react + // for the one who actually owns the output. + if (TerminalTabHelper::ValidateTerminalId(GetSenderWebContents(), + params->id)) { + // Registry lives on its own task runner. + chromeos::ProcessProxyRegistry::GetTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + &TerminalPrivateAckOutputFunction::AckOutputOnRegistryTaskRunner, + this, params->id)); + } return RespondNow(NoArguments()); }
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.h b/chrome/browser/extensions/api/terminal/terminal_private_api.h index 514cb15..2433e44f 100644 --- a/chrome/browser/extensions/api/terminal/terminal_private_api.h +++ b/chrome/browser/extensions/api/terminal/terminal_private_api.h
@@ -62,16 +62,13 @@ void OnCrostiniRestarted( std::unique_ptr<CrostiniStartupStatus> startup_status, const std::string& user_id_hash, - int tab_id, base::CommandLine cmdline, crostini::CrostiniResult result); void OpenVmshellProcess(const std::string& user_id_hash, - int tab_id, base::CommandLine cmdline); void OnGetVshSession(const std::string& user_id_hash, - int tab_id, base::CommandLine cmdline, int32_t vsh_pid, bool success, @@ -79,7 +76,6 @@ int32_t container_shell_pid); void OpenProcess(const std::string& user_id_hash, - int tab_id, base::CommandLine cmdline); using ProcessOutputCallback =
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_apitest.cc b/chrome/browser/extensions/api/terminal/terminal_private_apitest.cc index 244e8d28..47a612a 100644 --- a/chrome/browser/extensions/api/terminal/terminal_private_apitest.cc +++ b/chrome/browser/extensions/api/terminal/terminal_private_apitest.cc
@@ -2,11 +2,100 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/bind.h" #include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/location.h" +#include "base/run_loop.h" +#include "base/test/bind.h" #include "chrome/browser/extensions/extension_apitest.h" +#include "chromeos/process_proxy/process_proxy_registry.h" +#include "content/public/browser/browser_task_traits.h" #include "content/public/test/browser_test.h" #include "extensions/common/switches.h" +namespace { + +// For running and maintaining a `cat` process using `ProcessProxyRegistry` +// directly. +class CatProcess { + public: + CatProcess() { + base::RunLoop run_loop; + + chromeos::ProcessProxyRegistry::GetTaskRunner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + chromeos::ProcessProxyRegistry* registry = + chromeos::ProcessProxyRegistry::Get(); + + auto on_output_on_process_thread = base::BindLambdaForTesting( + [this](const std::string&, const std::string&, + const std::string&) { + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&CatProcess::OnOutputOnUIThread, + base::Unretained(this))); + }); + + // `user_id_hash` does not seems to matter in test. + this->ok_ = registry->OpenProcess( + base::CommandLine(base::FilePath("cat")), /*user_id_hash=*/"user", + on_output_on_process_thread, &this->process_id_); + + run_loop.Quit(); + })); + + run_loop.Run(); + } + + ~CatProcess() { + if (ok_) { + chromeos::ProcessProxyRegistry::GetTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + [](const std::string& process_id) { + chromeos::ProcessProxyRegistry::Get()->CloseProcess(process_id); + }, + process_id_)); + } + } + + bool ok() const { return ok_; } + bool has_output() const { return has_output_; } + const std::string& process_id() const { return process_id_; } + + void send_input_and_wait_output(const std::string& data) { + base::RunLoop run_loop; + CHECK(on_output_closure_.is_null()); + on_output_closure_ = run_loop.QuitClosure(); + + chromeos::ProcessProxyRegistry::GetTaskRunner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + chromeos::ProcessProxyRegistry::Get()->SendInput(this->process_id_, + data); + })); + + run_loop.Run(); + } + + private: + void OnOutputOnUIThread() { + // We don't bother to call `ProcessProxyRegistry::AckOutput()` here since we + // only need to know whether there is some output. + has_output_ = true; + + if (!on_output_closure_.is_null()) { + std::move(on_output_closure_).Run(); + } + } + + bool ok_; + std::string process_id_; + bool has_output_{false}; + base::OnceClosure on_output_closure_; +}; + +} // namespace + class ExtensionTerminalPrivateApiTest : public extensions::ExtensionApiTest { void SetUpCommandLine(base::CommandLine* command_line) override { extensions::ExtensionApiTest::SetUpCommandLine(command_line); @@ -16,7 +105,25 @@ } }; +IN_PROC_BROWSER_TEST_F(ExtensionTerminalPrivateApiTest, CatProcess) { + CatProcess cat_process; + ASSERT_TRUE(cat_process.ok()); + ASSERT_FALSE(cat_process.has_output()); + cat_process.send_input_and_wait_output("hello"); + ASSERT_TRUE(cat_process.has_output()); +} + IN_PROC_BROWSER_TEST_F(ExtensionTerminalPrivateApiTest, TerminalTest) { - EXPECT_TRUE(RunExtensionSubtest("terminal/component_extension", "test.html")) + CatProcess cat_process; + ASSERT_TRUE(cat_process.ok()); + + EXPECT_TRUE( + RunExtensionSubtest("terminal/component_extension", + "test.html?foreign_id=" + cat_process.process_id())) << message_; + + // Double check that test.html cannot write to the cat process here; + // Otherwises, we should detect some output. + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(cat_process.has_output()); }
diff --git a/chrome/browser/extensions/chrome_extension_cookies.cc b/chrome/browser/extensions/chrome_extension_cookies.cc index c68fddab..5ae0f2a 100644 --- a/chrome/browser/extensions/chrome_extension_cookies.cc +++ b/chrome/browser/extensions/chrome_extension_cookies.cc
@@ -164,8 +164,7 @@ void ChromeExtensionCookies::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (!io_data_) // null after shutdown. return;
diff --git a/chrome/browser/extensions/chrome_extension_cookies.h b/chrome/browser/extensions/chrome_extension_cookies.h index f1f0420..882072b9 100644 --- a/chrome/browser/extensions/chrome_extension_cookies.h +++ b/chrome/browser/extensions/chrome_extension_cookies.h
@@ -113,8 +113,7 @@ // content_settings::Observer: void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // content_settings::CookieSettings::Observer: void OnThirdPartyCookieBlockingChanged(
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc b/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc index fc7a5e3..3f9445a 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc +++ b/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc
@@ -78,15 +78,6 @@ } #endif // defined(OS_CHROMEOS) -// Returns true if the extension is fetched from the cache. -bool IsExtensionFetchedFromCache( - const base::Optional<ExtensionDownloaderDelegate::CacheStatus> status) { - DCHECK(status); - return status.value() == ExtensionDownloaderDelegate::CacheStatus:: - CACHE_HIT_ON_MANIFEST_FETCH_FAILURE || - status.value() == ExtensionDownloaderDelegate::CacheStatus::CACHE_HIT; -} - // Reports time taken for force installed extension during different // installation stages. void ReportInstallationStageTimes( @@ -251,10 +242,10 @@ is_from_store); base::UmaHistogramBoolean( "Extensions.ForceInstalledFailureWithCrxHeaderInvalidIsFromCache", - IsExtensionFetchedFromCache(installation.downloading_cache_status)); + ForceInstalledTracker::IsExtensionFetchedFromCache( + installation.downloading_cache_status)); } } - } // namespace ForceInstalledMetrics::ForceInstalledMetrics(
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc b/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc index 90f9ddb..a4b9cb4 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc +++ b/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc
@@ -197,7 +197,7 @@ } TEST_F(ForceInstalledMetricsTest, ExtensionsInstalled) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); @@ -223,7 +223,7 @@ // forced list, and their installation mode are overridden by ExtensionSettings // policy to something else. TEST_F(ForceInstalledMetricsTest, ExtensionSettingsOverrideForcedList) { - SetupForceList(); + SetupForceList(true /*is_from_store */); SetupExtensionManagementPref(); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); @@ -236,7 +236,7 @@ } TEST_F(ForceInstalledMetricsTest, ExtensionsInstallationTimedOut) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); registry()->AddEnabled(ext1.get()); EXPECT_TRUE(fake_timer_->IsRunning()); @@ -258,7 +258,7 @@ // Reporting the time for downloading the manifest of an extension and verifying // that it is correctly recorded in the histogram. TEST_F(ForceInstalledMetricsTest, ExtensionsManifestDownloadTime) { - SetupForceList(); + SetupForceList(true /*is_from_store */); ReportDownloadingManifestStage(); const base::TimeDelta manifest_download_time = base::TimeDelta::FromMilliseconds(200); @@ -280,7 +280,7 @@ // Reporting the time for downloading the CRX file of an extension and verifying // that it is correctly recorded in the histogram. TEST_F(ForceInstalledMetricsTest, ExtensionsCrxDownloadTime) { - SetupForceList(); + SetupForceList(true /*is_from_store */); ReportDownloadingManifestStage(); const base::TimeDelta install_time = base::TimeDelta::FromMilliseconds(200); ReportInstallationStarted(install_time); @@ -298,7 +298,7 @@ TEST_F(ForceInstalledMetricsTest, ExtensionsCrxDownloadTimeWhenFetchedFromCache) { - SetupForceList(); + SetupForceList(true /*is_from_store */); ReportDownloadingManifestStage(); install_stage_tracker()->ReportDownloadingStage( kExtensionId1, ExtensionDownloaderDelegate::Stage::MANIFEST_LOADED); @@ -321,7 +321,7 @@ // and verifying that the time consumed at each stage is correctly recorded in // the histogram. TEST_F(ForceInstalledMetricsTest, ExtensionsReportInstallationStageTimes) { - SetupForceList(); + SetupForceList(true /*is_from_store */); ReportDownloadingManifestStage(); ReportInstallationStarted(base::nullopt); install_stage_tracker()->ReportCRXInstallationStage( @@ -377,7 +377,7 @@ // installed but not loaded when extension is disable due to single reason. TEST_F(ForceInstalledMetricsTest, ExtensionsInstalledButNotLoadedUniqueDisableReason) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); registry()->AddDisabled(ext1.get()); ExtensionPrefs::Get(profile())->AddDisableReason( @@ -397,7 +397,7 @@ // installed but not loaded when extension is disable due to multiple reasons. TEST_F(ForceInstalledMetricsTest, ExtensionsInstalledButNotLoadedMultipleDisableReason) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); registry()->AddDisabled(ext1.get()); ExtensionPrefs::Get(profile())->AddDisableReasons( @@ -421,7 +421,7 @@ // which are installed but not loaded when extension is enabled. TEST_F(ForceInstalledMetricsTest, ExtensionsInstalledButNotLoadedNoDisableReason) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); registry()->AddEnabled(ext1.get()); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); @@ -436,7 +436,7 @@ } TEST_F(ForceInstalledMetricsTest, ExtensionForceInstalledAndBlocklisted) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); registry()->AddBlocklisted(ext1.get()); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); @@ -450,7 +450,7 @@ } TEST_F(ForceInstalledMetricsTest, ExtensionsInstallationCancelled) { - SetupForceList(); + SetupForceList(true /*is_from_store */); SetupEmptyForceList(); // ForceInstalledMetrics does not shut down the timer, because it's still // waiting for the initial extensions to install. @@ -471,7 +471,7 @@ // ForceInstalledMetrics should keep running as the forced extensions are // still not loaded. EXPECT_TRUE(fake_timer_->IsRunning()); - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), ext.get()); @@ -487,7 +487,7 @@ TEST_F(ForceInstalledMetricsTest, ExtensionsInstallationTimedOutDifferentReasons) { - SetupForceList(); + SetupForceList(true /*is_from_store */); install_stage_tracker()->ReportFailure( kExtensionId1, InstallStageTracker::FailureReason::INVALID_ID); install_stage_tracker()->ReportCrxInstallError( @@ -518,7 +518,7 @@ // fails to install with error CRX_INSTALL_ERROR_SANDBOXED_UNPACKER_FAILURE. TEST_F(ForceInstalledMetricsTest, ExtensionsCrxInstallErrorSandboxUnpackFailure) { - SetupForceList(); + SetupForceList(true /*is_from_store */); install_stage_tracker()->ReportSandboxedUnpackerFailureReason( kExtensionId1, SandboxedUnpackerFailureReason::CRX_FILE_NOT_READABLE); install_stage_tracker()->ReportSandboxedUnpackerFailureReason( @@ -538,7 +538,7 @@ // Reporting when the extension is downloaded from cache and it fails to install // with error CRX_HEADER_INVALID. TEST_F(ForceInstalledMetricsTest, ExtensionsCrxHeaderInvalidFromCache) { - SetupForceList(); + SetupForceList(true /*is_from_store */); install_stage_tracker()->ReportDownloadingCacheStatus( kExtensionId1, ExtensionDownloaderDelegate::CacheStatus::CACHE_HIT); install_stage_tracker()->ReportSandboxedUnpackerFailureReason( @@ -561,7 +561,7 @@ // Reporting when the extension is not downloaded from cache and it fails to // install with error CRX_HEADER_INVALID. TEST_F(ForceInstalledMetricsTest, ExtensionsCrxHeaderInvalidNotFromCache) { - SetupForceList(); + SetupForceList(true /*is_from_store */); install_stage_tracker()->ReportDownloadingCacheStatus( kExtensionId1, ExtensionDownloaderDelegate::CacheStatus::CACHE_MISS); install_stage_tracker()->ReportSandboxedUnpackerFailureReason( @@ -581,10 +581,36 @@ 1); } +// Verifies that offstore extension that is downloaded from the update server +// and fails with CRX_HEADER_INVALID error is considered as a misconfiguration. +TEST_F(ForceInstalledMetricsTest, + ExtensionsCrxHeaderInvalidIsMisconfiguration) { + SetupForceList(false); + install_stage_tracker()->ReportDownloadingCacheStatus( + kExtensionId1, ExtensionDownloaderDelegate::CacheStatus::CACHE_MISS); + install_stage_tracker()->ReportSandboxedUnpackerFailureReason( + kExtensionId1, SandboxedUnpackerFailureReason::CRX_HEADER_INVALID); + auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); + registry()->AddEnabled(ext2.get()); + force_installed_tracker()->OnExtensionLoaded(profile(), ext2.get()); + // ForceInstalledMetrics shuts down timer because all extension are either + // loaded or failed. + EXPECT_FALSE(fake_timer_->IsRunning()); + histogram_tester_.ExpectTotalCount(kSandboxUnpackFailureReason, 1); + histogram_tester_.ExpectBucketCount( + kSandboxUnpackFailureReason, + SandboxedUnpackerFailureReason::CRX_HEADER_INVALID, 1); + histogram_tester_.ExpectBucketCount(kCrxHeaderInvalidFailureIsCWS, false, 1); + histogram_tester_.ExpectBucketCount(kCrxHeaderInvalidFailureFromCache, false, + 1); + histogram_tester_.ExpectBucketCount(kPossibleNonMisconfigurationFailures, 0, + 1); +} + // Reporting info when the force installed extension fails to install with error // CRX_FETCH_URL_EMPTY due to no updates from the server. TEST_F(ForceInstalledMetricsTest, ExtensionsNoUpdatesInfoReporting) { - SetupForceList(); + SetupForceList(true /*is_from_store */); install_stage_tracker()->ReportInfoOnNoUpdatesFailure(kExtensionId1, "disabled by client"); @@ -610,7 +636,7 @@ // ALREADY_INSTALLED. TEST_F(ForceInstalledMetricsTest, ExtensionLoadedThenFailedWithAlreadyInstalledError) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); install_stage_tracker()->ReportFailure( @@ -629,7 +655,7 @@ // extensions which are in state READY. Also verifies that the failure reported // after READY state is not reflected in the statistics. TEST_F(ForceInstalledMetricsTest, ExtensionsReady) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); force_installed_tracker()->OnExtensionReady(profile(), ext1.get()); @@ -651,7 +677,7 @@ // Regression test to check if no metrics are reported for READY state when some // extensions are failed. TEST_F(ForceInstalledMetricsTest, AllExtensionsNotReady) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); force_installed_tracker()->OnExtensionReady(profile(), ext1.get()); @@ -669,7 +695,7 @@ // Verifies that the installation stage is not overwritten by a previous stage. TEST_F(ForceInstalledMetricsTest, ExtensionsPreviousInstallationStageReportedAgain) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); @@ -690,7 +716,7 @@ // Verifies that the installation stage is overwritten if DOWNLOADING stage is // reported again after INSTALLING stage. TEST_F(ForceInstalledMetricsTest, ExtensionsDownloadingStageReportedAgain) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); @@ -711,7 +737,7 @@ } TEST_F(ForceInstalledMetricsTest, ExtensionsStuck) { - SetupForceList(); + SetupForceList(true /*is_from_store */); install_stage_tracker()->ReportInstallationStage( kExtensionId1, InstallStageTracker::Stage::PENDING); install_stage_tracker()->ReportInstallationStage( @@ -736,7 +762,7 @@ } TEST_F(ForceInstalledMetricsTest, ExtensionStuckInCreatedStage) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); @@ -772,7 +798,7 @@ false /* browser_restart */, false /* is_child */); chromeos::ProfileHelper::Get()->SetProfileToUserMappingForTesting(user); - SetupForceList(); + SetupForceList(true /*is_from_store */); install_stage_tracker()->ReportFailure( kExtensionId1, InstallStageTracker::FailureReason::INVALID_ID); install_stage_tracker()->ReportCrxInstallError( @@ -799,7 +825,7 @@ false /* browser_restart */, false /* is_child */); chromeos::ProfileHelper::Get()->SetProfileToUserMappingForTesting(user); - SetupForceList(); + SetupForceList(true /*is_from_store */); install_stage_tracker()->ReportFailure( kExtensionId1, InstallStageTracker::FailureReason::INVALID_ID); install_stage_tracker()->ReportCrxInstallError( @@ -816,7 +842,7 @@ #endif // defined(OS_CHROMEOS) TEST_F(ForceInstalledMetricsTest, ExtensionsAreDownloading) { - SetupForceList(); + SetupForceList(true /*is_from_store */); install_stage_tracker()->ReportInstallationStage( kExtensionId1, InstallStageTracker::Stage::DOWNLOADING); install_stage_tracker()->ReportDownloadingStage( @@ -848,7 +874,7 @@ // Error Codes in case of CRX_FETCH_FAILED. TEST_F(ForceInstalledMetricsTest, ExtensionCrxFetchFailed) { - SetupForceList(); + SetupForceList(true /*is_from_store */); ExtensionDownloaderDelegate::FailureData data1(net::Error::OK, kResponseCode, kFetchTries); ExtensionDownloaderDelegate::FailureData data2( @@ -872,7 +898,7 @@ // Error Codes in case of MANIFEST_FETCH_FAILED. TEST_F(ForceInstalledMetricsTest, ExtensionManifestFetchFailed) { - SetupForceList(); + SetupForceList(true /*is_from_store */); ExtensionDownloaderDelegate::FailureData data1(net::Error::OK, kResponseCode, kFetchTries); ExtensionDownloaderDelegate::FailureData data2( @@ -898,7 +924,7 @@ // Errors occurred because the fetched update manifest was invalid. TEST_F(ForceInstalledMetricsTest, ExtensionManifestInvalid) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); @@ -918,7 +944,7 @@ // status was not OK. Verifies that this error with app status error as // "error-unknownApplication" is considered as a misconfiguration. TEST_F(ForceInstalledMetricsTest, ExtensionManifestInvalidAppStatusError) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); @@ -947,7 +973,7 @@ // misconfiguration. TEST_F(ForceInstalledMetricsTest, NonMisconfigurationFailureNotPresentKioskModeOnlyError) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); @@ -969,7 +995,7 @@ // kExtensionAllowedTypes is considered as misconfiguration. TEST_F(ForceInstalledMetricsTest, NonMisconfigurationFailureNotPresentDisallowedByPolicyTypeError) { - SetupForceList(); + SetupForceList(true /*is_from_store */); // Set TYPE_EXTENSION and TYPE_THEME as the allowed extension types. std::unique_ptr<base::Value> list = ListBuilder().Append("extension").Append("theme").Build(); @@ -999,7 +1025,7 @@ // a misconfiguration failure. TEST_F(ForceInstalledMetricsTest, NonMisconfigurationFailurePresentDisallowedByPolicyError) { - SetupForceList(); + SetupForceList(true /*is_from_store */); // Set TYPE_EXTENSION and TYPE_THEME as the allowed extension types. std::unique_ptr<base::Value> list = @@ -1028,7 +1054,7 @@ // Misconfiguration failure includes error KIOSK_MODE_ONLY, when force installed // extension fails to install with failure reason CRX_INSTALL_ERROR. TEST_F(ForceInstalledMetricsTest, NonMisconfigurationFailurePresent) { - SetupForceList(); + SetupForceList(true /*is_from_store */); install_stage_tracker()->ReportFailure( kExtensionId1, InstallStageTracker::FailureReason::INVALID_ID); install_stage_tracker()->ReportCrxInstallError( @@ -1052,7 +1078,7 @@ // Enable ARC++ for this profile. prefs()->SetManagedPref(arc::prefs::kArcEnabled, std::make_unique<base::Value>(true)); - SetupForceList(); + SetupForceList(true /*is_from_store */); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); @@ -1073,7 +1099,7 @@ // Enable ARC++ for this profile. prefs()->SetManagedPref(arc::prefs::kArcEnabled, std::make_unique<base::Value>(false)); - SetupForceList(); + SetupForceList(true /*is_from_store */); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); @@ -1092,7 +1118,7 @@ // NOT_PERFORMING_NEW_INSTALL is considered as misconfiguration. TEST_F(ForceInstalledMetricsTest, NonMisconfigurationFailureNotPresentNotPerformingNewInstallError) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); @@ -1111,7 +1137,7 @@ // CRX_FETCH_URL_EMPTY with empty info field is considered as misconfiguration. TEST_F(ForceInstalledMetricsTest, NonMisconfigurationFailureNotPresentCrxFetchUrlEmptyError) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); @@ -1129,7 +1155,7 @@ // is not considered as a misconfiguration. TEST_F(ForceInstalledMetricsTest, NonMisconfigurationFailurePresentCrxFetchUrlEmptyError) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto extension = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), extension.get()); @@ -1158,7 +1184,7 @@ } TEST_F(ForceInstalledMetricsTest, CachedExtensions) { - SetupForceList(); + SetupForceList(true /*is_from_store */); install_stage_tracker()->ReportDownloadingCacheStatus( kExtensionId1, ExtensionDownloaderDelegate::CacheStatus::CACHE_HIT); install_stage_tracker()->ReportDownloadingCacheStatus(
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_test_base.cc b/chrome/browser/extensions/forced_extensions/force_installed_test_base.cc index f09b3548..b613330 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_test_base.cc +++ b/chrome/browser/extensions/forced_extensions/force_installed_test_base.cc
@@ -32,6 +32,8 @@ const char ForceInstalledTestBase::kExtensionUpdateUrl[] = "https://clients2.google.com/service/update2/crx"; // URL of Chrome Web // Store backend. +const char ForceInstalledTestBase::kOffStoreUpdateUrl[] = + "https://www.example.com/update2/crx"; ForceInstalledTestBase::ForceInstalledTestBase() = default; ForceInstalledTestBase::~ForceInstalledTestBase() = default; @@ -57,20 +59,22 @@ std::make_unique<ForceInstalledTracker>(registry_, profile_); } -void ForceInstalledTestBase::SetupForceList() { +void ForceInstalledTestBase::SetupForceList(bool is_from_store) { base::Value list(base::Value::Type::LIST); - list.Append(base::StrCat({kExtensionId1, ";", kExtensionUpdateUrl})); - list.Append(base::StrCat({kExtensionId2, ";", kExtensionUpdateUrl})); + const std::string update_url = + is_from_store ? kExtensionUpdateUrl : kOffStoreUpdateUrl; + list.Append(base::StrCat({kExtensionId1, ";", update_url})); + list.Append(base::StrCat({kExtensionId2, ";", update_url})); std::unique_ptr<base::Value> dict = DictionaryBuilder() - .Set(kExtensionId1, DictionaryBuilder() - .Set(ExternalProviderImpl::kExternalUpdateUrl, - kExtensionUpdateUrl) - .Build()) - .Set(kExtensionId2, DictionaryBuilder() - .Set(ExternalProviderImpl::kExternalUpdateUrl, - kExtensionUpdateUrl) - .Build()) + .Set(kExtensionId1, + DictionaryBuilder() + .Set(ExternalProviderImpl::kExternalUpdateUrl, update_url) + .Build()) + .Set(kExtensionId2, + DictionaryBuilder() + .Set(ExternalProviderImpl::kExternalUpdateUrl, update_url) + .Build()) .Build(); prefs_->SetManagedPref(pref_names::kInstallForceList, std::move(dict));
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_test_base.h b/chrome/browser/extensions/forced_extensions/force_installed_test_base.h index 1e4b143a..61247c95 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_test_base.h +++ b/chrome/browser/extensions/forced_extensions/force_installed_test_base.h
@@ -36,8 +36,9 @@ void SetUp() override; // Creates and sets value for ExtensionInstallForcelist policy and - // kInstallForceList preference. - void SetupForceList(); + // kInstallForceList preference. |is_from_store| tells whether the extensions + // specified in the policy should have an update URL from CWS or not. + void SetupForceList(bool is_from_store); // Creates and sets empty value for ExtensionInstallForcelist policy and // kInstallForceList preference. @@ -62,6 +63,7 @@ static const char kExtensionName1[]; static const char kExtensionName2[]; static const char kExtensionUpdateUrl[]; + static const char kOffStoreUpdateUrl[]; content::BrowserTaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME};
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_tracker.cc b/chrome/browser/extensions/forced_extensions/force_installed_tracker.cc index 3e471a4..bc95e5c 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_tracker.cc +++ b/chrome/browser/extensions/forced_extensions/force_installed_tracker.cc
@@ -231,9 +231,33 @@ return true; } + if (installation_data.unpacker_failure_reason == + SandboxedUnpackerFailureReason::CRX_HEADER_INVALID) { + auto extension = extensions_.find(id); + // Extension id may be missing from this list if there is a change in + // ExtensionInstallForcelist policy after the user has logged in and + // |IsMisconfiguration| method is called from + // |ExtensionInstallEventLogCollector|. + if (extension != extensions_.end() && !extension->second.is_from_store && + !IsExtensionFetchedFromCache( + installation_data.downloading_cache_status)) { + return true; + } + } + return false; } +// static +bool ForceInstalledTracker::IsExtensionFetchedFromCache( + const base::Optional<ExtensionDownloaderDelegate::CacheStatus>& status) { + if (!status) + return false; + return status.value() == ExtensionDownloaderDelegate::CacheStatus:: + CACHE_HIT_ON_MANIFEST_FETCH_FAILURE || + status.value() == ExtensionDownloaderDelegate::CacheStatus::CACHE_HIT; +} + policy::PolicyService* ForceInstalledTracker::policy_service() { return profile_->GetProfilePolicyConnector()->policy_service(); }
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_tracker.h b/chrome/browser/extensions/forced_extensions/force_installed_tracker.h index 6a89962..a928d0a 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_tracker.h +++ b/chrome/browser/extensions/forced_extensions/force_installed_tracker.h
@@ -135,6 +135,9 @@ const InstallStageTracker::InstallationData& installation_data, const ExtensionId& id) const; + static bool IsExtensionFetchedFromCache( + const base::Optional<ExtensionDownloaderDelegate::CacheStatus>& status); + private: policy::PolicyService* policy_service();
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_tracker_unittest.cc b/chrome/browser/extensions/forced_extensions/force_installed_tracker_unittest.cc index c64ae14..14b3f1fdc 100644 --- a/chrome/browser/extensions/forced_extensions/force_installed_tracker_unittest.cc +++ b/chrome/browser/extensions/forced_extensions/force_installed_tracker_unittest.cc
@@ -47,7 +47,7 @@ TEST_F(ForceInstalledTrackerTest, BeforeForceInstallPolicy) { EXPECT_FALSE(loaded_called_); EXPECT_FALSE(ready_called_); - SetupForceList(); + SetupForceList(true /*is_from_store */); } // This test verifies that OnForceInstalledExtensionsLoaded() is called once all @@ -55,7 +55,7 @@ // OnForceInstalledExtensionsReady() is called once all those extensions have // become ready for use. TEST_F(ForceInstalledTrackerTest, AllExtensionsInstalled) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); EXPECT_FALSE(loaded_called_); @@ -80,7 +80,7 @@ // This test verifies that OnForceInstalledExtensionsLoaded() is not called till // all extensions have either successfully loaded or failed. TEST_F(ForceInstalledTrackerTest, ExtensionPendingInstall) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); EXPECT_FALSE(loaded_called_); @@ -99,7 +99,7 @@ TEST_F(ForceInstalledTrackerTest, ObserversOnlyCalledOnce) { // Start with a non-empty force-list, and install them, which triggers // observer. - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); auto ext2 = ExtensionBuilder(kExtensionName2).SetID(kExtensionId2).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); @@ -118,7 +118,7 @@ // This test verifies that observer is called if force installed extensions are // either successfully loaded or failed. TEST_F(ForceInstalledTrackerTest, ExtensionsInstallationFailed) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); force_installed_tracker()->OnExtensionInstallationFailed( @@ -132,7 +132,7 @@ // |ForceInstalledTracker::extensions_| as the extensions are either loaded or // failed. TEST_F(ForceInstalledTrackerTest, ExtensionsStatus) { - SetupForceList(); + SetupForceList(true /*is_from_store */); EXPECT_EQ(force_installed_tracker()->extensions().at(kExtensionId1).status, ForceInstalledTracker::ExtensionStatus::PENDING); EXPECT_EQ(force_installed_tracker()->extensions().at(kExtensionId2).status, @@ -155,7 +155,7 @@ // This test verifies that resetting the policy before all force installed // extensions are either loaded or failed does not call the observers. TEST_F(ForceInstalledTrackerTest, ExtensionsInstallationCancelled) { - SetupForceList(); + SetupForceList(true /*is_from_store */); SetupEmptyForceList(); EXPECT_FALSE(loaded_called_); EXPECT_FALSE(ready_called_); @@ -164,7 +164,7 @@ // This test verifies that READY state observer is called when each force // installed extension is either ready for use or failed. TEST_F(ForceInstalledTrackerTest, AllExtensionsReady) { - SetupForceList(); + SetupForceList(true /*is_from_store */); auto ext1 = ExtensionBuilder(kExtensionName1).SetID(kExtensionId1).Build(); force_installed_tracker()->OnExtensionLoaded(profile(), ext1.get()); force_installed_tracker()->OnExtensionReady(profile(), ext1.get());
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 4b219642..0b9489d 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -251,6 +251,11 @@ "expiry_milestone": 90 }, { + "name": "autofill-assistant-proactive-help", + "owners": [ "//components/autofill_assistant/OWNERS" ], + "expiry_milestone": 90 + }, + { "name": "autofill-cache-query-responses", "owners": [ "rogerm" ], "expiry_milestone": 72 @@ -1252,6 +1257,11 @@ "expiry_milestone": 78 }, { + "name": "enable-autofill-save-card-info-bar-account-indication-footer", + "owners": [ "annelim@google.com, mdjones@chromium.org"], + "expiry_milestone": 95 + }, + { "name": "enable-autofill-upi-vpa", "owners": [ "cfroussios" ], "expiry_milestone": 88
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 19d505b..493c5f2e 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -524,6 +524,12 @@ "When enabled, a footer indicating user's e-mail address will appear at " "the bottom of corresponding password InfoBars."; +const char kEnableAutofillSaveCardInfoBarAccountIndicationFooterName[] = + "Display SaveCardInfoBar footer with account indication information"; +const char kEnableAutofillSaveCardInfoBarAccountIndicationFooterDescription[] = + "When enabled, a footer indicating user's e-mail address will appear at " + "the bottom of SaveCardInfoBar."; + const char kEnableAutofillCreditCardCvcPromptGoogleLogoName[] = "Enable Google Pay branding on CVC prompt on Android"; const char kEnableAutofillCreditCardCvcPromptGoogleLogoDescription[] = @@ -2554,6 +2560,11 @@ const char kAutofillAssistantDirectActionsDescription[] = "When enabled, expose direct actions from the Autofill Assistant."; +const char kAutofillAssistantProactiveHelpName[] = + "Autofill Assistant proactive help"; +const char kAutofillAssistantProactiveHelpDescription[] = + "When enabled, allows the Autofill Assistant to proactively trigger."; + const char kAutofillUseMobileLabelDisambiguationName[] = "Autofill Uses Mobile Label Disambiguation"; const char kAutofillUseMobileLabelDisambiguationDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 0052f06..1356aea 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -332,6 +332,10 @@ extern const char kEnableAutofillPasswordInfoBarAccountIndicationFooterDescription[]; +extern const char kEnableAutofillSaveCardInfoBarAccountIndicationFooterName[]; +extern const char + kEnableAutofillSaveCardInfoBarAccountIndicationFooterDescription[]; + extern const char kEnableExperimentalCookieFeaturesName[]; extern const char kEnableExperimentalCookieFeaturesDescription[]; @@ -1491,6 +1495,9 @@ extern const char kAutofillAssistantDirectActionsName[]; extern const char kAutofillAssistantDirectActionsDescription[]; +extern const char kAutofillAssistantProactiveHelpName[]; +extern const char kAutofillAssistantProactiveHelpDescription[]; + extern const char kAutofillUseMobileLabelDisambiguationName[]; extern const char kAutofillUseMobileLabelDisambiguationDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 268f276..f8cb585f 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -69,6 +69,7 @@ &autofill::features::kAutofillCreditCardAuthentication, &autofill::features::kAutofillDownstreamCvcPromptUseGooglePayLogo, &autofill::features::kAutofillEnablePasswordInfoBarAccountIndicationFooter, + &autofill::features::kAutofillEnableSaveCardInfoBarAccountIndicationFooter, &autofill::features::kAutofillKeyboardAccessory, &autofill::features::kAutofillManualFallbackAndroid, &autofill::features::kAutofillRefreshStyleAndroid, @@ -77,6 +78,7 @@ &autofill_assistant::features::kAutofillAssistant, &autofill_assistant::features::kAutofillAssistantChromeEntry, &autofill_assistant::features::kAutofillAssistantDirectActions, + &autofill_assistant::features::kAutofillAssistantProactiveHelp, &device::kWebAuthPhoneSupport, &download::features::kDownloadAutoResumptionNative, &download::features::kDownloadLater,
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index c9326412..4cd05d4 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -203,6 +203,8 @@ "AutofillEnableGoogleIssuedCard"; public static final String AUTOFILL_ENABLE_PASSWORD_INFO_BAR_ACCOUNT_INDICATION_FOOTER = "AutofillEnablePasswordInfoBarAccountIndicationFooter"; + public static final String AUTOFILL_ENABLE_SAVE_CARD_INFO_BAR_ACCOUNT_INDICATION_FOOTER = + "AutofillEnableSaveCardInfoBarAccountIndicationFooter"; public static final String ADJUST_WEBAPK_INSTALLATION_SPACE = "AdjustWebApkInstallationSpace"; public static final String ANDROID_DEFAULT_BROWSER_PROMO = "AndroidDefaultBrowserPromo"; public static final String ANDROID_MANAGED_BY_MENU_ITEM = "AndroidManagedByMenuItem"; @@ -217,6 +219,7 @@ public static final String AUTOFILL_ASSISTANT = "AutofillAssistant"; public static final String AUTOFILL_ASSISTANT_CHROME_ENTRY = "AutofillAssistantChromeEntry"; public static final String AUTOFILL_ASSISTANT_DIRECT_ACTIONS = "AutofillAssistantDirectActions"; + public static final String AUTOFILL_ASSISTANT_PROACTIVE_HELP = "AutofillAssistantProactiveHelp"; public static final String AUTOFILL_MANUAL_FALLBACK_ANDROID = "AutofillManualFallbackAndroid"; public static final String AUTOFILL_REFRESH_STYLE_ANDROID = "AutofillRefreshStyleAndroid"; public static final String AUTOFILL_KEYBOARD_ACCESSORY = "AutofillKeyboardAccessory";
diff --git a/chrome/browser/media/media_engagement_service_unittest.cc b/chrome/browser/media/media_engagement_service_unittest.cc index 716f3c9..7aaf2f62 100644 --- a/chrome/browser/media/media_engagement_service_unittest.cc +++ b/chrome/browser/media/media_engagement_service_unittest.cc
@@ -62,11 +62,9 @@ } // Overridden from content_settings::Observer: - void OnContentSettingChanged( - const ContentSettingsPattern& primary_pattern, - const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override { + void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, + const ContentSettingsPattern& secondary_pattern, + ContentSettingsType content_type) override { if (content_type == ContentSettingsType::MEDIA_ENGAGEMENT) Proceed(); }
diff --git a/chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context.cc b/chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context.cc index 9686e76..4f24912 100644 --- a/chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context.cc +++ b/chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context.cc
@@ -72,8 +72,7 @@ void CameraPanTiltZoomPermissionContext::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { if (content_type != ContentSettingsType::MEDIASTREAM_CAMERA && content_type != ContentSettingsType::CAMERA_PAN_TILT_ZOOM) { return;
diff --git a/chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context.h b/chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context.h index 6b527ca4..96ad4743 100644 --- a/chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context.h +++ b/chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context.h
@@ -46,8 +46,7 @@ // content_settings::Observer void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // Returns true if at least one video capture device has PTZ capabilities. // Otherwise returns false.
diff --git a/chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context_unittest.cc b/chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context_unittest.cc index 74c65a3..717129c8 100644 --- a/chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context_unittest.cc +++ b/chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context_unittest.cc
@@ -33,11 +33,9 @@ this); } - void OnContentSettingChanged( - const ContentSettingsPattern& primary_pattern, - const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override { + void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, + const ContentSettingsPattern& secondary_pattern, + ContentSettingsType content_type) override { if (content_type == content_type_) Proceed(); }
diff --git a/chrome/browser/metrics/family_user_metrics_provider_browsertest.cc b/chrome/browser/metrics/family_user_metrics_provider_browsertest.cc index da0caca..403c10b2 100644 --- a/chrome/browser/metrics/family_user_metrics_provider_browsertest.cc +++ b/chrome/browser/metrics/family_user_metrics_provider_browsertest.cc
@@ -117,6 +117,7 @@ base::test::ScopedFeatureList scoped_feature_list_; }; +// TODO(crbug/1144651): Test disabled due to flaky failures. IN_PROC_BROWSER_TEST_P(FamilyUserMetricsProviderTest, DISABLED_UserCategory) { base::HistogramTester histogram_tester; // Simulate calling ProvideCurrentSessionData() prior to logging in.
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index c68ed423..fc3a18d 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -858,8 +858,7 @@ void ProfileNetworkContextService::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { switch (content_type) { case ContentSettingsType::COOKIES: UpdateCookieSettings(profile_);
diff --git a/chrome/browser/net/profile_network_context_service.h b/chrome/browser/net/profile_network_context_service.h index ffe1217..bc4fda4 100644 --- a/chrome/browser/net/profile_network_context_service.h +++ b/chrome/browser/net/profile_network_context_service.h
@@ -152,8 +152,7 @@ // content_settings::Observer: void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // content_settings::CookieSettings::Observer: void OnThirdPartyCookieBlockingChanged(
diff --git a/chrome/browser/notifications/notification_channels_provider_android_unittest.cc b/chrome/browser/notifications/notification_channels_provider_android_unittest.cc index e519a16..72a695d 100644 --- a/chrome/browser/notifications/notification_channels_provider_android_unittest.cc +++ b/chrome/browser/notifications/notification_channels_provider_android_unittest.cc
@@ -340,7 +340,7 @@ // Create channel as enabled initially - this should notify the mock observer. EXPECT_CALL(mock_observer, OnContentSettingChanged( - _, _, ContentSettingsType::NOTIFICATIONS, "")); + _, _, ContentSettingsType::NOTIFICATIONS)); channels_provider_->SetWebsiteSetting( ContentSettingsPattern::FromString("https://example.com"), ContentSettingsPattern(), ContentSettingsType::NOTIFICATIONS, @@ -353,7 +353,7 @@ // Observer should be notified on first invocation of GetRuleIterator. EXPECT_CALL(mock_observer, OnContentSettingChanged( - _, _, ContentSettingsType::NOTIFICATIONS, "")); + _, _, ContentSettingsType::NOTIFICATIONS)); channels_provider_->GetRuleIterator(ContentSettingsType::NOTIFICATIONS, std::string(), false /* incognito */); content::RunAllTasksUntilIdle(); @@ -388,9 +388,9 @@ ContentSettingsType::NOTIFICATIONS, std::string())); EXPECT_CALL(mock_observer, - OnContentSettingChanged( - ContentSettingsPattern(), ContentSettingsPattern(), - ContentSettingsType::NOTIFICATIONS, std::string())); + OnContentSettingChanged(ContentSettingsPattern(), + ContentSettingsPattern(), + ContentSettingsType::NOTIFICATIONS)); channels_provider_->ClearAllContentSettingsRules( ContentSettingsType::NOTIFICATIONS);
diff --git a/chrome/browser/notifications/notification_platform_bridge_mac_unnotification_unittest.mm b/chrome/browser/notifications/notification_platform_bridge_mac_unnotification_unittest.mm new file mode 100644 index 0000000..8d2ca954 --- /dev/null +++ b/chrome/browser/notifications/notification_platform_bridge_mac_unnotification_unittest.mm
@@ -0,0 +1,494 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import <UserNotifications/UserNotifications.h> + +#include "base/bind.h" +#include "base/mac/scoped_nsobject.h" +#include "base/run_loop.h" +#include "base/strings/utf_string_conversions.h" +#include "base/test/bind.h" +#include "chrome/browser/notifications/notification_platform_bridge_mac_unnotification.h" +#include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h" +#include "chrome/browser/ui/cocoa/notifications/unnotification_builder_mac.h" +#include "chrome/browser/ui/cocoa/notifications/unnotification_response_builder_mac.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/gtest_mac.h" +#include "ui/message_center/public/cpp/notification.h" +#include "url/gurl.h" + +// TODO(crbug/1146412): Move the mock classes to a separate file to avoid name +// clashes. +API_AVAILABLE(macosx(10.14)) +@interface FakeNotification : NSObject +@property(nonatomic, retain) UNNotificationRequest* request; +@end + +@implementation FakeNotification +@synthesize request; +@end + +API_AVAILABLE(macosx(10.14)) +@interface FakeUNUserNotificationCenter : NSObject +- (instancetype)init; +// Need to provide a nop implementation of setDelegate as it is +// used during the setup of the bridge. +- (void)setDelegate:(id<UNUserNotificationCenterDelegate>)delegate; +- (void)removeAllDeliveredNotifications; +- (void)setNotificationCategories:(NSSet<UNNotificationCategory*>*)categories; +- (void)replaceContentForRequestWithIdentifier:(NSString*)requestIdentifier + replacementContent: + (UNMutableNotificationContent*)content + completionHandler: + (void (^)(NSError* _Nullable error)) + notificationDelivered; +- (void)addNotificationRequest:(UNNotificationRequest*)request + withCompletionHandler:(void (^)(NSError* error))completionHandler; +- (void)getDeliveredNotificationsWithCompletionHandler: + (void (^)(NSArray<UNNotification*>* notifications))completionHandler; +- (void)getNotificationCategoriesWithCompletionHandler: + (void (^)(NSSet<UNNotificationCategory*>* categories))completionHandler; +- (void)requestAuthorizationWithOptions:(UNAuthorizationOptions)options + completionHandler:(void (^)(BOOL granted, NSError* error)) + completionHandler; +- (void)removeDeliveredNotificationsWithIdentifiers: + (NSArray<NSString*>*)identifiers; +@end + +@implementation FakeUNUserNotificationCenter { + base::scoped_nsobject<NSMutableArray> _banners; + base::scoped_nsobject<NSSet> _categories; +} + +- (instancetype)init { + if ((self = [super init])) { + _banners.reset([[NSMutableArray alloc] init]); + _categories.reset([[NSSet alloc] init]); + } + return self; +} + +- (void)setDelegate:(id<UNUserNotificationCenterDelegate>)delegate { +} + +- (void)removeAllDeliveredNotifications { + [_banners removeAllObjects]; +} + +- (void)setNotificationCategories:(NSSet<UNNotificationCategory*>*)categories { + _categories.reset([categories copy]); +} + +- (void)replaceContentForRequestWithIdentifier:(NSString*)requestIdentifier + replacementContent: + (UNMutableNotificationContent*)content + completionHandler: + (void (^)(NSError* _Nullable error)) + notificationDelivered { + UNNotificationRequest* request = + [UNNotificationRequest requestWithIdentifier:requestIdentifier + content:content + trigger:nil]; + base::scoped_nsobject<FakeNotification> notification( + [[FakeNotification alloc] init]); + [notification setRequest:request]; + [_banners addObject:notification]; + notificationDelivered(/*error=*/nil); +} + +- (void)addNotificationRequest:(UNNotificationRequest*)request + withCompletionHandler:(void (^)(NSError* error))completionHandler { + base::scoped_nsobject<FakeNotification> notification( + [[FakeNotification alloc] init]); + [notification setRequest:request]; + [_banners addObject:notification]; + completionHandler(/*error=*/nil); +} + +- (void)getDeliveredNotificationsWithCompletionHandler: + (void (^)(NSArray<UNNotification*>* notifications))completionHandler { + completionHandler([[_banners copy] autorelease]); +} + +- (void)getNotificationCategoriesWithCompletionHandler: + (void (^)(NSSet<UNNotificationCategory*>* categories))completionHandler { + completionHandler([[_categories copy] autorelease]); +} + +- (void)requestAuthorizationWithOptions:(UNAuthorizationOptions)options + completionHandler:(void (^)(BOOL granted, NSError* error)) + completionHandler { + completionHandler(/*granted=*/YES, /*error=*/nil); +} + +- (void)removeDeliveredNotificationsWithIdentifiers: + (NSArray<NSString*>*)identifiers { + [_banners filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL( + UNNotification* notification, + NSDictionary* bindings) { + NSString* toastId = [[[[notification request] content] userInfo] + objectForKey:notification_constants::kNotificationId]; + return ![identifiers containsObject:toastId]; + }]]; +} +@end + +using message_center::Notification; + +class UNNotificationPlatformBridgeMacTest : public testing::Test { + public: + UNNotificationPlatformBridgeMacTest() + : manager_(TestingBrowserProcess::GetGlobal()) {} + + void SetUp() override { + ASSERT_TRUE(manager_.SetUp()); + profile_ = manager_.CreateTestingProfile("Moe"); + if (@available(macOS 10.14, *)) { + center_.reset([[FakeUNUserNotificationCenter alloc] init]); + bridge_ = std::make_unique<NotificationPlatformBridgeMacUNNotification>( + static_cast<UNUserNotificationCenter*>(center_.get())); + } + } + + protected: + Notification CreateNotification(const std::string& notificationId = "id1") { + GURL url("https://gmail.com"); + + Notification notification( + message_center::NOTIFICATION_TYPE_SIMPLE, notificationId, + base::UTF8ToUTF16("Title"), base::UTF8ToUTF16("Context"), gfx::Image(), + base::UTF8ToUTF16("Notifier's Name"), url, + message_center::NotifierId(url), message_center::RichNotificationData(), + base::MakeRefCounted<message_center::NotificationDelegate>()); + + return notification; + } + + API_AVAILABLE(macosx(10.14)) + base::scoped_nsobject<FakeUNUserNotificationCenter> center_; + API_AVAILABLE(macosx(10.14)) + std::unique_ptr<NotificationPlatformBridgeMacUNNotification> bridge_; + TestingProfile* profile_ = nullptr; + + private: + content::BrowserTaskEnvironment task_environment_; + TestingProfileManager manager_; +}; + +TEST_F(UNNotificationPlatformBridgeMacTest, TestDisplay) { + if (@available(macOS 10.14, *)) { + Notification notification = CreateNotification(); + + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + notification, nullptr); + + [center_ getDeliveredNotificationsWithCompletionHandler:^( + NSArray<UNNotification*>* _Nonnull notifications) { + ASSERT_EQ(1u, [notifications count]); + UNNotification* delivered_notification = [notifications objectAtIndex:0]; + UNNotificationContent* delivered_content = + [[delivered_notification request] content]; + EXPECT_NSEQ(@"Title", [delivered_content title]); + EXPECT_NSEQ(@"Context", [delivered_content body]); + EXPECT_NSEQ(@"gmail.com", [delivered_content subtitle]); + }]; + + [center_ getNotificationCategoriesWithCompletionHandler:^( + NSSet<UNNotificationCategory*>* categories) { + EXPECT_EQ(1u, [categories count]); + }]; + } +} + +TEST_F(UNNotificationPlatformBridgeMacTest, TestNotificationHasIcon) { + if (@available(macOS 10.14, *)) { + Notification notification = CreateNotification(); + + SkBitmap icon; + icon.allocN32Pixels(64, 64); + icon.eraseARGB(255, 100, 150, 200); + notification.set_icon(gfx::Image::CreateFrom1xBitmap(icon)); + + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + notification, nullptr); + + [center_ getDeliveredNotificationsWithCompletionHandler:^( + NSArray<UNNotification*>* _Nonnull notifications) { + ASSERT_EQ(1u, [notifications count]); + UNNotification* delivered_notification = [notifications objectAtIndex:0]; + UNNotificationContent* delivered_content = + [[delivered_notification request] content]; + ASSERT_EQ(1u, [[delivered_content attachments] count]); + EXPECT_NSEQ(@"id1", [[[delivered_content attachments] objectAtIndex:0] + identifier]); + }]; + } +} + +TEST_F(UNNotificationPlatformBridgeMacTest, TestNotificationNoIcon) { + if (@available(macOS 10.14, *)) { + Notification notification = CreateNotification(); + + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + notification, nullptr); + + [center_ getDeliveredNotificationsWithCompletionHandler:^( + NSArray<UNNotification*>* _Nonnull notifications) { + ASSERT_EQ(1u, [notifications count]); + UNNotification* delivered_notification = [notifications objectAtIndex:0]; + UNNotificationContent* delivered_content = + [[delivered_notification request] content]; + EXPECT_EQ(0u, [[delivered_content attachments] count]); + }]; + } +} + +TEST_F(UNNotificationPlatformBridgeMacTest, TestCloseNotification) { + if (@available(macOS 10.14, *)) { + Notification notification = CreateNotification(); + + [center_ getDeliveredNotificationsWithCompletionHandler:^( + NSArray<UNNotification*>* _Nonnull notifications) { + EXPECT_EQ(0u, [notifications count]); + }]; + + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + notification, nullptr); + + [center_ getDeliveredNotificationsWithCompletionHandler:^( + NSArray<UNNotification*>* _Nonnull notifications) { + EXPECT_EQ(1u, [notifications count]); + }]; + + bridge_->Close(profile_, "id1"); + // RunLoop is used here to ensure that Close has finished executing before + // the notification count is checked below. Since Close executes + // asynchronous calls the order is not guaranteed by nature. + base::RunLoop().RunUntilIdle(); + [center_ getDeliveredNotificationsWithCompletionHandler:^( + NSArray<UNNotification*>* _Nonnull notifications) { + EXPECT_EQ(0u, [notifications count]); + }]; + } +} + +TEST_F(UNNotificationPlatformBridgeMacTest, TestGetDisplayed) { + if (@available(macOS 10.14, *)) { + Notification notification = CreateNotification(); + + [center_ getDeliveredNotificationsWithCompletionHandler:^( + NSArray<UNNotification*>* _Nonnull notifications) { + EXPECT_EQ(0u, [notifications count]); + }]; + + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + notification, nullptr); + + [center_ getDeliveredNotificationsWithCompletionHandler:^( + NSArray<UNNotification*>* _Nonnull notifications) { + EXPECT_EQ(1u, [notifications count]); + }]; + + base::RunLoop run_loop; + int notification_count = -1; + bridge_->GetDisplayed( + profile_, + base::BindLambdaForTesting([&](std::set<std::string> notifications, + bool supports_synchronization) { + notification_count = notifications.size(); + run_loop.Quit(); + })); + run_loop.Run(); + EXPECT_EQ(1, notification_count); + } +} + +TEST_F(UNNotificationPlatformBridgeMacTest, + TestGetDisplayedMultipleNotifications) { + if (@available(macOS 10.14, *)) { + Notification first_notification = CreateNotification("id1"); + + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + first_notification, nullptr); + + Notification second_notification = CreateNotification("id2"); + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + second_notification, nullptr); + + base::RunLoop run_loop; + int notification_count = -1; + bridge_->GetDisplayed( + profile_, + base::BindLambdaForTesting([&](std::set<std::string> notifications, + bool supports_synchronization) { + notification_count = notifications.size(); + run_loop.Quit(); + })); + run_loop.Run(); + EXPECT_EQ(2, notification_count); + + [center_ getNotificationCategoriesWithCompletionHandler:^( + NSSet<UNNotificationCategory*>* categories) { + EXPECT_EQ(2u, [categories count]); + }]; + } +} + +TEST_F(UNNotificationPlatformBridgeMacTest, TestQuitRemovesNotifications) { + if (@available(macOS 10.14, *)) { + Notification notification = CreateNotification(); + + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + notification, nullptr); + + [center_ getDeliveredNotificationsWithCompletionHandler:^( + NSArray<UNNotification*>* _Nonnull notifications) { + EXPECT_EQ(1u, [notifications count]); + }]; + + bridge_.reset(); + + // The destructor of the bridge_ will call removeAllDeliveredNotifications. + [center_ getDeliveredNotificationsWithCompletionHandler:^( + NSArray<UNNotification*>* _Nonnull notifications) { + EXPECT_EQ(0u, [notifications count]); + }]; + } +} + +TEST_F(UNNotificationPlatformBridgeMacTest, TestNotificationNoButtons) { + if (@available(macOS 10.14, *)) { + Notification notification = CreateNotification(); + + notification.set_settings_button_handler( + message_center::SettingsButtonHandler::DELEGATE); + + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + notification, nullptr); + + [center_ getNotificationCategoriesWithCompletionHandler:^( + NSSet<UNNotificationCategory*>* categories) { + ASSERT_EQ(1u, [categories count]); + UNNotificationCategory* category = [categories anyObject]; + // If this selector from the private API is available the close button + // will be set in alernateAction, and the other buttons will be set in + // actions. Otherwise, all buttons will be setting in actions which causes + // the total count to differ by one. + if ([category respondsToSelector:@selector(alternateAction)]) { + ASSERT_EQ(1ul, [[category actions] count]); + EXPECT_NSEQ(@"Close", + [[category valueForKey:@"_alternateAction"] title]); + EXPECT_NSEQ(@"Settings", [[[category actions] lastObject] title]); + } else { + ASSERT_EQ(2ul, [[category actions] count]); + EXPECT_NSEQ(@"Close", [[[category actions] lastObject] title]); + EXPECT_NSEQ(@"Settings", [[[category actions] firstObject] title]); + } + }]; + } +} + +TEST_F(UNNotificationPlatformBridgeMacTest, TestNotificationNoSettingsButton) { + if (@available(macOS 10.14, *)) { + Notification notification = CreateNotification(); + + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + notification, nullptr); + + [center_ getNotificationCategoriesWithCompletionHandler:^( + NSSet<UNNotificationCategory*>* categories) { + ASSERT_EQ(1u, [categories count]); + UNNotificationCategory* category = [categories anyObject]; + + if ([category respondsToSelector:@selector(alternateAction)]) + EXPECT_EQ(0ul, [[category actions] count]); + else + EXPECT_EQ(1ul, [[category actions] count]); + }]; + } +} + +TEST_F(UNNotificationPlatformBridgeMacTest, TestNotificationWithButtons) { + if (@available(macOS 10.14, *)) { + Notification notification = CreateNotification(); + + notification.set_settings_button_handler( + message_center::SettingsButtonHandler::DELEGATE); + std::vector<message_center::ButtonInfo> buttons = { + message_center::ButtonInfo(base::UTF8ToUTF16("Button 1")), + message_center::ButtonInfo(base::UTF8ToUTF16("Button 2"))}; + notification.set_buttons(buttons); + + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + notification, nullptr); + + [center_ getNotificationCategoriesWithCompletionHandler:^( + NSSet<UNNotificationCategory*>* categories) { + ASSERT_EQ(1u, [categories count]); + UNNotificationCategory* category = [categories anyObject]; + + if ([category respondsToSelector:@selector(alternateAction)]) { + EXPECT_NSEQ(@"Button 1", [[category actions][0] title]); + EXPECT_NSEQ(@"Button 2", [[category actions][1] title]); + EXPECT_EQ(3ul, [[category actions] count]); + } else { + EXPECT_NSEQ(@"Button 1", [[category actions][1] title]); + EXPECT_NSEQ(@"Button 2", [[category actions][2] title]); + EXPECT_EQ(4ul, [[category actions] count]); + } + }]; + } +} + +TEST_F(UNNotificationPlatformBridgeMacTest, + TestNotificationCategoryIdentifier) { + if (@available(macOS 10.14, *)) { + Notification notification = CreateNotification(); + + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + notification, nullptr); + + [center_ getNotificationCategoriesWithCompletionHandler:^( + NSSet<UNNotificationCategory*>* categories) { + ASSERT_EQ(1u, [categories count]); + EXPECT_NSEQ(@"id1", [[categories anyObject] identifier]); + }]; + } +} + +TEST_F(UNNotificationPlatformBridgeMacTest, TestCloseRemovesCategory) { + if (@available(macOS 10.14, *)) { + Notification first_notification = CreateNotification(); + + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + first_notification, nullptr); + + [center_ getNotificationCategoriesWithCompletionHandler:^( + NSSet<UNNotificationCategory*>* categories) { + EXPECT_EQ(1u, [categories count]); + }]; + + bridge_->Close(profile_, "id1"); + // RunLoop is used here to ensure that Close has finished executing before + // the notification count is checked below. Since Close executes + // asynchronous calls the order is not guaranteed by nature. + base::RunLoop().RunUntilIdle(); + + // Categories get updated during the next display call, so we call display + // to make sure that the category has been removed. + Notification second_notification = CreateNotification("id2"); + bridge_->Display(NotificationHandler::Type::WEB_PERSISTENT, profile_, + second_notification, nullptr); + + [center_ getNotificationCategoriesWithCompletionHandler:^( + NSSet<UNNotificationCategory*>* categories) { + ASSERT_EQ(1u, [categories count]); + EXPECT_NSEQ(@"id2", [[categories anyObject] identifier]); + }]; + } +}
diff --git a/chrome/browser/notifications/platform_notification_service_impl.cc b/chrome/browser/notifications/platform_notification_service_impl.cc index 4f3053f1..eda7203 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.cc +++ b/chrome/browser/notifications/platform_notification_service_impl.cc
@@ -164,8 +164,7 @@ void PlatformNotificationServiceImpl::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (content_type != ContentSettingsType::NOTIFICATIONS)
diff --git a/chrome/browser/notifications/platform_notification_service_impl.h b/chrome/browser/notifications/platform_notification_service_impl.h index 926349b..0c4baf0 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.h +++ b/chrome/browser/notifications/platform_notification_service_impl.h
@@ -99,8 +99,7 @@ // content_settings::Observer implementation. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; static void DidGetBackgroundSourceId( base::OnceClosure recorded_closure,
diff --git a/chrome/browser/password_manager/android/password_accessory_controller_impl.cc b/chrome/browser/password_manager/android/password_accessory_controller_impl.cc index dae8be30..a3390462 100644 --- a/chrome/browser/password_manager/android/password_accessory_controller_impl.cc +++ b/chrome/browser/password_manager/android/password_accessory_controller_impl.cc
@@ -314,7 +314,7 @@ autofill::AccessoryTabType::PASSWORDS, GetTitle(has_suggestions, origin), std::move(info_to_add), std::move(footer_commands_to_add)); - if (ShouldShowRecoveryToggle(focused_field_type, origin)) { + if (ShouldShowRecoveryToggle(origin)) { BlacklistedStatus blacklisted_status = credential_cache_->GetCredentialStore(origin).GetBlacklistedStatus(); if (blacklisted_status == BlacklistedStatus::kWasBlacklisted || @@ -392,7 +392,6 @@ } bool PasswordAccessoryControllerImpl::ShouldShowRecoveryToggle( - autofill::mojom::FocusedFieldType field_type, const url::Origin& origin) const { if (!base::FeatureList::IsEnabled( password_manager::features::kRecoverFromNeverSaveAndroid)) { @@ -402,10 +401,7 @@ autofill::features::kAutofillKeyboardAccessory)) { return false; } - if (!password_client_->IsSavingAndFillingEnabled(origin.GetURL())) - return false; - return field_type == FocusedFieldType::kFillablePasswordField || - field_type == FocusedFieldType::kFillableUsernameField; + return password_client_->IsSavingAndFillingEnabled(origin.GetURL()); } base::WeakPtr<ManualFillingController>
diff --git a/chrome/browser/password_manager/android/password_accessory_controller_impl.h b/chrome/browser/password_manager/android/password_accessory_controller_impl.h index 441d855..30bbbff 100644 --- a/chrome/browser/password_manager/android/password_accessory_controller_impl.h +++ b/chrome/browser/password_manager/android/password_accessory_controller_impl.h
@@ -114,10 +114,9 @@ bool is_password, const url::Origin& origin) const; - // Returns true if `field_type` and `origin` of a focused field allow to show + // Returns true if the `origin` of a focused field allows to show // the option toggle to recover from a "never save" state. - bool ShouldShowRecoveryToggle(autofill::mojom::FocusedFieldType field_type, - const url::Origin& origin) const; + bool ShouldShowRecoveryToggle(const url::Origin& origin) const; // Lazy-initializes and returns the ManualFillingController for the current // |web_contents_|. The lazy initialization allows injecting mocks for tests.
diff --git a/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc b/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc index 79491bd9..55d0f97 100644 --- a/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc +++ b/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc
@@ -745,7 +745,7 @@ /*is_manual_generation_available=*/false); } -TEST_F(PasswordAccessoryControllerTest, AddsSaveToggleOnUsernameIfBlacklisted) { +TEST_F(PasswordAccessoryControllerTest, AddsSaveToggleOnAnyFieldIfBlocked) { CreateSheetController(); base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitWithFeatures( @@ -768,7 +768,7 @@ EXPECT_CALL(mock_manual_filling_controller_, RefreshSuggestions(std::move(data_builder).Build())); controller()->RefreshSuggestionsForField( - FocusedFieldType::kFillableUsernameField, + FocusedFieldType::kFillableNonSearchField, /*is_manual_generation_available=*/false); }
diff --git a/chrome/browser/password_manager/password_store_factory.cc b/chrome/browser/password_manager/password_store_factory.cc index dd9dc301..7a9f696 100644 --- a/chrome/browser/password_manager/password_store_factory.cc +++ b/chrome/browser/password_manager/password_store_factory.cc
@@ -36,13 +36,6 @@ #if defined(OS_WIN) #include "chrome/browser/password_manager/password_manager_util_win.h" -#elif defined(OS_MAC) -// Use default store. -#elif defined(OS_CHROMEOS) || defined(OS_ANDROID) -// Don't do anything. We're going to use the default store. -#elif defined(USE_X11) -#include "chrome/browser/password_manager/password_store_x.h" -#include "ui/base/ui_base_features.h" #endif #if defined(PASSWORD_REUSE_DETECTION_ENABLED) @@ -53,11 +46,6 @@ namespace { -#if defined(USE_X11) -constexpr PasswordStoreX::MigrationToLoginDBStep - kMigrationToLoginDBNotAttempted = PasswordStoreX::NOT_ATTEMPTED; -#endif - #if defined(PASSWORD_REUSE_DETECTION_ENABLED) std::string GetSyncUsername(Profile* profile) { auto* identity_manager = @@ -149,16 +137,8 @@ #endif scoped_refptr<PasswordStore> ps; -#if defined(OS_WIN) - ps = new password_manager::PasswordStoreDefault(std::move(login_db)); -#elif defined(OS_CHROMEOS) || defined(OS_ANDROID) || defined(OS_MAC) - ps = new password_manager::PasswordStoreDefault(std::move(login_db)); -#elif defined(USE_X11) - if (features::IsUsingOzonePlatform()) - ps = new password_manager::PasswordStoreDefault(std::move(login_db)); - else - ps = new PasswordStoreX(std::move(login_db), profile->GetPrefs()); -#elif defined(USE_OZONE) +#if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ + defined(OS_MAC) || defined(USE_X11) || defined(USE_OZONE) ps = new password_manager::PasswordStoreDefault(std::move(login_db)); #else NOTIMPLEMENTED(); @@ -198,19 +178,6 @@ return ps; } -void PasswordStoreFactory::RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) { -#if defined(USE_X11) - if (!features::IsUsingOzonePlatform()) { - // Notice that the preprocessor conditions above are exactly those that will - // result in using PasswordStoreX in BuildServiceInstanceFor(). - registry->RegisterIntegerPref( - password_manager::prefs::kMigrationToLoginDBStep, - kMigrationToLoginDBNotAttempted); - } -#endif -} - content::BrowserContext* PasswordStoreFactory::GetBrowserContextToUse( content::BrowserContext* context) const { return chrome::GetBrowserContextRedirectedInIncognito(context);
diff --git a/chrome/browser/password_manager/password_store_factory.h b/chrome/browser/password_manager/password_store_factory.h index 74366f87..472a674a2 100644 --- a/chrome/browser/password_manager/password_store_factory.h +++ b/chrome/browser/password_manager/password_store_factory.h
@@ -43,8 +43,6 @@ // RefcountedBrowserContextKeyedServiceFactory: scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor( content::BrowserContext* context) const override; - void RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) override; content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override; bool ServiceIsNULLWhileTesting() const override;
diff --git a/chrome/browser/password_manager/password_store_x.cc b/chrome/browser/password_manager/password_store_x.cc deleted file mode 100644 index cedb573f..0000000 --- a/chrome/browser/password_manager/password_store_x.cc +++ /dev/null
@@ -1,250 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/password_manager/password_store_x.h" - -#include <algorithm> -#include <map> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/memory/weak_ptr.h" -#include "base/metrics/histogram_functions.h" -#include "base/stl_util.h" -#include "base/time/time.h" -#include "chrome/browser/chrome_notification_types.h" -#include "components/password_manager/core/browser/password_manager_metrics_util.h" -#include "components/password_manager/core/browser/password_manager_util.h" -#include "components/password_manager/core/browser/password_store_change.h" -#include "components/password_manager/core/common/password_manager_features.h" -#include "components/password_manager/core/common/password_manager_pref_names.h" -#include "components/pref_registry/pref_registry_syncable.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/notification_service.h" - -using password_manager::PasswordForm; -using password_manager::PasswordStoreChange; -using password_manager::PasswordStoreChangeList; -using password_manager::PasswordStoreDefault; - -namespace { - -// Reads and rewrites every entry in |login_db|, reading unecrypted and writing -// encrypted. This should run in a transaction. Returns LOGIN_DB_REPLACED on -// success, otherwise the step where the process failed. -PasswordStoreX::MigrationToLoginDBStep EncryptDatabase( - password_manager::LoginDatabase* login_db) { - // Read the unencrypted entries. - login_db->disable_encryption(); - std::map<int, std::unique_ptr<PasswordForm>> logins; - if (login_db->GetAllLogins(&logins) != - password_manager::FormRetrievalResult::kSuccess) { - return PasswordStoreX::FAILED_INIT_ENCRYPTED; - } - - // Re-insert the entries, encrypted this time. - login_db->enable_encryption(); - for (const auto& password_form : logins) { - password_manager::UpdateLoginError error; - PasswordStoreChangeList changes = - login_db->UpdateLogin(*password_form.second, &error); - // Check that an existing entry was replaced. - if (error != password_manager::UpdateLoginError::kNone || changes.empty() || - changes[0].type() != password_manager::PasswordStoreChange::UPDATE) { - return PasswordStoreX::FAILED_WRITE_TO_ENCRYPTED; - } - } - - return PasswordStoreX::LOGIN_DB_REPLACED; -} - -// Reads and rewrites every entry in |login_db|, reading unecrypted and writing -// encrypted. Returns LOGIN_DB_REPLACED on success, otherwise the step where the -// process failed. -PasswordStoreX::MigrationToLoginDBStep MigrateUnencryptedDatabase( - password_manager::LoginDatabase* login_db) { - if (!login_db->BeginTransaction()) - return PasswordStoreX::POSTPONED; - - PasswordStoreX::MigrationToLoginDBStep encryption_result = - EncryptDatabase(login_db); - - if (encryption_result == PasswordStoreX::LOGIN_DB_REPLACED) { - if (!login_db->CommitTransaction()) { - return PasswordStoreX::FAILED_REPLACE; - } - } else { - login_db->RollbackTransaction(); - } - - return encryption_result; -} - -} // namespace - -PasswordStoreX::PasswordStoreX( - std::unique_ptr<password_manager::LoginDatabase> login_db, - PrefService* prefs) - : PasswordStoreDefault(std::move(login_db)), migration_checked_(false) { - migration_step_pref_.Init(password_manager::prefs::kMigrationToLoginDBStep, - prefs); - migration_to_login_db_step_ = - static_cast<MigrationToLoginDBStep>(migration_step_pref_.GetValue()); -} - -PasswordStoreX::~PasswordStoreX() = default; - -scoped_refptr<base::SequencedTaskRunner> -PasswordStoreX::CreateBackgroundTaskRunner() const { - return PasswordStoreDefault::CreateBackgroundTaskRunner(); -} - -PasswordStoreChangeList PasswordStoreX::AddLoginImpl( - const PasswordForm& form, - password_manager::AddLoginError* error) { - CheckMigration(); - return PasswordStoreDefault::AddLoginImpl(form, error); -} - -PasswordStoreChangeList PasswordStoreX::UpdateLoginImpl( - const PasswordForm& form, - password_manager::UpdateLoginError* error) { - CheckMigration(); - return PasswordStoreDefault::UpdateLoginImpl(form, error); -} - -PasswordStoreChangeList PasswordStoreX::RemoveLoginImpl( - const PasswordForm& form) { - CheckMigration(); - return PasswordStoreDefault::RemoveLoginImpl(form); -} - -PasswordStoreChangeList PasswordStoreX::RemoveLoginsByURLAndTimeImpl( - const base::RepeatingCallback<bool(const GURL&)>& url_filter, - base::Time delete_begin, - base::Time delete_end) { - CheckMigration(); - return PasswordStoreDefault::RemoveLoginsByURLAndTimeImpl( - url_filter, delete_begin, delete_end); -} - -PasswordStoreChangeList PasswordStoreX::RemoveLoginsCreatedBetweenImpl( - base::Time delete_begin, - base::Time delete_end) { - CheckMigration(); - return PasswordStoreDefault::RemoveLoginsCreatedBetweenImpl(delete_begin, - delete_end); -} - -PasswordStoreChangeList PasswordStoreX::DisableAutoSignInForOriginsImpl( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter) { - CheckMigration(); - return PasswordStoreDefault::DisableAutoSignInForOriginsImpl(origin_filter); -} - -std::vector<std::unique_ptr<PasswordForm>> PasswordStoreX::FillMatchingLogins( - const FormDigest& form) { - CheckMigration(); - return PasswordStoreDefault::FillMatchingLogins(form); -} - -std::vector<std::unique_ptr<PasswordForm>> -PasswordStoreX::FillMatchingLoginsByPassword( - const base::string16& plain_text_password) { - CheckMigration(); - return PasswordStoreDefault::FillMatchingLoginsByPassword( - plain_text_password); -} - -bool PasswordStoreX::FillAutofillableLogins( - std::vector<std::unique_ptr<PasswordForm>>* forms) { - CheckMigration(); - return PasswordStoreDefault::FillAutofillableLogins(forms); -} - -bool PasswordStoreX::FillBlacklistLogins( - std::vector<std::unique_ptr<PasswordForm>>* forms) { - CheckMigration(); - return PasswordStoreDefault::FillBlacklistLogins(forms); -} - -void PasswordStoreX::CheckMigration() { - DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); - - if (migration_checked_) - return; - migration_checked_ = true; - - if (migration_to_login_db_step_ == LOGIN_DB_REPLACED) { - return; - } - - if (!login_db()) { - LOG(ERROR) << "Could not start the migration into the encrypted " - "LoginDatabase because the database failed to initialise."; - return; - } - - // If the db is empty, there are no records to migrate, and we then can call - // it a completed migration. - if (login_db()->IsEmpty()) { - UpdateMigrationToLoginDBStep(LOGIN_DB_REPLACED); - } else { - // The user has unencrypted entries in their login database. We will try to - // encrypt them. - UpdateMigrationToLoginDBStep(STARTED); - MigrationToLoginDBStep migration_result = - MigrateUnencryptedDatabase(login_db()); - UpdateMigrationToLoginDBStep(migration_result); - // If the migration did not complete, then we will continue using the - // database without encryption. - if (migration_result == LOGIN_DB_REPLACED) - login_db()->enable_encryption(); - else - login_db()->disable_encryption(); - } -} - -void PasswordStoreX::UpdateMigrationToLoginDBStep(MigrationToLoginDBStep step) { - migration_to_login_db_step_ = step; - main_task_runner()->PostTask( - FROM_HERE, base::BindOnce(&PasswordStoreX::UpdateMigrationPref, - weak_ptr_factory_.GetWeakPtr(), - migration_to_login_db_step_)); -} - -void PasswordStoreX::UpdateMigrationPref(MigrationToLoginDBStep step) { - migration_step_pref_.SetValue(step); -} - -void PasswordStoreX::ShutdownOnUIThread() { - migration_step_pref_.Destroy(); - // Invalidate the weak pointer to preempt any posted tasks in - // UpdateMigrationToLoginDBStep() because they cannot use the - // |migration_step_pref_| anymore. Both ShutdownOnUIThread() and - // UpdateMigrationToLoginDBStep() are only executed on the UI thread. - weak_ptr_factory_.InvalidateWeakPtrs(); - PasswordStoreDefault::ShutdownOnUIThread(); -} - -password_manager::FormRetrievalResult PasswordStoreX::ReadAllLogins( - password_manager::PrimaryKeyToFormMap* key_to_form_map) { - CheckMigration(); - return PasswordStoreDefault::ReadAllLogins(key_to_form_map); -} - -PasswordStoreChangeList PasswordStoreX::RemoveLoginByPrimaryKeySync( - int primary_key) { - CheckMigration(); - return PasswordStoreDefault::RemoveLoginByPrimaryKeySync(primary_key); -} - -password_manager::PasswordStoreSync::MetadataStore* -PasswordStoreX::GetMetadataStore() { - CheckMigration(); - return PasswordStoreDefault::GetMetadataStore(); -}
diff --git a/chrome/browser/password_manager/password_store_x.h b/chrome/browser/password_manager/password_store_x.h deleted file mode 100644 index 5f1b5a0..0000000 --- a/chrome/browser/password_manager/password_store_x.h +++ /dev/null
@@ -1,133 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_X_H_ -#define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_X_H_ - -#include <stddef.h> - -#include <memory> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "base/sequenced_task_runner.h" -#include "base/time/time.h" -#include "components/password_manager/core/browser/password_store_default.h" -#include "components/prefs/pref_member.h" - -namespace password_manager { -class LoginDatabase; -} - -// PasswordStoreX is used on Linux and other non-Windows, non-Mac OS X operating -// systems. It is used as a proxy for the PasswordStoreDefault that basically -// takes care of migrating the passwords of the users to login database. Once -// all users are migrated we should delete this class. -class PasswordStoreX : public password_manager::PasswordStoreDefault { - public: - // The state of the migration from native backends and an unencrypted loginDB - // to an encrypted loginDB. - enum MigrationToLoginDBStep { - // Neither started nor failed. - NOT_ATTEMPTED = 0, - // The last attempt was not completed. - DEPRECATED_FAILED, - // All the data is in the temporary encrypted loginDB. - DEPRECATED_COPIED_ALL, - // The standard login database is encrypted. - LOGIN_DB_REPLACED, - // The migration is about to be attempted. This value was deprecated and - // replaced by more price entries. It may still be store in users' - // preferences. - STARTED, - // No access to the native backend. - POSTPONED, - // Could not create or write into the file. - DEPRECATED_FAILED_CREATE_ENCRYPTED, - // Could not read from the native backend. - DEPRECATED_FAILED_ACCESS_NATIVE, - // Could not replace old database. - FAILED_REPLACE, - // Could not initialise the encrypted database. - FAILED_INIT_ENCRYPTED, - // Could not reset the encrypted database. - DEPRECATED_FAILED_RECREATE_ENCRYPTED, - // Could not add entries into the encrypted database. - FAILED_WRITE_TO_ENCRYPTED, - }; - - PasswordStoreX(std::unique_ptr<password_manager::LoginDatabase> login_db, - PrefService* prefs); - - // RefcountedKeyedService: - void ShutdownOnUIThread() override; - - protected: - // Implements PasswordStoreSync interface. - password_manager::FormRetrievalResult ReadAllLogins( - password_manager::PrimaryKeyToFormMap* key_to_form_map) override; - password_manager::PasswordStoreChangeList RemoveLoginByPrimaryKeySync( - int primary_key) override; - password_manager::PasswordStoreSync::MetadataStore* GetMetadataStore() - override; - - private: - ~PasswordStoreX() override; - - // Implements PasswordStore interface. - scoped_refptr<base::SequencedTaskRunner> CreateBackgroundTaskRunner() - const override; - password_manager::PasswordStoreChangeList AddLoginImpl( - const password_manager::PasswordForm& form, - password_manager::AddLoginError* error = nullptr) override; - password_manager::PasswordStoreChangeList UpdateLoginImpl( - const password_manager::PasswordForm& form, - password_manager::UpdateLoginError* error = nullptr) override; - password_manager::PasswordStoreChangeList RemoveLoginImpl( - const password_manager::PasswordForm& form) override; - password_manager::PasswordStoreChangeList RemoveLoginsByURLAndTimeImpl( - const base::RepeatingCallback<bool(const GURL&)>& url_filter, - base::Time delete_begin, - base::Time delete_end) override; - password_manager::PasswordStoreChangeList RemoveLoginsCreatedBetweenImpl( - base::Time delete_begin, - base::Time delete_end) override; - password_manager::PasswordStoreChangeList DisableAutoSignInForOriginsImpl( - const base::RepeatingCallback<bool(const GURL&)>& origin_filter) override; - std::vector<std::unique_ptr<password_manager::PasswordForm>> - FillMatchingLogins(const FormDigest& form) override; - std::vector<std::unique_ptr<password_manager::PasswordForm>> - FillMatchingLoginsByPassword( - const base::string16& plain_text_password) override; - bool FillAutofillableLogins( - std::vector<std::unique_ptr<password_manager::PasswordForm>>* forms) - override; - bool FillBlacklistLogins( - std::vector<std::unique_ptr<password_manager::PasswordForm>>* forms) - override; - - // Checks whether the login database is encrypted or not. - void CheckMigration(); - - // Update |migration_to_login_db_step_| and |migration_step_pref_|. - void UpdateMigrationToLoginDBStep(MigrationToLoginDBStep step); - - // Update |migration_step_pref_|. It must be executed on the preference's - // thread. - void UpdateMigrationPref(MigrationToLoginDBStep step); - - // Whether we have already attempted migration to the native store. - bool migration_checked_; - // Tracks the last completed step in the migration from the native backends to - // LoginDB. - IntegerPrefMember migration_step_pref_; - MigrationToLoginDBStep migration_to_login_db_step_ = NOT_ATTEMPTED; - - base::WeakPtrFactory<PasswordStoreX> weak_ptr_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(PasswordStoreX); -}; - -#endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_X_H_
diff --git a/chrome/browser/password_manager/password_store_x_unittest.cc b/chrome/browser/password_manager/password_store_x_unittest.cc deleted file mode 100644 index d4a7c8d8..0000000 --- a/chrome/browser/password_manager/password_store_x_unittest.cc +++ /dev/null
@@ -1,269 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/password_manager/password_store_x.h" - -#include <stddef.h> - -#include <string> -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/sequenced_task_runner.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/test/task_environment.h" -#include "base/time/time.h" -#include "chrome/test/base/testing_browser_process.h" -#include "components/os_crypt/os_crypt.h" -#include "components/os_crypt/os_crypt_mocker.h" -#include "components/password_manager/core/browser/password_manager_metrics_util.h" -#include "components/password_manager/core/browser/password_manager_test_utils.h" -#include "components/password_manager/core/browser/password_store_change.h" -#include "components/password_manager/core/browser/password_store_consumer.h" -#include "components/password_manager/core/common/password_manager_features.h" -#include "components/password_manager/core/common/password_manager_pref_names.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/prefs/pref_service.h" -#include "components/prefs/testing_pref_service.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using password_manager::FormRetrievalResult; -using password_manager::PasswordForm; -using password_manager::PasswordStoreChange; -using password_manager::PasswordStoreChangeList; -using password_manager::PrimaryKeyToFormMap; -using password_manager::UnorderedPasswordFormElementsAre; -using testing::ElementsAreArray; -using testing::Field; -using testing::IsEmpty; -using testing::Pointee; -using testing::UnorderedElementsAre; - -namespace { - -const char kPassword[] = "password_value"; -const char kUsername[] = "username_value"; -const char kAnotherUsername[] = "another_username_value"; -class MockPasswordStoreConsumer - : public password_manager::PasswordStoreConsumer { - public: - MOCK_METHOD1(OnGetPasswordStoreResultsConstRef, - void(const std::vector<std::unique_ptr<PasswordForm>>&)); - - // GMock cannot mock methods with move-only args. - void OnGetPasswordStoreResults( - std::vector<std::unique_ptr<PasswordForm>> results) override { - OnGetPasswordStoreResultsConstRef(results); - } -}; - -PasswordForm MakePasswordForm() { - PasswordForm form; - form.url = GURL("http://www.origin.com"); - form.username_element = base::UTF8ToUTF16("username_element"); - form.username_value = base::UTF8ToUTF16(kUsername); - form.password_element = base::UTF8ToUTF16("password_element"); - form.password_value = base::UTF8ToUTF16(kPassword); - form.signon_realm = form.url.GetOrigin().spec(); - form.in_store = password_manager::PasswordForm::Store::kProfileStore; - return form; -} - -} // namespace - -class PasswordStoreXTest : public testing::Test { - public: - PasswordStoreXTest() { - ignore_result(temp_dir_.CreateUniqueTempDir()); - fake_pref_service_.registry()->RegisterIntegerPref( - password_manager::prefs::kMigrationToLoginDBStep, - PasswordStoreX::NOT_ATTEMPTED); - OSCryptMocker::SetUp(); - } - - ~PasswordStoreXTest() override { OSCryptMocker::TearDown(); } - - PrefService* fake_pref_service() { return &fake_pref_service_; } - - base::FilePath test_login_db_file_path() const { - return temp_dir_.GetPath().Append(FILE_PATH_LITERAL("login_test")); - } - - void WaitForPasswordStore() { task_environment_.RunUntilIdle(); } - - protected: - base::HistogramTester histogram_tester_; - - private: - TestingPrefServiceSimple fake_pref_service_; - base::test::TaskEnvironment task_environment_; - base::ScopedTempDir temp_dir_; - - DISALLOW_COPY_AND_ASSIGN(PasswordStoreXTest); -}; - -TEST_F(PasswordStoreXTest, MigrationCompleted) { - IntegerPrefMember migration_step_pref_; - migration_step_pref_.Init(password_manager::prefs::kMigrationToLoginDBStep, - fake_pref_service()); - // Signal that the migration has been completed. - migration_step_pref_.SetValue(PasswordStoreX::LOGIN_DB_REPLACED); - - // Add existing credential into loginDB. It should be the only thing that's - // available in the store. - auto login_db = std::make_unique<password_manager::LoginDatabase>( - test_login_db_file_path(), password_manager::IsAccountStore(false)); - ASSERT_TRUE(login_db->Init()); - ignore_result(login_db->AddLogin(MakePasswordForm())); - login_db.reset(); - - // Create the store. - login_db = std::make_unique<password_manager::LoginDatabase>( - test_login_db_file_path(), password_manager::IsAccountStore(false)); - scoped_refptr<PasswordStoreX> store = - new PasswordStoreX(std::move(login_db), fake_pref_service()); - store->Init(nullptr); - - // Check the contents are still around. - MockPasswordStoreConsumer consumer; - EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef( - testing::ElementsAre(Pointee(MakePasswordForm())))); - store->GetAutofillableLogins(&consumer); - - WaitForPasswordStore(); - store->ShutdownOnUIThread(); - store.reset(); - WaitForPasswordStore(); - - // Check if the database is encrypted. - password_manager::LoginDatabase login_db2( - test_login_db_file_path(), password_manager::IsAccountStore(false)); - // Disable encryption. - login_db2.disable_encryption(); - EXPECT_TRUE(login_db2.Init()); - // Read the password again. - std::vector<std::unique_ptr<PasswordForm>> stored_forms; - EXPECT_TRUE(login_db2.GetAutofillableLogins(&stored_forms)); - EXPECT_EQ(1U, stored_forms.size()); - // Password values don't match because they have been stored encrypted and - // read unencrypted. - EXPECT_NE(kPassword, base::UTF16ToUTF8(stored_forms[0]->password_value)); - EXPECT_THAT(migration_step_pref_.GetValue(), - PasswordStoreX::LOGIN_DB_REPLACED); -} - -TEST_F(PasswordStoreXTest, MigrationNotAttemptedEmptyDB) { - IntegerPrefMember migration_step_pref_; - migration_step_pref_.Init(password_manager::prefs::kMigrationToLoginDBStep, - fake_pref_service()); - // Signal that the migration has not been attempted. - migration_step_pref_.SetValue(PasswordStoreX::NOT_ATTEMPTED); - - // Create the store with an empty database. - auto login_db = std::make_unique<password_manager::LoginDatabase>( - test_login_db_file_path(), password_manager::IsAccountStore(false)); - password_manager::LoginDatabase* login_db_ptr = login_db.get(); - - scoped_refptr<PasswordStoreX> store = - new PasswordStoreX(std::move(login_db), fake_pref_service()); - store->Init(nullptr); - WaitForPasswordStore(); - - // Add a password to the db. - PasswordStoreChangeList changes = login_db_ptr->AddLogin(MakePasswordForm()); - EXPECT_EQ(1U, changes.size()); - - store->ShutdownOnUIThread(); - store.reset(); - WaitForPasswordStore(); - - // Check if the database is encrypted. - password_manager::LoginDatabase login_db2( - test_login_db_file_path(), password_manager::IsAccountStore(false)); - login_db2.disable_encryption(); - EXPECT_TRUE(login_db2.Init()); - // Read the password again. - std::vector<std::unique_ptr<PasswordForm>> stored_forms; - EXPECT_TRUE(login_db2.GetAutofillableLogins(&stored_forms)); - EXPECT_EQ(1U, stored_forms.size()); - // Password values don't match because they have been stored encrypted and - // read unencrypted. - EXPECT_NE(kPassword, base::UTF16ToUTF8(stored_forms[0]->password_value)); - EXPECT_THAT(migration_step_pref_.GetValue(), - PasswordStoreX::LOGIN_DB_REPLACED); -} - -// If the login database contains unmigrated entries, they will be migrated into -// encryption. -TEST_F(PasswordStoreXTest, MigrationNotAttemptedNonEmptyDB) { - IntegerPrefMember migration_step_pref_; - migration_step_pref_.Init(password_manager::prefs::kMigrationToLoginDBStep, - fake_pref_service()); - // Signal that the migration has not been attempted. - migration_step_pref_.SetValue(PasswordStoreX::NOT_ATTEMPTED); - - // Add existing credential into loginDB. - auto existing_login = MakePasswordForm(); - auto login_db = std::make_unique<password_manager::LoginDatabase>( - test_login_db_file_path(), password_manager::IsAccountStore(false)); - login_db->disable_encryption(); - ASSERT_TRUE(login_db->Init()); - ignore_result(login_db->AddLogin(existing_login)); - login_db.reset(); - - // Create the store with a non-empty database. - login_db = std::make_unique<password_manager::LoginDatabase>( - test_login_db_file_path(), password_manager::IsAccountStore(false)); - password_manager::LoginDatabase* login_db_ptr = login_db.get(); - - scoped_refptr<PasswordStoreX> store = - new PasswordStoreX(std::move(login_db), fake_pref_service()); - store->Init(nullptr); - WaitForPasswordStore(); - - // Add another password to the db. - PasswordForm new_login = MakePasswordForm(); - new_login.username_value = base::UTF8ToUTF16(kAnotherUsername); - PasswordStoreChangeList changes = login_db_ptr->AddLogin(new_login); - EXPECT_EQ(1U, changes.size()); - - store->ShutdownOnUIThread(); - store.reset(); - WaitForPasswordStore(); - - // Check that the database is encrypted. - password_manager::LoginDatabase login_db2( - test_login_db_file_path(), password_manager::IsAccountStore(false)); - // Disable encryption and get the raw values. An encrypted database would have - // read both encrypted and unencrypted entries. - login_db2.disable_encryption(); - EXPECT_TRUE(login_db2.Init()); - // Read the password again. - std::vector<std::unique_ptr<PasswordForm>> stored_forms; - EXPECT_TRUE(login_db2.GetAutofillableLogins(&stored_forms)); - EXPECT_EQ(2U, stored_forms.size()); - - // Encrypt the passwords to compare them to the raw (i.e. encrypted) values. - std::string existing_password_encrypted, new_password_encrypted; - OSCrypt::EncryptString16(existing_login.password_value, - &existing_password_encrypted); - OSCrypt::EncryptString16(new_login.password_value, &new_password_encrypted); - EXPECT_THAT( - stored_forms, - UnorderedElementsAre( - Pointee(Field(&PasswordForm::password_value, - base::UTF8ToUTF16(existing_password_encrypted))), - Pointee(Field(&PasswordForm::password_value, - base::UTF8ToUTF16(new_password_encrypted))))); - - EXPECT_THAT(migration_step_pref_.GetValue(), - PasswordStoreX::LOGIN_DB_REPLACED); -}
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 7acda1d6..c535f067 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -3164,8 +3164,8 @@ // See chrome/test/data/pdf/accessibility/readme.md for more info. void ParsePdfForExtraDirectives( + const content::DumpAccessibilityTestHelper& test_helper, const std::string& pdf_contents, - AXTreeFormatter* formatter, std::vector<AXPropertyFilter>* property_filters) { const char kCommentMark = '%'; for (const std::string& line : base::SplitString( @@ -3173,12 +3173,7 @@ if (line.size() > 1 && line[0] == kCommentMark) { // Remove first character since it's the comment mark. std::string trimmed_line = line.substr(1); - const std::string& allow_str = formatter->GetAllowString(); - if (base::StartsWith(trimmed_line, allow_str, - base::CompareCase::SENSITIVE)) { - property_filters->push_back(AXPropertyFilter( - trimmed_line.substr(allow_str.size()), AXPropertyFilter::ALLOW)); - } + test_helper.ParsePropertyFilter(trimmed_line, property_filters); } } } @@ -3192,18 +3187,18 @@ // Set up the tree formatter. Parse filters and other directives in the test // file. + content::DumpAccessibilityTestHelper test_helper(test_pass_.name); + std::unique_ptr<AXTreeFormatter> formatter = test_pass_.create_formatter(); std::vector<AXPropertyFilter> property_filters; formatter->AddDefaultFilters(&property_filters); AddDefaultFilters(&property_filters); - ParsePdfForExtraDirectives(pdf_contents, formatter.get(), - &property_filters); + ParsePdfForExtraDirectives(test_helper, pdf_contents, &property_filters); formatter->SetPropertyFilters(property_filters); // Exit without running the test if we can't find an expectation file or if // the expectation file contains a skip marker. // This is used to skip certain tests on certain platforms. - content::DumpAccessibilityTestHelper test_helper(test_pass_.name); base::FilePath expected_file_path = test_helper.GetExpectationFilePath(test_file_path); if (expected_file_path.empty()) {
diff --git a/chrome/browser/permissions/chrome_permissions_client.cc b/chrome/browser/permissions/chrome_permissions_client.cc index 8aed0a2..fedc459 100644 --- a/chrome/browser/permissions/chrome_permissions_client.cc +++ b/chrome/browser/permissions/chrome_permissions_client.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/permissions/chrome_permissions_client.h" +#include <vector> + #include "base/feature_list.h" #include "build/build_config.h" #include "chrome/browser/bluetooth/bluetooth_chooser_context.h" @@ -18,6 +20,7 @@ #include "chrome/browser/permissions/contextual_notification_permission_ui_selector.h" #include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h" #include "chrome/browser/permissions/permission_manager_factory.h" +#include "chrome/browser/permissions/pref_notification_permission_ui_selector.h" #include "chrome/browser/permissions/quiet_notification_permission_ui_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" @@ -195,11 +198,16 @@ return PermissionsClient::GetOverrideIconId(type); } -std::unique_ptr<permissions::NotificationPermissionUiSelector> -ChromePermissionsClient::CreateNotificationPermissionUiSelector( +std::vector<std::unique_ptr<permissions::NotificationPermissionUiSelector>> +ChromePermissionsClient::CreateNotificationPermissionUiSelectors( content::BrowserContext* browser_context) { - return std::make_unique<ContextualNotificationPermissionUiSelector>( - Profile::FromBrowserContext(browser_context)); + std::vector<std::unique_ptr<permissions::NotificationPermissionUiSelector>> + selectors; + selectors.emplace_back( + std::make_unique<ContextualNotificationPermissionUiSelector>()); + selectors.emplace_back(std::make_unique<PrefNotificationPermissionUiSelector>( + Profile::FromBrowserContext(browser_context))); + return selectors; } void ChromePermissionsClient::OnPromptResolved(
diff --git a/chrome/browser/permissions/chrome_permissions_client.h b/chrome/browser/permissions/chrome_permissions_client.h index 559c59d..f386781 100644 --- a/chrome/browser/permissions/chrome_permissions_client.h +++ b/chrome/browser/permissions/chrome_permissions_client.h
@@ -42,8 +42,8 @@ GetUkmSourceIdCallback callback) override; permissions::PermissionRequest::IconId GetOverrideIconId( ContentSettingsType type) override; - std::unique_ptr<permissions::NotificationPermissionUiSelector> - CreateNotificationPermissionUiSelector( + std::vector<std::unique_ptr<permissions::NotificationPermissionUiSelector>> + CreateNotificationPermissionUiSelectors( content::BrowserContext* browser_context) override; void OnPromptResolved(content::BrowserContext* browser_context, permissions::PermissionRequestType request_type,
diff --git a/chrome/browser/permissions/contextual_notification_permission_ui_selector.cc b/chrome/browser/permissions/contextual_notification_permission_ui_selector.cc index 036fdb45..f0e06da 100644 --- a/chrome/browser/permissions/contextual_notification_permission_ui_selector.cc +++ b/chrome/browser/permissions/contextual_notification_permission_ui_selector.cc
@@ -18,12 +18,9 @@ #include "chrome/browser/permissions/crowd_deny_preload_data.h" #include "chrome/browser/permissions/quiet_notification_permission_ui_config.h" #include "chrome/browser/permissions/quiet_notification_permission_ui_state.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/common/chrome_features.h" -#include "components/content_settings/core/common/pref_names.h" #include "components/permissions/permission_request.h" -#include "components/prefs/pref_service.h" #include "components/safe_browsing/core/db/database_manager.h" namespace { @@ -134,8 +131,7 @@ } // namespace ContextualNotificationPermissionUiSelector:: - ContextualNotificationPermissionUiSelector(Profile* profile) - : profile_(profile) {} + ContextualNotificationPermissionUiSelector() = default; void ContextualNotificationPermissionUiSelector::SelectUiToUse( permissions::PermissionRequest* request, @@ -171,7 +167,7 @@ // If the PreloadData suggests this is an unacceptable site, ping Safe // Browsing to verify; but do not ping if it is not warranted. if (!decision || (!decision->quiet_ui_reason && !decision->warning_reason)) { - OnPerSiteTriggersEvaluated(Decision::UseNormalUiAndShowNoWarning()); + Notify(Decision::UseNormalUiAndShowNoWarning()); return; } @@ -198,31 +194,18 @@ switch (verdict) { case CrowdDenySafeBrowsingRequest::Verdict::kAcceptable: - OnPerSiteTriggersEvaluated(Decision::UseNormalUiAndShowNoWarning()); + Notify(Decision::UseNormalUiAndShowNoWarning()); break; case CrowdDenySafeBrowsingRequest::Verdict::kUnacceptable: if (candidate_decision.quiet_ui_reason && ShouldHoldBackQuietUI(*(candidate_decision.quiet_ui_reason))) { candidate_decision.quiet_ui_reason.reset(); } - OnPerSiteTriggersEvaluated(candidate_decision); + Notify(candidate_decision); break; } } -void ContextualNotificationPermissionUiSelector::OnPerSiteTriggersEvaluated( - Decision decision) { - // Still show the quiet UI if it is enabled for all sites, even if per-site - // conditions did not trigger showing the quiet UI on this origin. - if (!decision.quiet_ui_reason && - profile_->GetPrefs()->GetBoolean( - prefs::kEnableQuietNotificationPermissionUi)) { - decision.quiet_ui_reason = QuietUiReason::kEnabledInPrefs; - } - - Notify(decision); -} - void ContextualNotificationPermissionUiSelector::Notify( const Decision& decision) { std::move(callback_).Run(decision);
diff --git a/chrome/browser/permissions/contextual_notification_permission_ui_selector.h b/chrome/browser/permissions/contextual_notification_permission_ui_selector.h index 77c295a..abbf37f6 100644 --- a/chrome/browser/permissions/contextual_notification_permission_ui_selector.h +++ b/chrome/browser/permissions/contextual_notification_permission_ui_selector.h
@@ -10,8 +10,6 @@ #include "chrome/browser/permissions/crowd_deny_safe_browsing_request.h" #include "components/permissions/notification_permission_ui_selector.h" -class Profile; - namespace permissions { class PermissionRequest; } @@ -20,22 +18,19 @@ class Origin; } -// Determines if the quiet prompt UI should be used to display a notification -// permission request on a given site. This is the case when: -// 1) the quiet UI is enabled in prefs for all sites, either directly by the -// user in settings, or by the AdaptiveQuietNotificationPermissionUiEnabler. -// 2) the quiet UI is triggered by crowd deny, either through: -// a) CrowdDenyPreloadData, that is, the component updater, or -// b) CrowdDenySafeBrowsingRequest, that is, on-demand Safe Browsing pings. -// If both (1) and (2) are fulfilled, the crowd-deny UI is shown. +// Determines if crowd deny or abusive blocklists prescribe that the quiet UI +// should be used to display a notification permission request on a given site. +// This is the case when the both of the below sources classify the origin as +// spammy or abusive: +// a) CrowdDenyPreloadData, that is, the component updater, and +// b) CrowdDenySafeBrowsingRequest, that is, on-demand Safe Browsing pings. // // Each instance of this class is long-lived and can support multiple requests, // but only one at a time. class ContextualNotificationPermissionUiSelector : public permissions::NotificationPermissionUiSelector { public: - // Constructs an instance in the context of the given |profile|. - explicit ContextualNotificationPermissionUiSelector(Profile* profile); + ContextualNotificationPermissionUiSelector(); ~ContextualNotificationPermissionUiSelector() override; // NotificationPermissionUiSelector: @@ -54,11 +49,8 @@ void OnSafeBrowsingVerdictReceived( Decision candidate_decision, CrowdDenySafeBrowsingRequest::Verdict verdict); - void OnPerSiteTriggersEvaluated(Decision decision); void Notify(const Decision& decision); - Profile* profile_; - base::Optional<CrowdDenySafeBrowsingRequest> safe_browsing_request_; DecisionMadeCallback callback_; };
diff --git a/chrome/browser/permissions/contextual_notification_permission_ui_selector_unittest.cc b/chrome/browser/permissions/contextual_notification_permission_ui_selector_unittest.cc index 4f1dca8..82d36fc 100644 --- a/chrome/browser/permissions/contextual_notification_permission_ui_selector_unittest.cc +++ b/chrome/browser/permissions/contextual_notification_permission_ui_selector_unittest.cc
@@ -77,8 +77,7 @@ class ContextualNotificationPermissionUiSelectorTest : public testing::Test { public: ContextualNotificationPermissionUiSelectorTest() - : testing_profile_(std::make_unique<TestingProfile>()), - contextual_selector_(testing_profile_.get()) {} + : testing_profile_(std::make_unique<TestingProfile>()) {} ~ContextualNotificationPermissionUiSelectorTest() override = default; protected: @@ -230,6 +229,8 @@ // With all the field trials enabled, test all combinations of: // (a) quiet UI being enabled/disabled in prefs, and // (b) positive/negative Safe Browsing verdicts. +// The ContextualNotificationPermissionUiSelector should only take into account +// the Safe Browsing verdict and ignore the user pref. TEST_F(ContextualNotificationPermissionUiSelectorTest, PrefAndSafeBrowsingCombinations) { using Config = QuietNotificationPermissionUiConfig; @@ -245,11 +246,14 @@ LoadTestPreloadData(); - { - SetQuietUiEnabledInPrefs(false); + for (const bool quiet_ui_enabled_in_prefs : {false, true}) { + SetQuietUiEnabledInPrefs(quiet_ui_enabled_in_prefs); ClearSafeBrowsingBlocklist(); - SCOPED_TRACE("Quiet UI disabled in prefs, Safe Browsing verdicts negative"); + SCOPED_TRACE(quiet_ui_enabled_in_prefs ? "Quiet UI enabled in prefs" + : "Quiet UI disabled in prefs"); + SCOPED_TRACE("Safe Browsing verdicts negative"); + for (const auto* origin_string : kAllTestingOrigins) { SCOPED_TRACE(origin_string); QueryAndExpectDecisionForUrl(GURL(origin_string), Decision::UseNormalUi(), @@ -257,21 +261,8 @@ } } - { - SetQuietUiEnabledInPrefs(true); - ClearSafeBrowsingBlocklist(); - - SCOPED_TRACE("Quiet UI enabled in prefs, Safe Browsing verdicts negative"); - for (const auto* origin_string : kAllTestingOrigins) { - SCOPED_TRACE(origin_string); - QueryAndExpectDecisionForUrl(GURL(origin_string), - QuietUiReason::kEnabledInPrefs, - Decision::ShowNoWarning()); - } - } - - { - SetQuietUiEnabledInPrefs(false); + for (const bool quiet_ui_enabled_in_prefs : {false, true}) { + SetQuietUiEnabledInPrefs(quiet_ui_enabled_in_prefs); LoadTestSafeBrowsingBlocklist(); const struct { @@ -298,44 +289,10 @@ WarningReason::kAbusiveContent}, }; - SCOPED_TRACE("Quiet UI disabled in prefs, Safe Browsing verdicts positive"); - for (const auto& test : kTestCases) { - SCOPED_TRACE(test.origin_string); - QueryAndExpectDecisionForUrl(GURL(test.origin_string), - test.expected_ui_reason, - test.expected_warning_reason); - } - } + SCOPED_TRACE(quiet_ui_enabled_in_prefs ? "Quiet UI enabled in prefs" + : "Quiet UI disabled in prefs"); + SCOPED_TRACE("Safe Browsing verdicts positive"); - { - SetQuietUiEnabledInPrefs(true); - LoadTestSafeBrowsingBlocklist(); - - const struct { - const char* origin_string; - base::Optional<QuietUiReason> expected_ui_reason = - Decision::UseNormalUi(); - base::Optional<WarningReason> expected_warning_reason = - Decision::ShowNoWarning(); - } kTestCases[] = { - {kTestOriginNoData, QuietUiReason::kEnabledInPrefs}, - {kTestOriginUnknown, QuietUiReason::kEnabledInPrefs}, - {kTestOriginAcceptable, QuietUiReason::kEnabledInPrefs}, - {kTestOriginSpammy, QuietUiReason::kTriggeredByCrowdDeny}, - {kTestOriginSpammyWarn, QuietUiReason::kEnabledInPrefs}, - {kTestOriginAbusivePrompts, - QuietUiReason::kTriggeredDueToAbusiveRequests}, - {kTestOriginSubDomainOfAbusivePrompts, - QuietUiReason::kTriggeredDueToAbusiveRequests}, - {kTestOriginAbusivePromptsWarn, QuietUiReason::kEnabledInPrefs, - WarningReason::kAbusiveRequests}, - {kTestOriginAbusiveContent, - QuietUiReason::kTriggeredDueToAbusiveContent}, - {kTestOriginAbusiveContentWarn, QuietUiReason::kEnabledInPrefs, - WarningReason::kAbusiveContent}, - }; - - SCOPED_TRACE("Quiet UI enabled in prefs, Safe Browsing verdicts positive"); for (const auto& test : kTestCases) { SCOPED_TRACE(test.origin_string); QueryAndExpectDecisionForUrl(GURL(test.origin_string), @@ -349,7 +306,6 @@ base::test::ScopedFeatureList feature_list; feature_list.InitAndDisableFeature(features::kQuietNotificationPrompts); - SetQuietUiEnabledInPrefs(true); LoadTestPreloadData(); LoadTestSafeBrowsingBlocklist(); @@ -360,7 +316,7 @@ } } -// The feature is enabled but no adaptive triggers are enabled. +// The feature is enabled but no triggers are enabled. TEST_F(ContextualNotificationPermissionUiSelectorTest, AllTriggersDisabled) { using Config = QuietNotificationPermissionUiConfig; base::test::ScopedFeatureList feature_list; @@ -374,8 +330,7 @@ for (const auto* origin_string : kAllTestingOrigins) { SCOPED_TRACE(origin_string); - QueryAndExpectDecisionForUrl(GURL(origin_string), - QuietUiReason::kEnabledInPrefs, + QueryAndExpectDecisionForUrl(GURL(origin_string), Decision::UseNormalUi(), Decision::ShowNoWarning()); } } @@ -389,7 +344,6 @@ {{Config::kEnableAdaptiveActivation, "true"}, {Config::kEnableCrowdDenyTriggering, "true"}}); - SetQuietUiEnabledInPrefs(false); LoadTestPreloadData(); LoadTestSafeBrowsingBlocklist(); @@ -426,7 +380,6 @@ {{Config::kEnableAdaptiveActivation, "true"}, {Config::kEnableAbusiveContentTriggeredRequestBlocking, "true"}}); - SetQuietUiEnabledInPrefs(false); LoadTestPreloadData(); LoadTestSafeBrowsingBlocklist(); @@ -463,7 +416,6 @@ {{Config::kEnableAdaptiveActivation, "true"}, {Config::kEnableAbusiveContentTriggeredRequestWarning, "true"}}); - SetQuietUiEnabledInPrefs(false); LoadTestPreloadData(); LoadTestSafeBrowsingBlocklist(); @@ -501,7 +453,6 @@ {{Config::kEnableAdaptiveActivation, "true"}, {Config::kEnableAbusiveRequestBlocking, "true"}}); - SetQuietUiEnabledInPrefs(false); LoadTestPreloadData(); LoadTestSafeBrowsingBlocklist(); @@ -540,7 +491,6 @@ {{Config::kEnableAdaptiveActivation, "true"}, {Config::kEnableAbusiveRequestWarning, "true"}}); - SetQuietUiEnabledInPrefs(false); LoadTestPreloadData(); LoadTestSafeBrowsingBlocklist(); @@ -572,17 +522,13 @@ CrowdDenyHoldbackChance) { const struct { std::string holdback_chance; - bool enabled_in_prefs; base::Optional<QuietUiReason> expected_ui_reason; bool expected_histogram_bucket; } kTestCases[] = { // 100% chance to holdback, the UI used should be the normal UI. - {"1.0", false, Decision::UseNormalUi(), true}, + {"1.0", Decision::UseNormalUi(), true}, // 0% chance to holdback, the UI used should be the quiet UI. - {"0.0", false, QuietUiReason::kTriggeredByCrowdDeny}, - // 100% chance to holdback but the quiet UI is enabled by the user in - // prefs, the UI used should be the quiet UI. - {"1.0", true, QuietUiReason::kEnabledInPrefs, true}, + {"0.0", QuietUiReason::kTriggeredByCrowdDeny}, }; LoadTestPreloadData(); @@ -590,7 +536,6 @@ for (const auto& test : kTestCases) { SCOPED_TRACE(test.holdback_chance); - SCOPED_TRACE(test.enabled_in_prefs); using Config = QuietNotificationPermissionUiConfig; base::test::ScopedFeatureList feature_list; @@ -604,8 +549,6 @@ {Config::kEnableCrowdDenyTriggering, "true"}, {Config::kCrowdDenyHoldBackChance, test.holdback_chance}}); - SetQuietUiEnabledInPrefs(test.enabled_in_prefs); - base::HistogramTester histograms; QueryAndExpectDecisionForUrl(GURL(kTestOriginSpammy), test.expected_ui_reason, @@ -616,18 +559,14 @@ QuietUiReason::kTriggeredDueToAbusiveRequests, Decision::ShowNoWarning()); QueryAndExpectDecisionForUrl(GURL(kTestOriginAbusivePromptsWarn), - test.enabled_in_prefs - ? QuietUiReason::kEnabledInPrefs - : Decision::UseNormalUi(), + Decision::UseNormalUi(), WarningReason::kAbusiveRequests); QueryAndExpectDecisionForUrl(GURL(kTestOriginAbusiveContent), QuietUiReason::kTriggeredDueToAbusiveContent, Decision::ShowNoWarning()); QueryAndExpectDecisionForUrl(GURL(kTestOriginAbusiveContentWarn), - test.enabled_in_prefs - ? QuietUiReason::kEnabledInPrefs - : Decision::UseNormalUi(), + Decision::UseNormalUi(), WarningReason::kAbusiveContent); auto expected_bucket = static_cast<base::HistogramBase::Sample>(
diff --git a/chrome/browser/permissions/pref_notification_permission_ui_selector.cc b/chrome/browser/permissions/pref_notification_permission_ui_selector.cc new file mode 100644 index 0000000..b401dfd --- /dev/null +++ b/chrome/browser/permissions/pref_notification_permission_ui_selector.cc
@@ -0,0 +1,36 @@ +// 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/permissions/pref_notification_permission_ui_selector.h" + +#include <utility> + +#include "base/bind.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/chrome_features.h" +#include "components/content_settings/core/common/pref_names.h" +#include "components/prefs/pref_service.h" + +PrefNotificationPermissionUiSelector::PrefNotificationPermissionUiSelector( + Profile* profile) + : profile_(profile) {} + +PrefNotificationPermissionUiSelector::~PrefNotificationPermissionUiSelector() = + default; + +void PrefNotificationPermissionUiSelector::SelectUiToUse( + permissions::PermissionRequest* request, + DecisionMadeCallback callback) { + if (base::FeatureList::IsEnabled(features::kQuietNotificationPrompts) && + profile_->GetPrefs()->GetBoolean( + prefs::kEnableQuietNotificationPermissionUi)) { + std::move(callback).Run( + Decision(QuietUiReason::kEnabledInPrefs, Decision::ShowNoWarning())); + return; + } + + std::move(callback).Run(Decision::UseNormalUiAndShowNoWarning()); +} + +void PrefNotificationPermissionUiSelector::Cancel() {}
diff --git a/chrome/browser/permissions/pref_notification_permission_ui_selector.h b/chrome/browser/permissions/pref_notification_permission_ui_selector.h new file mode 100644 index 0000000..91f29cc --- /dev/null +++ b/chrome/browser/permissions/pref_notification_permission_ui_selector.h
@@ -0,0 +1,45 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PERMISSIONS_PREF_NOTIFICATION_PERMISSION_UI_SELECTOR_H_ +#define CHROME_BROWSER_PERMISSIONS_PREF_NOTIFICATION_PERMISSION_UI_SELECTOR_H_ + +#include "components/permissions/notification_permission_ui_selector.h" + +class Profile; + +namespace permissions { +class PermissionRequest; +} + +// Determines if the quiet prompt UI should be used to display a notification +// permission request on a given site according to user prefs. The quiet UI can +// be enabled in prefs for all sites, either directly by the user in settings, +// or by the AdaptiveQuietNotificationPermissionUiEnabler. +// +// Each instance of this class is long-lived and can support multiple requests. +class PrefNotificationPermissionUiSelector + : public permissions::NotificationPermissionUiSelector { + public: + // Constructs an instance in the context of the given |profile|. + explicit PrefNotificationPermissionUiSelector(Profile* profile); + ~PrefNotificationPermissionUiSelector() override; + + // Disallow copying and assigning. + PrefNotificationPermissionUiSelector( + const PrefNotificationPermissionUiSelector&) = delete; + PrefNotificationPermissionUiSelector& operator=( + const PrefNotificationPermissionUiSelector&) = delete; + + // NotificationPermissionUiSelector: + void SelectUiToUse(permissions::PermissionRequest* request, + DecisionMadeCallback callback) override; + + void Cancel() override; + + private: + Profile* profile_; +}; + +#endif // CHROME_BROWSER_PERMISSIONS_PREF_NOTIFICATION_PERMISSION_UI_SELECTOR_H_
diff --git a/chrome/browser/permissions/pref_notification_permission_ui_selector_unittest.cc b/chrome/browser/permissions/pref_notification_permission_ui_selector_unittest.cc new file mode 100644 index 0000000..ba5d923 --- /dev/null +++ b/chrome/browser/permissions/pref_notification_permission_ui_selector_unittest.cc
@@ -0,0 +1,106 @@ +// 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/permissions/pref_notification_permission_ui_selector.h" + +#include "base/optional.h" +#include "base/run_loop.h" +#include "base/test/mock_callback.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/common/chrome_features.h" +#include "chrome/test/base/testing_profile.h" +#include "components/content_settings/core/common/pref_names.h" +#include "components/permissions/test/mock_permission_request.h" +#include "components/prefs/testing_pref_service.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace { + +using QuietUiReason = PrefNotificationPermissionUiSelector::QuietUiReason; +using WarningReason = PrefNotificationPermissionUiSelector::WarningReason; +using Decision = PrefNotificationPermissionUiSelector::Decision; + +ACTION_P(QuitMessageLoop, loop) { + loop->Quit(); +} + +} // namespace + +class PrefNotificationPermissionUiSelectorTest : public testing::Test { + public: + PrefNotificationPermissionUiSelectorTest() + : testing_profile_(std::make_unique<TestingProfile>()), + pref_selector_(testing_profile_.get()) {} + + PrefNotificationPermissionUiSelector* pref_selector() { + return &pref_selector_; + } + + TestingProfile* profile() { return testing_profile_.get(); } + + private: + content::BrowserTaskEnvironment task_environment_; + + std::unique_ptr<TestingProfile> testing_profile_; + + PrefNotificationPermissionUiSelector pref_selector_; + + DISALLOW_COPY_AND_ASSIGN(PrefNotificationPermissionUiSelectorTest); +}; + +TEST_F(PrefNotificationPermissionUiSelectorTest, FeatureAndPrefCombinations) { + const struct { + bool feature_enabled; + bool quiet_ui_enabled_in_prefs; + base::Optional<QuietUiReason> expected_reason; + } kTests[] = { + {true, false, Decision::UseNormalUi()}, + {true, true, QuietUiReason::kEnabledInPrefs}, + {false, true, Decision::UseNormalUi()}, + {false, false, Decision::UseNormalUi()}, + }; + + for (const auto& test_case : kTests) { + SCOPED_TRACE(base::StringPrintf("feature: %d, pref: %d", + test_case.feature_enabled, + test_case.quiet_ui_enabled_in_prefs)); + + // Init feature and pref settings. + base::test::ScopedFeatureList feature_list; + if (test_case.feature_enabled) + feature_list.InitAndEnableFeature(features::kQuietNotificationPrompts); + else + feature_list.InitAndDisableFeature(features::kQuietNotificationPrompts); + profile()->GetPrefs()->SetBoolean( + prefs::kEnableQuietNotificationPermissionUi, + test_case.quiet_ui_enabled_in_prefs); + + // Setup and prepare for the request. + base::RunLoop callback_loop; + base::MockCallback< + PrefNotificationPermissionUiSelector::DecisionMadeCallback> + mock_callback; + Decision actual_decison(base::nullopt, base::nullopt); + + // Make a request and wait for the callback. + EXPECT_CALL(mock_callback, Run) + .WillRepeatedly(DoAll(testing::SaveArg<0>(&actual_decison), + QuitMessageLoop(&callback_loop))); + + permissions::MockPermissionRequest mock_request( + std::string(), + permissions::PermissionRequestType::PERMISSION_NOTIFICATIONS, + GURL("http://example.com")); + pref_selector()->SelectUiToUse(&mock_request, mock_callback.Get()); + callback_loop.Run(); + testing::Mock::VerifyAndClearExpectations(&mock_callback); + + // Check expectations. + EXPECT_EQ(test_case.expected_reason, actual_decison.quiet_ui_reason); + EXPECT_EQ(Decision::ShowNoWarning(), actual_decison.warning_reason); + } +}
diff --git a/chrome/browser/plugins/chrome_plugin_service_filter.cc b/chrome/browser/plugins/chrome_plugin_service_filter.cc index 33e1191..bbf9d20 100644 --- a/chrome/browser/plugins/chrome_plugin_service_filter.cc +++ b/chrome/browser/plugins/chrome_plugin_service_filter.cc
@@ -36,11 +36,9 @@ explicit ProfileContentSettingObserver(Profile* profile) : profile_(profile) {} ~ProfileContentSettingObserver() override {} - void OnContentSettingChanged( - const ContentSettingsPattern& primary_pattern, - const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override { + void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, + const ContentSettingsPattern& secondary_pattern, + ContentSettingsType content_type) override { if (content_type != ContentSettingsType::PLUGINS) return;
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index ec99e2a..5e1d368 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -1803,8 +1803,6 @@ SCHEMA_ALLOW_UNKNOWN, SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED, SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED)); - handlers->AddHandler( - std::make_unique<EcryptfsMigrationStrategyPolicyHandler>()); handlers->AddHandler(std::make_unique<SimpleSchemaValidatingPolicyHandler>( key::kKerberosAccounts, prefs::kKerberosAccounts, chrome_schema, SCHEMA_ALLOW_UNKNOWN,
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java index 58b5c6f..83e14fdf 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -71,6 +71,9 @@ /** The number of times a user has explicitly canceled a lite script. */ public static final String AUTOFILL_ASSISTANT_NUMBER_OF_LITE_SCRIPTS_CANCELED = "Chrome.AutofillAssistant.NumberOfLiteScriptsCanceled"; + /** Whether proactive help is enabled. */ + public static final String AUTOFILL_ASSISTANT_PROACTIVE_HELP = + "Chrome.AutofillAssistant.ProactiveHelp"; /** * LEGACY preference indicating whether "do not show again" was checked in the autofill * assistant onboarding @@ -797,6 +800,7 @@ ASSISTANT_VOICE_SEARCH_SUPPORTED, AUTOFILL_ASSISTANT_FIRST_TIME_LITE_SCRIPT_USER, AUTOFILL_ASSISTANT_NUMBER_OF_LITE_SCRIPTS_CANCELED, + AUTOFILL_ASSISTANT_PROACTIVE_HELP, APPLICATION_OVERRIDE_LANGUAGE, CLIPBOARD_SHARED_URI, CONDITIONAL_TAB_STRIP_CONTINUOUS_DISMISS_COUNTER,
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index b1817554..c30beb6f 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -226,7 +226,7 @@ #include "components/ntp_tiles/popular_sites_impl.h" #include "components/permissions/contexts/geolocation_permission_context_android.h" #include "components/query_tiles/tile_service_prefs.h" -#else // defined(OS_ANDROID) +#else // defined(OS_ANDROID) #include "chrome/browser/accessibility/caption_controller.h" #include "chrome/browser/enterprise/reporting/prefs.h" #include "chrome/browser/gcm/gcm_product_util.h" @@ -485,6 +485,11 @@ // Deprecated 10/2020 const char kHistoryMenuPromoShown[] = "history.menu_promo_shown"; +// Deprecated 11/2020 +#if defined(USE_X11) +const char kMigrationToLoginDBStep[] = "profile.migration_to_logindb_step"; +#endif + // Register local state used only for migration (clearing or moving to a new // key). void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) { @@ -550,6 +555,10 @@ registry->RegisterBooleanPref(kWasOnboardingFeatureCheckedBefore, false); registry->RegisterBooleanPref(kHistoryMenuPromoShown, true); + +#if defined(USE_X11) + registry->RegisterIntegerPref(kMigrationToLoginDBStep, 0); +#endif } } // namespace @@ -1139,4 +1148,9 @@ // Added 10/2020 profile_prefs->ClearPref(kHistoryMenuPromoShown); + + // Added 11/2020 +#if defined(USE_X11) + profile_prefs->ClearPref(kMigrationToLoginDBStep); +#endif }
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc index d679543..8c99760 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.cc +++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
@@ -1229,8 +1229,7 @@ void PushMessagingServiceImpl::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { if (content_type != ContentSettingsType::NOTIFICATIONS) return;
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.h b/chrome/browser/push_messaging/push_messaging_service_impl.h index 348fc931..c085beb 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.h +++ b/chrome/browser/push_messaging/push_messaging_service_impl.h
@@ -142,8 +142,7 @@ // content_settings::Observer implementation. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // Fires the `pushsubscriptionchange` event to the associated service worker // of |app_identifier|, which is the app identifier for |old_subscription|
diff --git a/chrome/browser/resource_coordinator/discard_metrics_lifecycle_unit_observer.cc b/chrome/browser/resource_coordinator/discard_metrics_lifecycle_unit_observer.cc index 3af1e7e43..767870e0 100644 --- a/chrome/browser/resource_coordinator/discard_metrics_lifecycle_unit_observer.cc +++ b/chrome/browser/resource_coordinator/discard_metrics_lifecycle_unit_observer.cc
@@ -12,20 +12,9 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/resource_coordinator/lifecycle_unit.h" #include "chrome/browser/resource_coordinator/time.h" -#include "net/base/network_change_notifier.h" namespace resource_coordinator { -namespace { - -void RecordReloadAfterDiscardHistograms(const char* reason) { - base::UmaHistogramBoolean( - base::JoinString({"Discarding.OnlineOnReload", reason}, "."), - !net::NetworkChangeNotifier::IsOffline()); -} - -} // namespace - DiscardMetricsLifecycleUnitObserver::DiscardMetricsLifecycleUnitObserver() = default; DiscardMetricsLifecycleUnitObserver::~DiscardMetricsLifecycleUnitObserver() = @@ -88,20 +77,6 @@ UMA_HISTOGRAM_CUSTOM_TIMES( "TabManager.Discarding.InactiveToReloadTime", inactive_to_reload_time, base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(1), 100); - - // TODO(fdoray): All discard histograms should have a reason suffix. - switch (discard_reason_) { - case LifecycleUnitStateChangeReason::SYSTEM_MEMORY_PRESSURE: - RecordReloadAfterDiscardHistograms("Urgent"); - break; - case LifecycleUnitStateChangeReason::EXTENSION_INITIATED: - RecordReloadAfterDiscardHistograms("Extension"); - break; - case LifecycleUnitStateChangeReason::BROWSER_INITIATED: - default: - NOTREACHED(); - break; - } } } // namespace resource_coordinator
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 12c71ebd..0ea606c 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -308,6 +308,7 @@ "chromeos/deep_linking_behavior.m.js", "chromeos/google_assistant_page/google_assistant_browser_proxy.m.js", "chromeos/google_assistant_page/google_assistant_page.m.js", + "chromeos/internet_page/cellular_networks_list.m.js", "chromeos/internet_page/cellular_setup_dialog.m.js", "chromeos/internet_page/cellular_setup_settings_delegate.m.js", "chromeos/internet_page/internet_config.m.js", @@ -576,6 +577,8 @@ "chromeos/google_assistant_page/google_assistant_browser_proxy.js", "chromeos/google_assistant_page/google_assistant_page.html", "chromeos/google_assistant_page/google_assistant_page.js", + "chromeos/internet_page/cellular_networks_list.js", + "chromeos/internet_page/cellular_networks_list.html", "chromeos/internet_page/cellular_setup_dialog.html", "chromeos/internet_page/cellular_setup_dialog.js", "chromeos/internet_page/cellular_setup_settings_delegate.html",
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn index b2248eef..394b0bf2 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
@@ -8,6 +8,7 @@ js_type_check("closure_compile") { deps = [ + ":cellular_networks_list", ":cellular_setup_dialog", ":internet_config", ":internet_detail_menu", @@ -122,6 +123,7 @@ js_library("internet_subpage") { deps = [ + ":cellular_networks_list", ":internet_page_browser_proxy", "..:deep_linking_behavior", "..:metrics_recorder", @@ -198,10 +200,20 @@ ] } +js_library("cellular_networks_list") { + deps = [ + "//ui/webui/resources/cr_components/chromeos/network:onc_mojo", + "//ui/webui/resources/js:i18n_behavior", + ] + externs_list = [ "$externs_path/networking_private.js" ] + extra_sources = [ "$interfaces_path/networking_private_interface.js" ] +} + # TODO: Uncomment as the Polymer3 migration makes progress. js_type_check("closure_compile_module") { is_polymer3 = true deps = [ + ":cellular_networks_list.m", ":cellular_setup_dialog.m", ":cellular_setup_settings_delegate.m", ":internet_config.m", @@ -336,13 +348,13 @@ ":internet_page_browser_proxy.m", ":internet_subpage.m", ":network_summary.m", + "//chrome/browser/resources/settings:router.m", "//chrome/browser/resources/settings/chromeos:deep_linking_behavior.m", "//chrome/browser/resources/settings/chromeos:metrics_recorder.m", "//chrome/browser/resources/settings/chromeos:os_route.m", "//chrome/browser/resources/settings/prefs:prefs.m", "//chrome/browser/resources/settings/settings_page:settings_animated_pages.m", "//chrome/browser/resources/settings/settings_page:settings_subpage.m", - "//chrome/browser/resources/settings:router.m", "//third_party/polymer/v3_0/components-chromium/iron-icon:iron-icon", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider.m", @@ -382,13 +394,14 @@ js_library("internet_subpage.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.m.js" ] deps = [ + ":cellular_networks_list.m", ":internet_page_browser_proxy.m", - "//chrome/browser/resources/settings/chromeos/localized_link:localized_link.m", + "//chrome/browser/resources/settings:router.m", "//chrome/browser/resources/settings/chromeos:deep_linking_behavior.m", "//chrome/browser/resources/settings/chromeos:metrics_recorder.m", "//chrome/browser/resources/settings/chromeos:os_route.m", "//chrome/browser/resources/settings/chromeos:route_origin_behavior.m", - "//chrome/browser/resources/settings:router.m", + "//chrome/browser/resources/settings/chromeos/localized_link:localized_link.m", "//third_party/polymer/v3_0/components-chromium/iron-flex-layout:iron-flex-layout-classes", "//third_party/polymer/v3_0/components-chromium/iron-icon:iron-icon", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", @@ -473,10 +486,21 @@ extra_deps = [ ":tether_connection_dialog_module" ] } +js_library("cellular_networks_list.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.m.js" ] + deps = [ + "//chrome/browser/resources/settings/chromeos/localized_link:localized_link.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:i18n_behavior.m", + ] + extra_deps = [ ":cellular_networks_list_module" ] +} + import("//tools/polymer/polymer.gni") group("polymer3_elements") { public_deps = [ + ":cellular_networks_list_module", ":cellular_setup_dialog_module", ":internet_config_module", ":internet_detail_menu_module", @@ -588,6 +612,14 @@ namespace_rewrites = os_settings_namespace_rewrites } +polymer_modulizer("cellular_networks_list") { + js_file = "cellular_networks_list.js" + html_file = "cellular_networks_list.html" + html_type = "dom-module" + auto_imports = os_settings_auto_imports + namespace_rewrites = os_settings_namespace_rewrites +} + js_modulizer("modulize") { input_files = [ "internet_page_browser_proxy.js",
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.html b/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.html new file mode 100644 index 0000000..5ca8785 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.html
@@ -0,0 +1,103 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html"> +<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_list_types.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> +<link rel="import" href="../../chromeos/os_settings_icons_css.html"> + +<dom-module id="cellular-networks-list"> + <template> + <style include="cr-shared-style os-settings-icons settings-shared iron-flex"> + + .cellular-network-list-header { + border-top: var(--cr-separator-line); + padding: 16px 0 8px 0; + } + + .cellular-network-content { + margin: 8px 0 8px 32px; + } + + .cellular-not-setup { + color: var(--google-grey-700); + font-size: smaller; + margin-bottom: 16px; + } + </style> + <div class="cellular-network-list-header"> + $i18n{cellularNetworkEsimLabel} + </div> + <template is="dom-if" + if="[[shouldShowNetworkSublist_(eSimNetworks_)]]" restamp> + <div class="cellular-network-content"> + <network-list id="esimNetworkList" show-buttons + show-technology-badge="[[showTechnologyBadge]]" + networks="[[eSimNetworks_]]" + device-state="[[deviceState]]"> + </network-list> + </div> + </template> + <template + is="dom-if" + if="[[!shouldShowNetworkSublist_(eSimNetworks_)]]" restamp> + <div class="cellular-network-content cellular-not-setup"> + <settings-localized-link + on-link-clicked="onEsimLearnMoreClicked_" + localized-string="$i18n{eSimNetworkNotSetup}"> + </settings-localized-link> + </div> + </template> + <div class="cellular-network-list-header"> + $i18n{cellularNetworkPsimLabel} + </div> + <template + is="dom-if" + if="[[shouldShowNetworkSublist_(pSimNetworks_)]]" restamp> + <div class="cellular-network-content"> + <network-list + id="psimNetworkList" show-buttons + show-technology-badge="[[showTechnologyBadge]]" + networks="[[pSimNetworks_]]" + device-state="[[deviceState]]"> + </network-list> + </div> + </template> + <template + is="dom-if" + if="[[!shouldShowNetworkSublist_(pSimNetworks_)]]" restamp> + <div class="cellular-network-content cellular-not-setup"> + <settings-localized-link + on-link-clicked="onPsimLearnMoreClicked_" + localized-string="$i18n{pSimNetworkNotSetup}"> + </settings-localized-link> + </div> + </template> + <div class="cellular-network-list-header"> + $i18n{cellularNetworkTetherLabel} + </div> + <template is="dom-if" + if="[[shouldShowNetworkSublist_(tetherNetworks_)]]" restamp> + <div class="cellular-network-content"> + <network-list + id="tetherNetworkList" show-buttons + class="cellular-network-content" + show-technology-badge="[[showTechnologyBadge]]" + networks="[[tetherNetworks_]]" + device-state="[[deviceState]]"> + </network-list> + </div> + </template> + <template is="dom-if" + if="[[!shouldShowNetworkSublist_(tetherNetworks_)]]" restamp> + <div class="cellular-network-content cellular-not-setup"> + <settings-localized-link + localized-string="[[i18nAdvanced('tetherNetworkNotSetup')]]"> + </settings-localized-link> + </div> + </template> + </template> + <script src="cellular_networks_list.js"></script> +</dom-module> \ No newline at end of file
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.js b/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.js new file mode 100644 index 0000000..77359f7 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.js
@@ -0,0 +1,137 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Polymer element for displaying a summary of Cellular network + * states + */ + +Polymer({ + is: 'cellular-networks-list', + + behaviors: [ + I18nBehavior, + ], + + properties: { + /** + * The list of network state properties for the items to display. + * @type {!Array<!OncMojo.NetworkStateProperties>} + */ + networks: { + type: Array, + value() { + return []; + }, + observer: 'networksListChange_', + }, + + /** + * Whether to show technology badge on mobile network icons. + */ + showTechnologyBadge: Boolean, + + /** + * Device state for the network type. + * @type {!OncMojo.DeviceStateProperties|undefined} + */ + deviceState: Object, + + /** + * The list of eSIM network state properties for display. + * @type {!Array<!OncMojo.NetworkStateProperties>} + * @private + */ + eSimNetworks_: { + type: Array, + value() { + return []; + }, + }, + + /** + * The list of pSIM network state properties for display. + * @type {!Array<!OncMojo.NetworkStateProperties>} + * @private + */ + pSimNetworks_: { + type: Array, + value() { + return []; + }, + }, + + /** + * The list of tether network state properties for display. + * @type {!Array<!OncMojo.NetworkStateProperties>} + * @private + */ + tetherNetworks_: { + type: Array, + value() { + return []; + }, + } + }, + + /** + * @private + */ + networksListChange_() { + const mojom = chromeos.networkConfig.mojom; + + const pSimNetworks = []; + const eSimNetworks = []; + const tetherNetworks = []; + + + for (const network of this.networks) { + if (network.eid) { + eSimNetworks.push(network); + continue; + } + if (network.type === mojom.NetworkType.kTether) { + tetherNetworks.push(network); + continue; + } + pSimNetworks.push(network); + } + this.eSimNetworks_ = eSimNetworks; + this.pSimNetworks_ = pSimNetworks; + this.tetherNetworks_ = tetherNetworks; + }, + + + /** + * @param {!Array<!OncMojo.NetworkStateProperties>} list + * @returns {boolean} + * @private + */ + shouldShowNetworkSublist_(list) { + return list.length > 0; + }, + + /** + * @param {Event} event + * @private + */ + onEsimLearnMoreClicked_(event) { + // TODO(crbug.com/1093185): navigate to cellular dialog esim setup landing + // page + + event.detail.event.preventDefault(); + event.stopPropagation(); + }, + + /** + * @param {Event} event + * @private + */ + onPsimLearnMoreClicked_(event) { + // TODO(crbug.com/1093185): navigate to cellular dialog psim setup landing + // page + event.detail.event.preventDefault(); + event.stopPropagation(); + }, +});
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.html index 78dc009..6a87a70 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.html +++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.html
@@ -22,6 +22,7 @@ <link rel="import" href="../localized_link/localized_link.html"> <link rel="import" href="../metrics_recorder.html"> <link rel="import" href="../os_route.html"> +<link rel="import" href="./cellular_networks_list.html"> <link rel="import" href="../route_origin_behavior.html"> <link rel="import" href="internet_page_browser_proxy.html"> @@ -165,6 +166,17 @@ </network-list> </template> + <!-- List of cellular and instant tethering networks --> + <template is="dom-if" + if="[[shouldShowCellularNetworkList_(networkStateList_)]]"> + <cellular-networks-list id="cellularNetworkList" + networks="[[networkStateList_]]" + show-technology-badge="[[showTechnologyBadge_]]" + on-selected="onNetworkSelected_" + device-state="[[deviceState]]"> + </cellular-networks-list> + </template> + <!-- Instructions for how to enable "Google Play Services" notifications (needed for Instant Tethering). --> <template is="dom-if" if="[[showGmsCoreNotificationsSection_( @@ -190,7 +202,7 @@ <!-- Text shown if no networks exist. --> <settings-localized-link class="no-networks" - hidden="[[shouldShowNetworkList_(networkStateList_)]]" + hidden="[[hideNoNetworksMessage_(networkStateList_)]]" localized-string= "[[getNoNetworksInnerHtml_(deviceState, tetherDeviceState)]]"> </settings-localized-link>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.js index fd877e31..980bc0a 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.js +++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.js
@@ -415,8 +415,7 @@ networkType: mojom.NetworkType.kTether, }; this.networkConfig_.getNetworkStateList(filter).then(response => { - const tetherNetworkStates = response.result; - this.networkStateList_ = networkStates.concat(tetherNetworkStates); + this.set('networkStateList_', networkStates.concat(response.result)); }); return; } @@ -449,7 +448,7 @@ this.thirdPartyVpns_ = thirdPartyVpns; } - this.networkStateList_ = networkStates; + this.set('networkStateList_', networkStates); }, /** @@ -825,26 +824,58 @@ }, /** - * @param {!Array<!OncMojo.NetworkStateProperties>} networkStateList + * @param {!Array<!OncMojo.NetworkStateProperties>} + * networkStateList * @return {boolean} * @private */ shouldShowNetworkList_(networkStateList) { + if (this.shouldShowCellularNetworkList_()) { + return false; + } + if (!!this.deviceState && this.deviceState.type === mojom.NetworkType.kVPN) { - return this.shouldShowVpnList_(networkStateList); + return this.shouldShowVpnList_(); } - return networkStateList.length > 0; + return this.networkStateList_.length > 0; }, /** - * @param {!Array<!OncMojo.NetworkStateProperties>} networkStateList * @return {boolean} True if native VPN is not disabled by policy and there * are more than one VPN network configured. * @private */ - shouldShowVpnList_(networkStateList) { - return this.vpnIsEnabled_ && networkStateList.length > 0; + shouldShowVpnList_() { + return this.vpnIsEnabled_ && this.networkStateList_.length > 0; + }, + + /** + * @return {boolean} + * @private + */ + shouldShowCellularNetworkList_() { + if (!this.isUpdatedCellularUiEnabled_) { + return false; + } + + if (this.deviceState.type === mojom.NetworkType.kCellular || + this.deviceState.type === mojom.NetworkType.kTether) { + return this.networkStateList_.length > 0; + } + + return false; + }, + + /** + * @param {!Array<!OncMojo.NetworkStateProperties>} + * networkStateList + * @return {boolean} + * @private + */ + hideNoNetworksMessage_(networkStateList) { + return this.shouldShowCellularNetworkList_() || + this.shouldShowNetworkList_(networkStateList); }, /**
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index 3fec1244..5db3d9b 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -706,48 +706,6 @@ </settings-subpage> </template> </template> - <template is="dom-if" route-path="/content/unsandboxedPlugins" no-search> - <settings-subpage page-title="$i18n{siteSettingsUnsandboxedPlugins}" - search-label="$i18n{siteSettingsAllSitesSearch}" - search-term="{{searchFilter_}}"> - <template is="dom-if" if="[[enableContentSettingsRedesign_]]"> - <div class="content-settings-header"> - <h2>$i18n{siteSettingsUnsandboxedPluginsDescription}</h2> - </div> - <settings-category-default-radio-group - category="[[ContentSettingsTypes.UNSANDBOXED_PLUGINS]]" - allow-option-label= - "$i18n{siteSettingsUnsandboxedPluginsAllowed}" - allow-option-icon="cr:extension" - block-option-label= - "$i18n{siteSettingsUnsandboxedPluginsBlocked}" - block-option-icon="settings:block"> - </settings-category-default-radio-group> - <category-setting-exceptions - category="[[ContentSettingsTypes.UNSANDBOXED_PLUGINS]]" - allow-header= - "$i18n{siteSettingsUnsandboxedPluginsAllowedExceptions}" - block-header= - "$i18n{siteSettingsUnsandboxedPluginsBlockedExceptions}" - search-filter="[[searchFilter_]]"> - </category-setting-exceptions> - </template> - <template is="dom-if" if="[[!enableContentSettingsRedesign_]]"> - <category-default-setting - toggle-off-label="$i18n{siteSettingsUnsandboxedPluginsBlock}" - toggle-on-label= - "$i18n{siteSettingsUnsandboxedPluginsAskRecommended}" - category="[[ContentSettingsTypes.UNSANDBOXED_PLUGINS]]"> - </category-default-setting> - <category-setting-exceptions - category="[[ContentSettingsTypes.UNSANDBOXED_PLUGINS]]" - block-header="$i18n{siteSettingsBlock}" - allow-header="$i18n{siteSettingsAllow}" - search-filter="[[searchFilter_]]"> - </category-setting-exceptions> - </template> - </settings-subpage> - </template> <template is="dom-if" route-path="/content/midiDevices" no-search> <settings-subpage page-title="$i18n{siteSettingsMidiDevices}" search-label="$i18n{siteSettingsAllSitesSearch}"
diff --git a/chrome/browser/resources/settings/route.js b/chrome/browser/resources/settings/route.js index de56c1b..0e3a27e 100644 --- a/chrome/browser/resources/settings/route.js +++ b/chrome/browser/resources/settings/route.js
@@ -55,8 +55,6 @@ r.SITE_SETTINGS_MICROPHONE = r.SITE_SETTINGS.createChild('microphone'); r.SITE_SETTINGS_NOTIFICATIONS = r.SITE_SETTINGS.createChild('notifications'); r.SITE_SETTINGS_POPUPS = r.SITE_SETTINGS.createChild('popups'); - r.SITE_SETTINGS_UNSANDBOXED_PLUGINS = - r.SITE_SETTINGS.createChild('unsandboxedPlugins'); r.SITE_SETTINGS_MIDI_DEVICES = r.SITE_SETTINGS.createChild('midiDevices'); r.SITE_SETTINGS_USB_DEVICES = r.SITE_SETTINGS.createChild('usbDevices'); r.SITE_SETTINGS_HID_DEVICES = r.SITE_SETTINGS.createChild('hidDevices');
diff --git a/chrome/browser/resources/settings/settings_routes.js b/chrome/browser/resources/settings/settings_routes.js index 03a96da..52829d8a 100644 --- a/chrome/browser/resources/settings/settings_routes.js +++ b/chrome/browser/resources/settings/settings_routes.js
@@ -74,7 +74,6 @@ * SITE_SETTINGS_PROTECTED_CONTENT: !Route, * SITE_SETTINGS_SITE_DATA: !Route, * SITE_SETTINGS_SITE_DETAILS: !Route, - * SITE_SETTINGS_UNSANDBOXED_PLUGINS: !Route, * SITE_SETTINGS_USB_DEVICES: !Route, * SITE_SETTINGS_SERIAL_PORTS: !Route, * SITE_SETTINGS_VR: !Route,
diff --git a/chrome/browser/resources/settings/site_settings/README.md b/chrome/browser/resources/settings/site_settings/README.md index 6fb139f..57341c4 100644 --- a/chrome/browser/resources/settings/site_settings/README.md +++ b/chrome/browser/resources/settings/site_settings/README.md
@@ -36,9 +36,9 @@ ``` <site-details-permission - category="{{ContentSettingsTypes.UNSANDBOXED_PLUGINS}}" - icon="cr:extension" id="unsandboxedPlugins" - label="$i18n{siteSettingsUnsandboxedPlugins}"> + category="{{ContentSettingsTypes.SITE_SETTINGS_SOUND}}" + icon="settings:volume-up" id="siteSettingsSound" + label="$i18n{siteSettingsSound}"> </site-details-permission> ```
diff --git a/chrome/browser/resources/settings/site_settings/category_default_setting.js b/chrome/browser/resources/settings/site_settings/category_default_setting.js index 0a9d210..f1aeec3e 100644 --- a/chrome/browser/resources/settings/site_settings/category_default_setting.js +++ b/chrome/browser/resources/settings/site_settings/category_default_setting.js
@@ -177,7 +177,6 @@ case ContentSettingsTypes.GEOLOCATION: case ContentSettingsTypes.MIC: case ContentSettingsTypes.NOTIFICATIONS: - case ContentSettingsTypes.UNSANDBOXED_PLUGINS: case ContentSettingsTypes.MIDI_DEVICES: case ContentSettingsTypes.USB_DEVICES: case ContentSettingsTypes.SERIAL_PORTS:
diff --git a/chrome/browser/resources/settings/site_settings/constants.js b/chrome/browser/resources/settings/site_settings/constants.js index a0870de..1679cc0d 100644 --- a/chrome/browser/resources/settings/site_settings/constants.js +++ b/chrome/browser/resources/settings/site_settings/constants.js
@@ -38,7 +38,6 @@ SENSORS: 'sensors', SERIAL_PORTS: 'serial-ports', SOUND: 'sound', - UNSANDBOXED_PLUGINS: 'ppapi-broker', USB_DEVICES: 'usb-devices', VR: 'vr', WINDOW_PLACEMENT: 'window-placement',
diff --git a/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.js b/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.js index 065cb80c..1c25bf3 100644 --- a/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.js +++ b/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.js
@@ -101,7 +101,6 @@ case ContentSettingsTypes.GEOLOCATION: case ContentSettingsTypes.MIC: case ContentSettingsTypes.NOTIFICATIONS: - case ContentSettingsTypes.UNSANDBOXED_PLUGINS: case ContentSettingsTypes.MIDI_DEVICES: case ContentSettingsTypes.USB_DEVICES: case ContentSettingsTypes.SERIAL_PORTS:
diff --git a/chrome/browser/resources/settings/site_settings/site_details.html b/chrome/browser/resources/settings/site_settings/site_details.html index f30d06c..cf100e2d 100644 --- a/chrome/browser/resources/settings/site_settings/site_details.html +++ b/chrome/browser/resources/settings/site_settings/site_details.html
@@ -186,10 +186,6 @@ <site-details-permission category="[[ContentSettingsTypes.HID_DEVICES]]" icon="settings:hid-device" label="$i18n{siteSettingsHidDevices}"> </site-details-permission> - <site-details-permission - category="[[ContentSettingsTypes.UNSANDBOXED_PLUGINS]]" - icon="cr:extension" label="$i18n{siteSettingsUnsandboxedPlugins}"> - </site-details-permission> <if expr="chromeos"> <site-details-permission category="[[ContentSettingsTypes.PROTECTED_CONTENT]]"
diff --git a/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js b/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js index 78dc450..711ad978 100644 --- a/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js +++ b/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js
@@ -136,8 +136,6 @@ return this.i18n('siteSettingsCamera'); case ContentSettingsTypes.PROTOCOL_HANDLERS: return this.i18n('siteSettingsHandlers'); - case ContentSettingsTypes.UNSANDBOXED_PLUGINS: - return this.i18n('siteSettingsUnsandboxedPlugins'); case ContentSettingsTypes.AUTOMATIC_DOWNLOADS: return this.i18n('siteSettingsAutomaticDownloads'); case ContentSettingsTypes.BACKGROUND_SYNC:
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js index 2546de8..01f45ea 100644 --- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js +++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
@@ -276,14 +276,6 @@ disabledLabel: 'siteSettingsSoundBlock', }, { - route: routes.SITE_SETTINGS_UNSANDBOXED_PLUGINS, - id: Id.UNSANDBOXED_PLUGINS, - label: 'siteSettingsUnsandboxedPlugins', - icon: 'cr:extension', - enabledLabel: 'siteSettingsUnsandboxedPluginsAsk', - disabledLabel: 'siteSettingsUnsandboxedPluginsBlock', - }, - { route: routes.SITE_SETTINGS_USB_DEVICES, id: Id.USB_DEVICES, label: 'siteSettingsUsbDevices', @@ -366,7 +358,6 @@ permissionsAdvanced: buildItemListFromIds([ Id.SENSORS, Id.AUTOMATIC_DOWNLOADS, - Id.UNSANDBOXED_PLUGINS, Id.PROTOCOL_HANDLERS, Id.MIDI_DEVICES, Id.USB_DEVICES,
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc index 70ff7fe..272f8267 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc
@@ -289,8 +289,7 @@ void SafeBrowsingNavigationObserver::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { // For all the content settings that can be changed via page info UI, we // assume there is a user gesture associated with the content setting change. if (web_contents() &&
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h index 02b6788..7513eb0 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h
@@ -140,8 +140,7 @@ // content_settings::Observer overrides. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // Map keyed on NavigationHandle* to keep track of all the ongoing navigation // events. NavigationHandle pointers are owned by RenderFrameHost. Since a
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc index 679e170..8cdf9b4d 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc
@@ -343,8 +343,7 @@ // Simulate content setting change via page info UI. navigation_observer_->OnContentSettingChanged( ContentSettingsPattern::FromURL(web_content->GetLastCommittedURL()), - ContentSettingsPattern::Wildcard(), ContentSettingsType::NOTIFICATIONS, - std::string()); + ContentSettingsPattern::Wildcard(), ContentSettingsType::NOTIFICATIONS); // A user gesture should be recorded. ASSERT_EQ(1U, user_gesture_map()->size()); @@ -356,8 +355,7 @@ // Simulate content setting change that cannot be changed via page info UI. navigation_observer_->OnContentSettingChanged( ContentSettingsPattern::FromURL(web_content->GetLastCommittedURL()), - ContentSettingsPattern::Wildcard(), ContentSettingsType::SITE_ENGAGEMENT, - std::string()); + ContentSettingsPattern::Wildcard(), ContentSettingsType::SITE_ENGAGEMENT); // No user gesture should be recorded. EXPECT_EQ(0U, user_gesture_map()->size()); }
diff --git a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc index acf368f..e9a7f4d 100644 --- a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc +++ b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
@@ -120,6 +120,11 @@ const char kActivationListHistogram[] = "SubresourceFilter.PageLoad.ActivationList"; +const char kPageLoadActivationStateHistogram[] = + "SubresourceFilter.PageLoad.ActivationState"; +const char kPageLoadActivationStateDidInheritHistogram[] = + "SubresourceFilter.PageLoad.ActivationState.DidInherit"; + // Other histograms. const char kSubresourceFilterActionsHistogram[] = "SubresourceFilter.Actions2"; @@ -887,6 +892,7 @@ ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL("/title1.html")); + base::HistogramTester tester; ASSERT_TRUE(ExecJs(web_contents(), content::JsReplace("popup = window.open($1, 'name1');", embedded_test_server()->GetURL( @@ -901,9 +907,14 @@ title_watcher.WaitAndGetTitle()); } - ui_test_utils::NavigateToURL( - chrome::FindBrowserWithWebContents(popup_observer.GetWebContents()), - GURL("about:blank")); + // Check histograms agree that activation was not inherited. + tester.ExpectBucketCount(kPageLoadActivationStateHistogram, + static_cast<int>(mojom::ActivationLevel::kEnabled), + 1); + tester.ExpectTotalCount(kPageLoadActivationStateDidInheritHistogram, 0); + + ASSERT_TRUE( + ExecJs(web_contents(), "popup = window.open('about:blank', 'name1');")); ASSERT_TRUE(ExecJs(web_contents(), R"SCRIPT( // Get reference to popup without changing its location. @@ -923,6 +934,14 @@ // Check the load was blocked. EXPECT_EQ(base::ASCIIToUTF16("failed"), title_watcher.WaitAndGetTitle()); + + // Check the new histograms agree that activation was inherited. + tester.ExpectBucketCount(kPageLoadActivationStateHistogram, + static_cast<int>(mojom::ActivationLevel::kEnabled), + 2); + tester.ExpectBucketCount(kPageLoadActivationStateDidInheritHistogram, + static_cast<int>(mojom::ActivationLevel::kEnabled), + 1); } // Test that resources in a popup with an aborted initial load due to a @@ -944,6 +963,7 @@ ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL("/title1.html")); + base::HistogramTester tester; content::WebContentsAddedObserver popup_observer; ASSERT_TRUE(ExecJs(original_web_contents, R"SCRIPT( popup = window.open('http://b.com/slow?100'); @@ -965,6 +985,14 @@ // Check the load was blocked. EXPECT_EQ(base::ASCIIToUTF16("failed"), title_watcher.WaitAndGetTitle()); + + // Check histograms agree that activation was inherited. + tester.ExpectBucketCount(kPageLoadActivationStateHistogram, + static_cast<int>(mojom::ActivationLevel::kEnabled), + 1); + tester.ExpectBucketCount(kPageLoadActivationStateDidInheritHistogram, + static_cast<int>(mojom::ActivationLevel::kEnabled), + 1); } // Tests checking how histograms are recorded. ---------------------------------
diff --git a/chrome/browser/sync/wifi_configuration_sync_service_factory.cc b/chrome/browser/sync/wifi_configuration_sync_service_factory.cc index b918807c..0870ebd4 100644 --- a/chrome/browser/sync/wifi_configuration_sync_service_factory.cc +++ b/chrome/browser/sync/wifi_configuration_sync_service_factory.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/sync/model_type_store_service_factory.h" #include "chrome/common/channel_info.h" #include "chromeos/components/sync_wifi/pending_network_configuration_tracker_impl.h" +#include "chromeos/components/sync_wifi/wifi_configuration_bridge.h" #include "chromeos/components/sync_wifi/wifi_configuration_sync_service.h" #include "chromeos/network/network_handler.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -67,4 +68,5 @@ user_prefs::PrefRegistrySyncable* registry) { chromeos::sync_wifi::PendingNetworkConfigurationTrackerImpl:: RegisterProfilePrefs(registry); + chromeos::sync_wifi::WifiConfigurationBridge::RegisterPrefs(registry); }
diff --git a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc index c82fb30..12913c0 100644 --- a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc +++ b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc
@@ -62,8 +62,7 @@ const GURL& url, IsOriginSecure is_origin_secure, base::span<const password_manager::UiCredential> credentials) { - auto java_object = GetOrCreateJavaObject(); - if (!java_object) + if (!RecreateJavaObject()) return; // Serialize the |credentials| span into a Java array and instruct the bridge // to show it together with |url| to the user. @@ -83,7 +82,7 @@ } Java_TouchToFillBridge_showCredentials( - env, java_object, ConvertUTF8ToJavaString(env, url.spec()), + env, java_object_internal_, ConvertUTF8ToJavaString(env, url.spec()), is_origin_secure.value(), credential_array); } @@ -109,16 +108,17 @@ OnDismiss(); } -base::android::ScopedJavaGlobalRef<jobject> -TouchToFillViewImpl::GetOrCreateJavaObject() { - if (java_object_internal_) { - return java_object_internal_; - } +bool TouchToFillViewImpl::RecreateJavaObject() { if (controller_->GetNativeView() == nullptr || controller_->GetNativeView()->GetWindowAndroid() == nullptr) { - return nullptr; // No window attached (yet or anymore). + return false; // No window attached (yet or anymore). } - return java_object_internal_ = Java_TouchToFillBridge_create( - AttachCurrentThread(), reinterpret_cast<intptr_t>(this), - controller_->GetNativeView()->GetWindowAndroid()->GetJavaObject()); + if (java_object_internal_) { + Java_TouchToFillBridge_destroy(AttachCurrentThread(), + java_object_internal_); + } + java_object_internal_ = Java_TouchToFillBridge_create( + AttachCurrentThread(), reinterpret_cast<intptr_t>(this), + controller_->GetNativeView()->GetWindowAndroid()->GetJavaObject()); + return !!java_object_internal_; }
diff --git a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h index ac02732..af2aacd 100644 --- a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h +++ b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h
@@ -38,11 +38,10 @@ void OnDismiss(JNIEnv* env); private: - // Returns either the fully initialized java counterpart of this bridge or - // a is_null() reference if the creation failed. By using this method, the - // bridge will try to recreate the java object if it failed previously (e.g. - // because there was no native window available). - base::android::ScopedJavaGlobalRef<jobject> GetOrCreateJavaObject(); + // Returns either true if the java counterpart of this bridge is initialized + // successfully or false if the creation failed. This method will recreate the + // java object whenever Show() is called. + bool RecreateJavaObject(); TouchToFillController* controller_ = nullptr; base::android::ScopedJavaGlobalRef<jobject> java_object_internal_;
diff --git a/chrome/browser/ui/android/infobars/autofill_save_card_infobar.cc b/chrome/browser/ui/android/infobars/autofill_save_card_infobar.cc index e43d83fc..f60ce4b 100644 --- a/chrome/browser/ui/android/infobars/autofill_save_card_infobar.cc +++ b/chrome/browser/ui/android/infobars/autofill_save_card_infobar.cc
@@ -24,15 +24,20 @@ namespace autofill { std::unique_ptr<infobars::InfoBar> CreateSaveCardInfoBarMobile( - std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile> delegate) { - return std::make_unique<AutofillSaveCardInfoBar>(std::move(delegate)); + std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile> delegate, + base::Optional<AccountInfo> account_info) { + return std::make_unique<AutofillSaveCardInfoBar>(std::move(delegate), + account_info); } } // namespace autofill AutofillSaveCardInfoBar::AutofillSaveCardInfoBar( - std::unique_ptr<autofill::AutofillSaveCardInfoBarDelegateMobile> delegate) - : ChromeConfirmInfoBar(std::move(delegate)) {} + std::unique_ptr<autofill::AutofillSaveCardInfoBarDelegateMobile> delegate, + base::Optional<AccountInfo> account_info) + : ChromeConfirmInfoBar(std::move(delegate)) { + account_info_ = account_info; +} AutofillSaveCardInfoBar::~AutofillSaveCardInfoBar() {} @@ -59,7 +64,10 @@ env, GetTextFor(ConfirmInfoBarDelegate::BUTTON_OK)), base::android::ConvertUTF16ToJavaString( env, GetTextFor(ConfirmInfoBarDelegate::BUTTON_CANCEL)), - delegate->IsGooglePayBrandingEnabled()); + delegate->IsGooglePayBrandingEnabled(), + account_info_.has_value() + ? ConvertToJavaAccountInfo(env, account_info_.value()) + : nullptr); Java_AutofillSaveCardInfoBar_setDescriptionText( env, java_delegate,
diff --git a/chrome/browser/ui/android/infobars/autofill_save_card_infobar.h b/chrome/browser/ui/android/infobars/autofill_save_card_infobar.h index 97c2d05..c4df1a0 100644 --- a/chrome/browser/ui/android/infobars/autofill_save_card_infobar.h +++ b/chrome/browser/ui/android/infobars/autofill_save_card_infobar.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "chrome/browser/ui/android/infobars/chrome_confirm_infobar.h" +#include "components/signin/public/identity_manager/account_info.h" namespace autofill { class AutofillSaveCardInfoBarDelegateMobile; @@ -20,8 +21,9 @@ class AutofillSaveCardInfoBar : public ChromeConfirmInfoBar { public: explicit AutofillSaveCardInfoBar( - std::unique_ptr<autofill::AutofillSaveCardInfoBarDelegateMobile> - delegate); + std::unique_ptr<autofill::AutofillSaveCardInfoBarDelegateMobile> delegate, + base::Optional<AccountInfo> account_info); + ~AutofillSaveCardInfoBar() override; // Called when a link in the legal message text was clicked. @@ -40,6 +42,8 @@ // are stored in /chrome and /components cannot depend on /chrome. int GetGooglePayBrandingIconId(); + base::Optional<AccountInfo> account_info_; + DISALLOW_COPY_AND_ASSIGN(AutofillSaveCardInfoBar); };
diff --git a/chrome/browser/ui/android/layouts/BUILD.gn b/chrome/browser/ui/android/layouts/BUILD.gn index 98c02d2..a85bb82a 100644 --- a/chrome/browser/ui/android/layouts/BUILD.gn +++ b/chrome/browser/ui/android/layouts/BUILD.gn
@@ -8,6 +8,7 @@ sources = [ "java/src/org/chromium/chrome/browser/layouts/CompositorModelChangeProcessor.java", "java/src/org/chromium/chrome/browser/layouts/EventFilter.java", + "java/src/org/chromium/chrome/browser/layouts/LayoutManager.java", "java/src/org/chromium/chrome/browser/layouts/LayoutStateProvider.java", "java/src/org/chromium/chrome/browser/layouts/LayoutType.java", "java/src/org/chromium/chrome/browser/layouts/SceneOverlay.java",
diff --git a/chrome/browser/ui/android/layouts/java/src/org/chromium/chrome/browser/layouts/LayoutManager.java b/chrome/browser/ui/android/layouts/java/src/org/chromium/chrome/browser/layouts/LayoutManager.java new file mode 100644 index 0000000..668661f --- /dev/null +++ b/chrome/browser/ui/android/layouts/java/src/org/chromium/chrome/browser/layouts/LayoutManager.java
@@ -0,0 +1,31 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.layouts; + +import org.chromium.chrome.browser.layouts.scene_layer.SceneLayer; +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyModelChangeProcessor; + +/** An interface for classes that manage the display of layouts and their components. */ +public interface LayoutManager extends LayoutStateProvider { + /** + * Add a {@link SceneOverlay} to be drawn on the composited layer of the active layout. + * @param overlay The overlay to add. + */ + void addSceneOverlay(SceneOverlay overlay); + + /** + * Creates a CompositorModelChangeProcessor observing the given {@code model} that will operate + * on this {@code LayoutManager}'s frame cycle. The model will be bound to the view initially + * and request a new frame. + * @param model The model containing the data to be bound to the view. + * @param view The view which the model will be bound to. + * @param viewBinder This is used to bind the model to the view. + */ + <V extends SceneLayer> CompositorModelChangeProcessor<V> createCompositorMCP( + PropertyModel model, V view, + PropertyModelChangeProcessor.ViewBinder<PropertyModel, V, PropertyKey> viewBinder); +}
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index d477fd1..0d01575 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -2129,6 +2129,9 @@ <message name="IDS_CONTEXTMENU_OPEN_IN_EPHEMERAL_TAB" desc="Context-sensitive menu item to open a quick preview of the selected linked page. Note that 'preview' is a verb, not a noun. We're also labeling it *New* to draw attention to it when first released. The selected link will open in an overlay panel on top of the current tab which will go away easily too. [CHAR-LIMIT=30]"> Preview page <ph name="BEGIN_NEW"><new></ph>New<ph name="END_NEW"></new></ph> </message> + <message name="IDS_CONTEXTMENU_READ_LATER" desc="Context sensitive menu item for marking a link to be read later. We're also labeling it *New* to draw attention to it when first released. [CHAR-LIMIT=30]"> + Read later <ph name="BEGIN_NEW"><new></ph>New<ph name="END_NEW"></new></ph> + </message> <message name="IDS_CONTEXTMENU_PERFORMANCE_INFO_FAST" desc="This string is shown in the context sensitive menu for links and is shown underneath the link URL. It indicates to the user that the link's target page is fast-loading and responsive. [CHAR-LIMIT=30]"> Fast page </message> @@ -3956,12 +3959,27 @@ <message name="IDS_PREFS_AUTOFILL_ASSISTANT_TITLE" desc="Title for the Autofill Assistant preferences screen. [CHAR-LIMIT=32]"> Google Assistant in Chrome </message> - <message name="IDS_PREFS_AUTOFILL_ASSISTANT_SWITCH" desc="Title for the switch toggling whether Autofill Assistant is enabled. [CHAR-LIMIT=32]"> - Assistant Triggered Checkout + <message name="IDS_PREFS_AUTOFILL_ASSISTANT_SUMMARY" desc="Summary for the Autofill Assistant preferences screen."> + Helps you complete tasks, such as checkout, throughout the web </message> - <message name="IDS_PREFS_AUTOFILL_ASSISTANT_SUMMARY" desc="Description for the Autofill Assistant toggle."> + <message name="IDS_PREFS_WEB_ASSISTANCE_SECTION_TITLE" desc="Title for the web assistance section"> + Web Assistance + </message> + <message name="IDS_PREFS_AUTOFILL_ASSISTANT_GET_HELP_TITLE" desc="Title for the switch toggling whether Autofill Assistant is enabled. [CHAR-LIMIT=32]"> + Get help with tasks on the web + </message> + <message name="IDS_PREFS_AUTOFILL_ASSISTANT_GET_HELP_SUMMARY" desc="Description for the Autofill Assistant toggle."> To help you complete tasks, Google will receive the URLs and contents of sites on which you use Assistant, as well as information you submit through Assistant </message> + <message name="IDS_PREFS_AUTOFILL_ASSISTANT_PROACTIVE_HELP_TITLE" desc="Title for the switch toggling whether proactive help is enabled. When turned on, the Assistant will be able to proactively show up (without explicit user prompt) and offer to help. [CHAR-LIMIT=32]"> + Proactive Help + </message> + <message name="IDS_PREFS_AUTOFILL_ASSISTANT_PROACTIVE_HELP_SUMMARY" desc="Description for the proactive help toggle. It explains that the Assistant may appear proactively when it detects that it can help the user. "> + Assistant will appear when it detects that it can help you on supported websites + </message> + <message name="IDS_PREFS_PROACTIVE_HELP_SYNC_LINK" desc="Disclaimer that appears after the proactive help toggle, but only if 'make search and browsing better'[MSBB] is switched off. Proactive help is only possible while MSBB is turned on, which is the default for signed-in users. If MSBB is off, the proactive help setting will be grayed out and this disclaimer is shown."> + To use this setting <ph name="BEGIN_LINK"><link></ph>Make searches and browsing better<ph name="END_LINK"></link></ph> must be turned on + </message> <!-- Usage Stats strings --> <message name="IDS_USAGE_STATS_CONSENT_TITLE" desc="Title for activity authorizing Digital Wellbeing to access Chrome usage data"> Show your Chrome activity in Digital Wellbeing?
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_READ_LATER.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_READ_LATER.png.sha1 new file mode 100644 index 0000000..eb32c8c --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_READ_LATER.png.sha1
@@ -0,0 +1 @@ +06e75fef54b699b8ce7b66b7a772f20b81bf120d \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_GET_HELP_SUMMARY.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_GET_HELP_SUMMARY.png.sha1 new file mode 100644 index 0000000..c8733a4 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_GET_HELP_SUMMARY.png.sha1
@@ -0,0 +1 @@ +a8d9fbf90c9305b249b996a0bd271e26d08fbd4f \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_GET_HELP_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_GET_HELP_TITLE.png.sha1 new file mode 100644 index 0000000..c8733a4 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_GET_HELP_TITLE.png.sha1
@@ -0,0 +1 @@ +a8d9fbf90c9305b249b996a0bd271e26d08fbd4f \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_PROACTIVE_HELP_SUMMARY.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_PROACTIVE_HELP_SUMMARY.png.sha1 new file mode 100644 index 0000000..c8733a4 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_PROACTIVE_HELP_SUMMARY.png.sha1
@@ -0,0 +1 @@ +a8d9fbf90c9305b249b996a0bd271e26d08fbd4f \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_PROACTIVE_HELP_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_PROACTIVE_HELP_TITLE.png.sha1 new file mode 100644 index 0000000..c8733a4 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_PROACTIVE_HELP_TITLE.png.sha1
@@ -0,0 +1 @@ +a8d9fbf90c9305b249b996a0bd271e26d08fbd4f \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_SUMMARY.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_SUMMARY.png.sha1 index 972a010..ae621d4 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_SUMMARY.png.sha1 +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_SUMMARY.png.sha1
@@ -1 +1 @@ -0388570ab9b393c32b4ad885f8cae107905318ff \ No newline at end of file +0ab00e4536b0621afa932bf2e3fd1525a893729e \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_TITLE.png.sha1 new file mode 100644 index 0000000..ae621d4 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_AUTOFILL_ASSISTANT_TITLE.png.sha1
@@ -0,0 +1 @@ +0ab00e4536b0621afa932bf2e3fd1525a893729e \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_PROACTIVE_HELP_SYNC_LINK.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_PROACTIVE_HELP_SYNC_LINK.png.sha1 new file mode 100644 index 0000000..1c36b3fe --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_PROACTIVE_HELP_SYNC_LINK.png.sha1
@@ -0,0 +1 @@ +16a54b7ae27afdcb1de2f961746c4612614ddced \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_WEB_ASSISTANCE_SECTION_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_WEB_ASSISTANCE_SECTION_TITLE.png.sha1 new file mode 100644 index 0000000..c8733a4 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_WEB_ASSISTANCE_SECTION_TITLE.png.sha1
@@ -0,0 +1 @@ +a8d9fbf90c9305b249b996a0bd271e26d08fbd4f \ No newline at end of file
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 4b959f7f..f7b2630 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -404,7 +404,8 @@ /*upload=*/false, options, card, LegalMessageLines(), /*upload_save_card_callback=*/ AutofillClient::UploadSaveCardPromptCallback(), - /*local_save_card_callback=*/std::move(callback), GetPrefs()))); + /*local_save_card_callback=*/std::move(callback), GetPrefs()), + base::nullopt)); #else // Do lazy initialization of SaveCardBubbleControllerImpl. SaveCardBubbleControllerImpl::CreateForWebContents(web_contents()); @@ -428,9 +429,19 @@ /*upload_save_card_callback=*/std::move(callback), /*local_save_card_callback=*/ AutofillClient::LocalSaveCardPromptCallback(), GetPrefs()); + bool sync_disabled_wallet_transport_enabled = + GetPersonalDataManager()->GetSyncSigninState() == + autofill::AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled; + + base::Optional<AccountInfo> account_info = base::nullopt; + // AccountInfo data should be passed down only if sync is off and user has + // multiple accounts. + if (sync_disabled_wallet_transport_enabled && IsMultipleAccountUser()) { + account_info = GetAccountInfo(); + } InfoBarService::FromWebContents(web_contents()) ->AddInfoBar(CreateSaveCardInfoBarMobile( - std::move(save_card_info_bar_delegate_mobile))); + std::move(save_card_info_bar_delegate_mobile), account_info)); #else // Do lazy initialization of SaveCardBubbleControllerImpl. SaveCardBubbleControllerImpl::CreateForWebContents(web_contents()); @@ -718,6 +729,22 @@ return Profile::FromBrowserContext(web_contents()->GetBrowserContext()); } +base::Optional<AccountInfo> ChromeAutofillClient::GetAccountInfo() { + signin::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(GetProfile()); + CoreAccountId account_id = + identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kNotRequired); + return identity_manager + ->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId( + account_id); +} + +bool ChromeAutofillClient::IsMultipleAccountUser() { + signin::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(GetProfile()); + return identity_manager->GetAccountsWithRefreshTokens().size() > 1; +} + base::string16 ChromeAutofillClient::GetAccountHolderName() { Profile* profile = GetProfile(); if (!profile)
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index 1233d02..cd0cdd1 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -14,6 +14,7 @@ #include "base/i18n/rtl.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "build/build_config.h" #include "chrome/browser/autofill/autofill_gstatic_reader.h" #include "chrome/browser/profiles/profile.h" @@ -21,6 +22,7 @@ #include "components/autofill/core/browser/logging/log_manager.h" #include "components/autofill/core/browser/payments/legal_message_line.h" #include "components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h" +#include "components/signin/public/identity_manager/account_info.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" @@ -174,6 +176,8 @@ explicit ChromeAutofillClient(content::WebContents* web_contents); Profile* GetProfile() const; + base::Optional<AccountInfo> GetAccountInfo(); + bool IsMultipleAccountUser(); base::string16 GetAccountHolderName(); std::unique_ptr<payments::PaymentsClient> payments_client_;
diff --git a/chrome/browser/ui/cocoa/notifications/unnotification_builder_mac_unittest.mm b/chrome/browser/ui/cocoa/notifications/unnotification_builder_mac_unittest.mm index 361c1c5..021c0bb8 100644 --- a/chrome/browser/ui/cocoa/notifications/unnotification_builder_mac_unittest.mm +++ b/chrome/browser/ui/cocoa/notifications/unnotification_builder_mac_unittest.mm
@@ -32,6 +32,7 @@ [builder setProfileId:@"profileId"]; [builder setIncognito:false]; [builder setCreatorPid:@1]; + [builder setShowSettingsButton:NO]; [builder setNotificationType:[NSNumber numberWithInt:static_cast<int>(type)]]; return builder; }
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc index abdef13..42db5197 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.cc +++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -14,7 +14,7 @@ #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/numerics/ranges.h" -#include "base/stl_util.h" +#include "base/ranges/algorithm.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" @@ -973,7 +973,7 @@ if (group.has_value()) { auto grouped_tabs = group_model_->GetTabGroup(group.value())->ListTabs(); if (grouped_tabs.size() > 0) { - DCHECK(base::STLIsSorted(grouped_tabs)); + DCHECK(base::ranges::is_sorted(grouped_tabs)); index = base::ClampToRange(index, grouped_tabs.front(), grouped_tabs.back() + 1); } @@ -2039,7 +2039,7 @@ std::vector<int> new_indices = SetTabsPinned(indices, false); std::vector<int> tabs_in_group = group_model_->GetTabGroup(group)->ListTabs(); - DCHECK(base::STLIsSorted(tabs_in_group)); + DCHECK(base::ranges::is_sorted(tabs_in_group)); // Split |new_indices| into |tabs_left_of_group| and |tabs_right_of_group| to // be moved to proper destination index. Directly set the group for indices
diff --git a/chrome/browser/ui/views/extensions/extension_dialog.cc b/chrome/browser/ui/views/extensions/extension_dialog.cc index 7421a79..b19fad12 100644 --- a/chrome/browser/ui/views/extensions/extension_dialog.cc +++ b/chrome/browser/ui/views/extensions/extension_dialog.cc
@@ -30,7 +30,7 @@ #if defined(OS_CHROMEOS) #include "ash/public/cpp/tablet_mode.h" -#include "ash/public/cpp/window_properties.h" +#include "chromeos/ui/base/window_properties.h" #include "ui/aura/window.h" #endif @@ -226,12 +226,12 @@ aura::Window* native_view = window->GetNativeWindow(); if (init_params.title_color) { // Frame active color changes the title color when dialog is active. - native_view->SetProperty(ash::kFrameActiveColorKey, + native_view->SetProperty(chromeos::kFrameActiveColorKey, init_params.title_color.value()); } if (init_params.title_inactive_color) { // Frame inactive color changes the title color when dialog is inactive. - native_view->SetProperty(ash::kFrameInactiveColorKey, + native_view->SetProperty(chromeos::kFrameInactiveColorKey, init_params.title_inactive_color.value()); } #endif
diff --git a/chrome/browser/ui/views/frame/browser_frame_header_ash.cc b/chrome/browser/ui/views/frame/browser_frame_header_ash.cc index 664fb23b..20cb922 100644 --- a/chrome/browser/ui/views/frame/browser_frame_header_ash.cc +++ b/chrome/browser/ui/views/frame/browser_frame_header_ash.cc
@@ -4,10 +4,10 @@ #include "chrome/browser/ui/views/frame/browser_frame_header_ash.h" -#include "ash/public/cpp/ash_constants.h" #include "ash/public/cpp/tablet_mode.h" #include "base/check.h" #include "chrome/app/vector_icons/vector_icons.h" +#include "chromeos/ui/base/chromeos_ui_constants.h" #include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/base/window_state_type.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" @@ -180,7 +180,7 @@ target_widget()->GetNativeWindow()->GetProperty( chromeos::kWindowStateTypeKey); int corner_radius = chromeos::IsNormalWindowStateType(state_type) - ? ash::kTopCornerRadiusWhenRestored + ? chromeos::kTopCornerRadiusWhenRestored : 0; PaintFrameImagesInRoundRect(canvas, frame_image, frame_overlay_image,
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc index dd2043f..60ad8747 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -730,12 +730,12 @@ } if (active_color) { - window->SetProperty(ash::kFrameActiveColorKey, *active_color); - window->SetProperty(ash::kFrameInactiveColorKey, + window->SetProperty(chromeos::kFrameActiveColorKey, *active_color); + window->SetProperty(chromeos::kFrameInactiveColorKey, inactive_color.value_or(*active_color)); } else { - window->ClearProperty(ash::kFrameActiveColorKey); - window->ClearProperty(ash::kFrameInactiveColorKey); + window->ClearProperty(chromeos::kFrameActiveColorKey); + window->ClearProperty(chromeos::kFrameInactiveColorKey); } if (frame_header_)
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc index 078ebc10..b31e2dd 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -1004,8 +1004,10 @@ IN_PROC_BROWSER_TEST_P(WebAppNonClientFrameViewAshTest, FrameThemeColorIsSet) { SetUpWebApp(); aura::Window* window = browser_view_->GetWidget()->GetNativeWindow(); - EXPECT_EQ(GetThemeColor(), window->GetProperty(ash::kFrameActiveColorKey)); - EXPECT_EQ(GetThemeColor(), window->GetProperty(ash::kFrameInactiveColorKey)); + EXPECT_EQ(GetThemeColor(), + window->GetProperty(chromeos::kFrameActiveColorKey)); + EXPECT_EQ(GetThemeColor(), + window->GetProperty(chromeos::kFrameInactiveColorKey)); EXPECT_EQ(gfx::kGoogleGrey200, GetActiveColor()); } @@ -1382,7 +1384,8 @@ aura::Window* window = app_browser->window()->GetNativeWindow(); window->Show(); - SkColor active_frame_color = window->GetProperty(ash::kFrameActiveColorKey); + SkColor active_frame_color = + window->GetProperty(chromeos::kFrameActiveColorKey); EXPECT_EQ(active_frame_color, SkColorSetRGB(253, 254, 255)) << "RGB: " << SkColorGetR(active_frame_color) << ", " << SkColorGetG(active_frame_color) << ", "
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc index 1c6c307a0..8dcaa49 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
@@ -242,11 +242,9 @@ } // content_settings::Observer: - void OnContentSettingChanged( - const ContentSettingsPattern& primary_pattern, - const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override { + void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, + const ContentSettingsPattern& secondary_pattern, + ContentSettingsType content_type) override { if (content_type == ContentSettingsType::PLUGINS) Proceed(); }
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.cc b/chrome/browser/ui/views/select_file_dialog_extension.cc index ba95a96e4..9c285825 100644 --- a/chrome/browser/ui/views/select_file_dialog_extension.cc +++ b/chrome/browser/ui/views/select_file_dialog_extension.cc
@@ -15,7 +15,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" @@ -84,7 +84,8 @@ // static PendingDialog* PendingDialog::GetInstance() { - return base::Singleton<PendingDialog>::get(); + static base::NoDestructor<PendingDialog> instance; + return instance.get(); } void PendingDialog::Add(SelectFileDialogExtension::RoutingID id,
diff --git a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc index b301d82e..b570ab5 100644 --- a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc +++ b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
@@ -8,7 +8,6 @@ #include "ash/public/cpp/keyboard/keyboard_switches.h" #include "ash/public/cpp/test/shell_test_api.h" -#include "ash/public/cpp/window_properties.h" #include "base/bind_helpers.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" @@ -34,6 +33,7 @@ #include "chrome/common/pref_names.h" #include "chrome/test/base/ui_test_utils.h" #include "chromeos/constants/chromeos_features.h" +#include "chromeos/ui/base/window_properties.h" #include "components/prefs/pref_service.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" @@ -625,9 +625,10 @@ dialog_->GetRenderViewHost()->GetMainFrame(); aura::Window* dialog_window = frame_host->GetNativeView()->GetToplevelWindow(); - SkColor active_color = dialog_window->GetProperty(ash::kFrameActiveColorKey); + SkColor active_color = + dialog_window->GetProperty(chromeos::kFrameActiveColorKey); SkColor inactive_color = - dialog_window->GetProperty(ash::kFrameInactiveColorKey); + dialog_window->GetProperty(chromeos::kFrameInactiveColorKey); constexpr SkColor kFilesNgTitleColor = gfx::kGoogleGrey200; if (GetParam()) {
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc index 1c0a4131..3b98db40 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -221,9 +221,7 @@ } void CoreOobeHandler::HandleInitialized() { - // TODO(crbug.com/1082670): Remove excessive logging after investigation. - LOG(ERROR) << "1082670 : CoreOobeHandler::HandleInitialized"; - + VLOG(3) << "CoreOobeHandler::HandleInitialized"; GetOobeUI()->InitializeHandlers(); AllowJavascript(); }
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc index 17b24566..80a7a372 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -577,9 +577,6 @@ OobeUI::OobeUI(content::WebUI* web_ui, const GURL& url) : ui::MojoWebUIController(web_ui, true /* enable_chrome_send */) { - // TODO(crbug.com/1082670): Remove excessive logging after investigation. - LOG(ERROR) << "1082670 : Creating new OobeUI"; - display_type_ = GetDisplayType(url); js_calls_container_ = std::make_unique<JSCallsContainer>(); @@ -699,14 +696,8 @@ } void OobeUI::InitializeHandlers() { - // TODO(crbug.com/1082670): Remove excessive logging after investigation. - LOG(ERROR) << "1082670 : OobeUI::InitializeHandlers"; - js_calls_container_->ExecuteDeferredJSCalls(web_ui()); - // TODO(crbug.com/1082670): Remove excessive logging after investigation. - LOG(ERROR) << "1082670 : OobeUI::Marking as ready and executing callbacks"; - ready_ = true; for (size_t i = 0; i < ready_callbacks_.size(); ++i) ready_callbacks_[i].Run(); @@ -737,9 +728,6 @@ } bool OobeUI::IsJSReady(const base::Closure& display_is_ready_callback) { - // TODO(crbug.com/1082670): Remove excessive logging after investigation. - LOG(ERROR) << "1082670 : OobeUI::IsJSReady? = " << ready_; - if (!ready_) ready_callbacks_.push_back(display_is_ready_callback); return ready_;
diff --git a/chrome/browser/ui/webui/settings/chromeos/internet_section.cc b/chrome/browser/ui/webui/settings/chromeos/internet_section.cc index fab78ee..20329939 100644 --- a/chrome/browser/ui/webui/settings/chromeos/internet_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
@@ -694,6 +694,13 @@ {"tetherConnectionConnectButton", IDS_SETTINGS_INTERNET_TETHER_CONNECTION_CONNECT_BUTTON}, {"tetherEnableBluetooth", IDS_ENABLE_BLUETOOTH}, + {"cellularNetworkEsimLabel", IDS_SETTINGS_INTERNET_ESIM_LABEL}, + {"cellularNetworkPsimLabel", IDS_SETTINGS_INTERNET_PSIM_LABEL}, + {"pSimNetworkNotSetup", + IDS_SETTINGS_INTERNET_PSIM_NOT_SETUP_WITH_SETUP_LINK}, + {"eSimNetworkNotSetup", + IDS_SETTINGS_INTERNET_ESIM_NOT_SETUP_WITH_SETUP_LINK}, + {"cellularNetworkTetherLabel", IDS_SETTINGS_INTERNET_TETHER_LABEL}, }; AddLocalizedStringsBulk(html_source, kLocalizedStrings); @@ -740,6 +747,11 @@ l10n_util::GetStringFUTF16( IDS_SETTINGS_INTERNET_LOOKING_FOR_MOBILE_NETWORK, GetHelpUrlWithBoard(chrome::kInstantTetheringLearnMoreURL))); + html_source->AddString( + "tetherNetworkNotSetup", + l10n_util::GetStringFUTF16( + IDS_SETTINGS_INTERNET_TETHER_NOT_SETUP_WITH_LEARN_MORE_LINK, + GetHelpUrlWithBoard(chrome::kInstantTetheringLearnMoreURL))); } void InternetSection::AddHandlers(content::WebUI* web_ui) {
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index af9f3b6..35b8a0c0 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -1683,8 +1683,6 @@ IDS_SETTINGS_SITE_SETTINGS_PROTECTED_CONTENT_ENABLE_IDENTIFIERS}, #endif {"siteSettingsPopups", IDS_SETTINGS_SITE_SETTINGS_POPUPS}, - {"siteSettingsUnsandboxedPlugins", - IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS}, {"siteSettingsHidDevices", IDS_SETTINGS_SITE_SETTINGS_HID_DEVICES}, {"siteSettingsHidDevicesAsk", IDS_SETTINGS_SITE_SETTINGS_HID_DEVICES_ASK}, {"siteSettingsHidDevicesAskRecommended", @@ -1758,12 +1756,6 @@ IDS_SETTINGS_SITE_SETTINGS_AUTOMATIC_DOWNLOAD_ASK_RECOMMENDED}, {"siteSettingsAutoDownloadBlock", IDS_SETTINGS_SITE_SETTINGS_AUTOMATIC_DOWNLOAD_BLOCK}, - {"siteSettingsUnsandboxedPluginsAsk", - IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ASK}, - {"siteSettingsUnsandboxedPluginsAskRecommended", - IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ASK_RECOMMENDED}, - {"siteSettingsUnsandboxedPluginsBlock", - IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_BLOCK}, {"siteSettingsDontShowImages", IDS_SETTINGS_SITE_SETTINGS_DONT_SHOW_IMAGES}, {"siteSettingsShowAll", IDS_SETTINGS_SITE_SETTINGS_SHOW_ALL}, {"siteSettingsShowAllRecommended", @@ -2115,16 +2107,6 @@ IDS_SETTINGS_SITE_SETTINGS_SOUND_ALLOWED_EXCEPTIONS}, {"siteSettingsSoundBlockedExceptions", IDS_SETTINGS_SITE_SETTINGS_SOUND_BLOCKED_EXCEPTIONS}, - {"siteSettingsUnsandboxedPluginsDescription", - IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_DESCRIPTION}, - {"siteSettingsUnsandboxedPluginsAllowed", - IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ALLOWED}, - {"siteSettingsUnsandboxedPluginsBlocked", - IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_BLOCKED}, - {"siteSettingsUnsandboxedPluginsAllowedExceptions", - IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_ALLOWED_EXCEPTIONS}, - {"siteSettingsUnsandboxedPluginsBlockedExceptions", - IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS_BLOCKED_EXCEPTIONS}, {"siteSettingsUsbDescription", IDS_SETTINGS_SITE_SETTINGS_USB_DESCRIPTION}, {"siteSettingsUsbAllowed", IDS_SETTINGS_SITE_SETTINGS_USB_ALLOWED}, {"siteSettingsUsbBlocked", IDS_SETTINGS_SITE_SETTINGS_USB_BLOCKED},
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc index cf9a3086..9a28e12c 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -582,8 +582,7 @@ void SiteSettingsHandler::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { if (!site_settings::HasRegisteredGroupName(content_type)) return;
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.h b/chrome/browser/ui/webui/settings/site_settings_handler.h index 197855f..54c9689 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.h +++ b/chrome/browser/ui/webui/settings/site_settings_handler.h
@@ -76,8 +76,7 @@ // content_settings::Observer: void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // ProfileObserver: void OnOffTheRecordProfileCreated(Profile* off_the_record) override;
diff --git a/chrome/browser/ui/webui/webui_allowlist_provider_unittest.cc b/chrome/browser/ui/webui/webui_allowlist_provider_unittest.cc index e845e53..f52e0c7f 100644 --- a/chrome/browser/ui/webui/webui_allowlist_provider_unittest.cc +++ b/chrome/browser/ui/webui/webui_allowlist_provider_unittest.cc
@@ -174,11 +174,9 @@ size_t change_counter() { return change_counter_; } // content_settings::Observer: - void OnContentSettingChanged( - const ContentSettingsPattern& primary_pattern, - const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override { + void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, + const ContentSettingsPattern& secondary_pattern, + ContentSettingsType content_type) override { change_counter_++; }
diff --git a/chrome/browser/web_applications/components/external_app_install_features.cc b/chrome/browser/web_applications/components/external_app_install_features.cc index 3b7ed43..63dd9c87 100644 --- a/chrome/browser/web_applications/components/external_app_install_features.cc +++ b/chrome/browser/web_applications/components/external_app_install_features.cc
@@ -40,7 +40,7 @@ #if defined(OS_CHROMEOS) // Enable or disables running the Camera App as a System Web App. const base::Feature kCameraSystemWebApp{"CameraSystemWebApp", - base::FEATURE_ENABLED_BY_DEFAULT}; + base::FEATURE_DISABLED_BY_DEFAULT}; #endif // OS_CHROMEOS bool IsExternalAppInstallFeatureEnabled(base::StringPiece feature_name) {
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 05be272..fb2a4802 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1604966213-470516c2fd4e526d214b1511f3d83ecfab2ce340.profdata +chrome-linux-master-1605009236-ea4b3e0cf6b6eb37089f063eb3b9762bfdc69494.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 1e7fc106..e85b5ed1 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1604987499-7dfc90285fa0600b167fa15e7d7c9c3f744524d3.profdata +chrome-mac-master-1605009236-712b615a5b080d19851b96ffa1d3eb36eb083647.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index aaf8f76..19f90a5 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1604955437-61247d42a6140f126d61086b5421948904b6ffb0.profdata +chrome-win32-master-1604987499-d58c7c50ae14a2e4ca32a9270333a79aabab2447.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 5e81f26..17ea906 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1604966213-11b581102b343c7a1c3accf4f99e5d9072414c62.profdata +chrome-win64-master-1604987499-9d0e7b1f2ad8a8a8d61e84a818ba5c2f2988369e.profdata
diff --git a/chrome/common/extensions/api/terminal_private.json b/chrome/common/extensions/api/terminal_private.json index 6acab80..91b25e9 100644 --- a/chrome/common/extensions/api/terminal_private.json +++ b/chrome/common/extensions/api/terminal_private.json
@@ -174,11 +174,6 @@ "description": "Called from |onProcessOutput| when the event is dispatched to terminal extension. Observing the terminal process output will be paused after |onProcessOutput| is dispatched until this method is called.", "parameters": [ { - "name": "tabId", - "type": "integer", - "description": "Tab ID from |onProcessOutput| event." - }, - { "name": "id", "type": "string", "description": "The id of the process to which |onProcessOutput| was dispatched."
diff --git a/chrome/common/extensions/docs/examples/api/contentSettings/popup.js b/chrome/common/extensions/docs/examples/api/contentSettings/popup.js index 214e454..c623a8c 100644 --- a/chrome/common/extensions/docs/examples/api/contentSettings/popup.js +++ b/chrome/common/extensions/docs/examples/api/contentSettings/popup.js
@@ -25,9 +25,10 @@ var current = tabs[0]; incognito = current.incognito; url = current.url; - var types = ['cookies', 'images', 'javascript', 'location', 'plugins', - 'popups', 'notifications', 'microphone', 'camera', - 'unsandboxedPlugins', 'automaticDownloads']; + var types = [ + 'cookies', 'images', 'javascript', 'location', 'popups', 'notifications', + 'microphone', 'camera', 'automaticDownloads' + ]; types.forEach(function(type) { // HACK: [type] is not recognised by the docserver's sample crawler, so // mention an explicit
diff --git a/chrome/renderer/resources/extensions/terminal_private_custom_bindings.js b/chrome/renderer/resources/extensions/terminal_private_custom_bindings.js index 49957cc..72ee617 100644 --- a/chrome/renderer/resources/extensions/terminal_private_custom_bindings.js +++ b/chrome/renderer/resources/extensions/terminal_private_custom_bindings.js
@@ -3,14 +3,12 @@ // found in the LICENSE file. // Custom bindings for chrome.terminalPrivate API. -bindingUtil.registerEventArgumentMassager('terminalPrivate.onProcessOutput', - function(args, dispatch) { - var tabId = args[0]; - var terminalId = args[1]; - try { - // Remove tabId from event args, as it's not expected by listeners. - dispatch(args.slice(1)); - } finally { - chrome.terminalPrivate.ackOutput(tabId, terminalId); - } -}); +bindingUtil.registerEventArgumentMassager( + 'terminalPrivate.onProcessOutput', function(args, dispatch) { + const terminalId = args[0]; + try { + dispatch(args); + } finally { + chrome.terminalPrivate.ackOutput(terminalId); + } + });
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 9e2c218..567113c 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3543,7 +3543,6 @@ "../browser/page_load_metrics/observers/translate_page_load_metrics_observer_unittest.cc", "../browser/paint_preview/services/paint_preview_tab_service_unittest.cc", "../browser/password_manager/chrome_password_manager_client_unittest.cc", - "../browser/password_manager/password_store_x_unittest.cc", "../browser/performance_hints/performance_hints_observer_unittest.cc", "../browser/performance_hints/rewrite_handler_unittest.cc", "../browser/performance_manager/decorators/execution_context_priority_decorator_unittest.cc", @@ -3566,6 +3565,7 @@ "../browser/permissions/crowd_deny_preload_data_unittest.cc", "../browser/permissions/crowd_deny_safe_browsing_request_unittest.cc", "../browser/permissions/permission_context_base_feature_policy_unittest.cc", + "../browser/permissions/pref_notification_permission_ui_selector_unittest.cc", "../browser/persisted_state_db/persisted_state_db_factory_unittest.cc", "../browser/persisted_state_db/persisted_state_db_unittest.cc", "../browser/plugins/pdf_iframe_navigation_throttle_unittest.cc", @@ -3908,6 +3908,7 @@ "../browser/mac/exception_processor_unittest.mm", "../browser/mac/keystone_glue_unittest.mm", "../browser/notifications/notification_platform_bridge_mac_unittest.mm", + "../browser/notifications/notification_platform_bridge_mac_unnotification_unittest.mm", "../browser/notifications/notification_platform_bridge_mac_utils_unittest.mm", "../browser/notifications/stub_alert_dispatcher_mac.h", "../browser/notifications/stub_alert_dispatcher_mac.mm", @@ -5781,8 +5782,6 @@ } if (use_x11) { deps += [ "//ui/events/devices" ] - } else { - sources -= [ "../browser/password_manager/password_store_x_unittest.cc" ] } if ((is_linux || is_chromeos) && use_aura) { deps += [ "//ui/aura:test_support" ]
diff --git a/chrome/test/data/extensions/api_test/content_settings/incognitoisolation/test.js b/chrome/test/data/extensions/api_test/content_settings/incognitoisolation/test.js index dd68e69..18027e42 100644 --- a/chrome/test/data/extensions/api_test/content_settings/incognitoisolation/test.js +++ b/chrome/test/data/extensions/api_test/content_settings/incognitoisolation/test.js
@@ -24,7 +24,6 @@ 'notifications', 'microphone', 'camera', - 'unsandboxedPlugins', 'automaticDownloads' ];
diff --git a/chrome/test/data/extensions/api_test/content_settings/standard/test.js b/chrome/test/data/extensions/api_test/content_settings/standard/test.js index 3935bdd..923e3293 100644 --- a/chrome/test/data/extensions/api_test/content_settings/standard/test.js +++ b/chrome/test/data/extensions/api_test/content_settings/standard/test.js
@@ -17,7 +17,6 @@ "mouselock": "ask", "microphone": "ask", "camera": "ask", - "unsandboxedPlugins": "ask", "automaticDownloads": "ask" }; @@ -32,7 +31,6 @@ "mouselock": "block", // Should be ignored. "microphone": "block", "camera": "block", - "unsandboxedPlugins": "block", "automaticDownloads": "block" };
diff --git a/chrome/test/data/extensions/api_test/terminal/component_extension/test.js b/chrome/test/data/extensions/api_test/terminal/component_extension/test.js index 3344d81..baa3db7 100644 --- a/chrome/test/data/extensions/api_test/terminal/component_extension/test.js +++ b/chrome/test/data/extensions/api_test/terminal/component_extension/test.js
@@ -288,4 +288,23 @@ }); }, + function invalidTerminalIdTest() { + const foreign_id = (new URLSearchParams(location.search)).get('foreign_id'); + chrome.test.assertTrue(!!foreign_id); + + const callbackFail = chrome.test.callbackFail; + + [foreign_id, 'invalid id'].forEach((id) => { + // Ideally, we will also want to test ackOutput, but it does not have a + // result callback. + chrome.terminalPrivate.closeTerminalProcess( + id, callbackFail('invalid terminal id')); + // If this manages to write to the `foreign_id` process, we should detect + // some output in terminal_private_apitest.cc. + chrome.terminalPrivate.sendInput( + id, 'hello', callbackFail('invalid terminal id')); + chrome.terminalPrivate.onTerminalResize( + id, 10, 10, callbackFail('invalid terminal id')); + }); + }, ]);
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 4cd92e23..5a7a369 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -5017,15 +5017,7 @@ }, "EcryptfsMigrationStrategy": { - "os": ["chromeos"], - "policy_pref_mapping_test": [ - { - "policies": { - "EcryptfsMigrationStrategy": 1 - }, - "prefs": { "ecryptfs_migration_strategy": {} } - } - ] + "note": "This policy is deprecated and removed since Chrome 88." }, "SchedulerConfiguration": {
diff --git a/chrome/test/data/webui/settings/chromeos/internet_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/internet_subpage_tests.js index 98ab4ba0..8064126 100644 --- a/chrome/test/data/webui/settings/chromeos/internet_subpage_tests.js +++ b/chrome/test/data/webui/settings/chromeos/internet_subpage_tests.js
@@ -55,6 +55,20 @@ internetSubpage.deviceState = mojoApi_.getDeviceStateForTest(type); } + function setCellularNetworks() { + const mojom = chromeos.networkConfig.mojom; + mojoApi_.setNetworkTypeEnabledState(mojom.NetworkType.kTether); + setNetworksForTest(mojom.NetworkType.kCellular, [ + OncMojo.getDefaultNetworkState(mojom.NetworkType.kCellular, 'cellular1'), + OncMojo.getDefaultNetworkState(mojom.NetworkType.kTether, 'tether1'), + OncMojo.getDefaultNetworkState(mojom.NetworkType.kTether, 'tether2'), + ]); + internetSubpage.tetherDeviceState = { + type: mojom.NetworkType.kTether, + deviceState: mojom.DeviceStateType.kEnabled + }; + } + function initSubpage(isUpdatedCellularUiEnabled) { if (isUpdatedCellularUiEnabled !== undefined) { loadTimeData.overrideValues( @@ -118,7 +132,7 @@ }); test('Tether', function() { - initSubpage(); + initSubpage(false); const mojom = chromeos.networkConfig.mojom; setNetworksForTest(mojom.NetworkType.kTether, [ OncMojo.getDefaultNetworkState(mojom.NetworkType.kTether, 'tether1'), @@ -167,7 +181,7 @@ }); test('Fire show cellular setup event on add cellular clicked', () => { - initSubpage(); + initSubpage(true); const mojom = chromeos.networkConfig.mojom; mojoApi_.setNetworkTypeEnabledState(mojom.NetworkType.kCellular); setNetworksForTest(mojom.NetworkType.kCellular, [ @@ -193,33 +207,45 @@ }); }); - test('Tether plus Cellular', function() { - initSubpage(false /* isUpdatedCellularUiEnabled */); - const mojom = chromeos.networkConfig.mojom; - mojoApi_.setNetworkTypeEnabledState(mojom.NetworkType.kTether); - setNetworksForTest(mojom.NetworkType.kCellular, [ - OncMojo.getDefaultNetworkState( - mojom.NetworkType.kCellular, 'cellular1'), - OncMojo.getDefaultNetworkState(mojom.NetworkType.kTether, 'tether1'), - OncMojo.getDefaultNetworkState(mojom.NetworkType.kTether, 'tether2'), - ]); - internetSubpage.tetherDeviceState = { - type: mojom.NetworkType.kTether, - deviceState: mojom.DeviceStateType.kEnabled - }; - return flushAsync().then(() => { - assertEquals(3, internetSubpage.networkStateList_.length); - const toggle = internetSubpage.$$('#deviceEnabledButton'); - assertTrue(!!toggle); - assertFalse(toggle.disabled); - const networkList = internetSubpage.$$('#networkList'); - assertTrue(!!networkList); - assertEquals(3, networkList.networks.length); - const tetherToggle = internetSubpage.$$('#tetherEnabledButton'); - assertTrue(!!tetherToggle); - assertFalse(tetherToggle.disabled); - }); - }); + test( + 'Tether plus Cellular with updatedCellularActivationUi false', + function() { + initSubpage(false /* isUpdatedCellularUiEnabled */); + const mojom = chromeos.networkConfig.mojom; + setCellularNetworks(); + return flushAsync().then(() => { + assertEquals(3, internetSubpage.networkStateList_.length); + const toggle = internetSubpage.$$('#deviceEnabledButton'); + assertTrue(!!toggle); + assertFalse(toggle.disabled); + const networkList = internetSubpage.$$('#networkList'); + assertTrue(!!networkList); + assertEquals(3, networkList.networks.length); + const tetherToggle = internetSubpage.$$('#tetherEnabledButton'); + assertTrue(!!tetherToggle); + assertFalse(tetherToggle.disabled); + }); + }); + + test( + 'Tether plus Cellular with updatedCellularActivationUi true', + function() { + initSubpage(true /* isUpdatedCellularUiEnabled */); + const mojom = chromeos.networkConfig.mojom; + setCellularNetworks(); + return flushAsync().then(() => { + assertEquals(3, internetSubpage.networkStateList_.length); + const toggle = internetSubpage.$$('#deviceEnabledButton'); + assertTrue(!!toggle); + assertFalse(toggle.disabled); + const cellularNetworkList = + internetSubpage.$$('#cellularNetworkList'); + assertTrue(!!cellularNetworkList); + assertEquals(3, cellularNetworkList.networks.length); + const tetherToggle = internetSubpage.$$('#tetherEnabledButton'); + assertFalse(!!tetherToggle); + }); + }); test('Deep link to tether on/off toggle w/ cellular', async () => { initSubpage(false /* isUpdatedCellularUiEnabled */);
diff --git a/chrome/test/data/webui/settings/privacy_page_test.js b/chrome/test/data/webui/settings/privacy_page_test.js index 4fcb202..c8905100 100644 --- a/chrome/test/data/webui/settings/privacy_page_test.js +++ b/chrome/test/data/webui/settings/privacy_page_test.js
@@ -39,7 +39,6 @@ routes.SITE_SETTINGS_SENSORS, routes.SITE_SETTINGS_SERIAL_PORTS, routes.SITE_SETTINGS_SOUND, - routes.SITE_SETTINGS_UNSANDBOXED_PLUGINS, routes.SITE_SETTINGS_USB_DEVICES, routes.SITE_SETTINGS_VR,
diff --git a/chrome/test/data/webui/settings/site_details_tests.js b/chrome/test/data/webui/settings/site_details_tests.js index d275c5b..d74e5b9 100644 --- a/chrome/test/data/webui/settings/site_details_tests.js +++ b/chrome/test/data/webui/settings/site_details_tests.js
@@ -102,9 +102,6 @@ ContentSettingsTypes.CAMERA, [createRawSiteException('https://foo.com:443')]), createContentSettingTypeToValuePair( - ContentSettingsTypes.UNSANDBOXED_PLUGINS, - [createRawSiteException('https://foo.com:443')]), - createContentSettingTypeToValuePair( ContentSettingsTypes.AUTOMATIC_DOWNLOADS, [createRawSiteException('https://foo.com:443')]), createContentSettingTypeToValuePair(
diff --git a/chromecast/base/chromecast_switches.cc b/chromecast/base/chromecast_switches.cc index 16d95afd..68b80b1 100644 --- a/chromecast/base/chromecast_switches.cc +++ b/chromecast/base/chromecast_switches.cc
@@ -183,6 +183,9 @@ // Whether to enable detection and dispatch of a 'drag from the top' gesture. const char kEnableTopDragGesture[] = "enable-top-drag-gesture"; +// Whether to enable the drawing of rounded window corners in the root window. +const char kEnableRoundedWindowCorners[] = "enable-rounded-window-corners"; + // Endpoint that the mixer service listens on. This is a path for a UNIX domain // socket (default is /tmp/mixer-service). const char kMixerServiceEndpoint[] = "mixer-service-endpoint";
diff --git a/chromecast/base/chromecast_switches.h b/chromecast/base/chromecast_switches.h index 10f84d6..d06ee62 100644 --- a/chromecast/base/chromecast_switches.h +++ b/chromecast/base/chromecast_switches.h
@@ -83,6 +83,7 @@ extern const char kBottomSystemGestureStartHeight[]; extern const char kBackGestureHorizontalThreshold[]; extern const char kEnableTopDragGesture[]; +extern const char kEnableRoundedWindowCorners[]; // Background color used when Chromium hasn't rendered anything yet. extern const char kCastAppBackgroundColor[];
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index 7ca713c..c4df1037 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -602,8 +602,11 @@ CAST_IS_DEBUG_BUILD() || GetSwitchValueBoolean(switches::kEnableInput, false)); window_manager_->Setup(); - rounded_window_corners_manager_ = - std::make_unique<RoundedWindowCornersManager>(window_manager_.get()); + + if (GetSwitchValueBoolean(switches::kEnableRoundedWindowCorners, false)) { + rounded_window_corners_manager_ = + std::make_unique<RoundedWindowCornersManager>(window_manager_.get()); + } #if BUILDFLAG(ENABLE_CHROMECAST_EXTENSIONS) cast_browser_process_->SetAccessibilityManager(
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 0d0a3d90..1689910 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -504,6 +504,15 @@ <message name="IDS_SCANNING_APP_COLOR_MODE_DROPDOWN_LABEL" desc="The label for the dropdown that displays available color modes (e.g. color, grayscale, black and white, etc.)."> Color </message> + <message name="IDS_SCANNING_APP_BLACK_AND_WHITE_OPTION_TEXT" desc="The text displayed for the black and white option in the color mode dropdown."> + Black and white + </message> + <message name="IDS_SCANNING_APP_COLOR_OPTION_TEXT" desc="The text displayed for the color option in the color mode dropdown."> + Color + </message> + <message name="IDS_SCANNING_APP_GRAYSCALE_OPTION_TEXT" desc="The text displayed for the grayscale option in the color mode dropdown."> + Grayscale + </message> <message name="IDS_SCANNING_APP_PAGE_SIZE_DROPDOWN_LABEL" desc="The label for the dropdown that displays available page sizes."> Page size </message>
diff --git a/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_BLACK_AND_WHITE_OPTION_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_BLACK_AND_WHITE_OPTION_TEXT.png.sha1 new file mode 100644 index 0000000..402f5383 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_BLACK_AND_WHITE_OPTION_TEXT.png.sha1
@@ -0,0 +1 @@ +016e35a3f93fdde45296d67436693e542d832cfd \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_COLOR_OPTION_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_COLOR_OPTION_TEXT.png.sha1 new file mode 100644 index 0000000..402f5383 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_COLOR_OPTION_TEXT.png.sha1
@@ -0,0 +1 @@ +016e35a3f93fdde45296d67436693e542d832cfd \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_GRAYSCALE_OPTION_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_GRAYSCALE_OPTION_TEXT.png.sha1 new file mode 100644 index 0000000..402f5383 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_GRAYSCALE_OPTION_TEXT.png.sha1
@@ -0,0 +1 @@ +016e35a3f93fdde45296d67436693e542d832cfd \ No newline at end of file
diff --git a/chromeos/components/diagnostics_ui/backend/system_data_provider_unittest.cc b/chromeos/components/diagnostics_ui/backend/system_data_provider_unittest.cc index ff23b2a..d80d04b 100644 --- a/chromeos/components/diagnostics_ui/backend/system_data_provider_unittest.cc +++ b/chromeos/components/diagnostics_ui/backend/system_data_provider_unittest.cc
@@ -106,8 +106,8 @@ const std::string& status, const base::Optional<std::string>& manufacture_date, uint64_t temperature) { - cros_healthd::mojom::UInt64ValuePtr temp_value_ptr( - cros_healthd::mojom::UInt64Value::New()); + cros_healthd::mojom::NullableUint64Ptr temp_value_ptr( + cros_healthd::mojom::NullableUint64::New()); if (temperature != 0) { temp_value_ptr->value = temperature; }
diff --git a/chromeos/components/scanning/resources/scanning_app_util.js b/chromeos/components/scanning/resources/scanning_app_util.js index 9961dde6..376d7f78 100644 --- a/chromeos/components/scanning/resources/scanning_app_util.js +++ b/chromeos/components/scanning/resources/scanning_app_util.js
@@ -52,17 +52,16 @@ * @return {string} */ export function getColorModeString(mojoColorMode) { - // TODO(jschettler): Replace with finalized i18n strings. switch (mojoColorMode) { case chromeos.scanning.mojom.ColorMode.kBlackAndWhite: - return 'Black and White'; + return loadTimeData.getString('blackAndWhiteOptionText'); case chromeos.scanning.mojom.ColorMode.kGrayscale: - return 'Grayscale'; + return loadTimeData.getString('grayscaleOptionText'); case chromeos.scanning.mojom.ColorMode.kColor: - return 'Color'; + return loadTimeData.getString('colorOptionText'); default: assertNotReached(); - return 'Unknown'; + return loadTimeData.getString('blackAndWhiteOptionText'); } }
diff --git a/chromeos/components/scanning/scanning_ui.cc b/chromeos/components/scanning/scanning_ui.cc index 50344ef15..767dcb2 100644 --- a/chromeos/components/scanning/scanning_ui.cc +++ b/chromeos/components/scanning/scanning_ui.cc
@@ -53,10 +53,13 @@ void AddScanningAppStrings(content::WebUIDataSource* html_source) { static constexpr webui::LocalizedString kLocalizedStrings[] = { {"appTitle", IDS_SCANNING_APP_TITLE}, + {"blackAndWhiteOptionText", IDS_SCANNING_APP_BLACK_AND_WHITE_OPTION_TEXT}, {"colorModeDropdownLabel", IDS_SCANNING_APP_COLOR_MODE_DROPDOWN_LABEL}, + {"colorOptionText", IDS_SCANNING_APP_COLOR_OPTION_TEXT}, {"defaultSourceOptionText", IDS_SCANNING_APP_DEFAULT_SOURCE_OPTION_TEXT}, {"flatbedOptionText", IDS_SCANNING_APP_FLATBED_OPTION_TEXT}, {"fileTypeDropdownLabel", IDS_SCANNING_APP_FILE_TYPE_DROPDOWN_LABEL}, + {"grayscaleOptionText", IDS_SCANNING_APP_GRAYSCALE_OPTION_TEXT}, {"jpgOptionText", IDS_SCANNING_APP_JPG_OPTION_TEXT}, {"moreSettings", IDS_SCANNING_APP_MORE_SETTINGS}, {"myFilesSelectOption", IDS_SCANNING_APP_MY_FILES_SELECT_OPTION},
diff --git a/chromeos/components/sync_wifi/wifi_configuration_bridge.cc b/chromeos/components/sync_wifi/wifi_configuration_bridge.cc index d44eedd..e23cb456 100644 --- a/chromeos/components/sync_wifi/wifi_configuration_bridge.cc +++ b/chromeos/components/sync_wifi/wifi_configuration_bridge.cc
@@ -24,6 +24,8 @@ #include "chromeos/network/network_event_log.h" #include "chromeos/network/network_metadata_store.h" #include "components/device_event_log/device_event_log.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" #include "components/sync/model/entity_change.h" #include "components/sync/model/metadata_batch.h" #include "components/sync/model/metadata_change_list.h" @@ -60,6 +62,7 @@ NetworkConfigurationHandler* network_configuration_handler, SyncedNetworkMetricsLogger* metrics_recorder, TimerFactory* timer_factory, + PrefService* pref_service, std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor, syncer::OnceModelTypeStoreFactory create_store_callback) : ModelTypeSyncBridge(std::move(change_processor)), @@ -68,6 +71,7 @@ network_configuration_handler_(network_configuration_handler), metrics_recorder_(metrics_recorder), timer_factory_(timer_factory), + pref_service_(pref_service), network_metadata_store_(nullptr) { std::move(create_store_callback) .Run(syncer::WIFI_CONFIGURATIONS, @@ -82,6 +86,11 @@ OnShuttingDown(); } +// static +void WifiConfigurationBridge::RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(kIsFirstRun, true); +} + void WifiConfigurationBridge::OnShuttingDown() { if (network_metadata_store_) { network_metadata_store_->RemoveObserver(this); @@ -302,11 +311,22 @@ } entries_[record.id] = std::move(data); } - - metrics_recorder_->RecordTotalCount(entries_.size()); store_->ReadAllMetadata( base::BindOnce(&WifiConfigurationBridge::OnReadAllMetadata, weak_ptr_factory_.GetWeakPtr())); + + int entries_size = entries_.size(); + // Do not log the total network count during OOBE. It returns 0 even if there + // are networks synced since MergeSyncData has not executed yet. + if (pref_service_->GetBoolean(kIsFirstRun)) { + pref_service_->SetBoolean(kIsFirstRun, false); + // This is only meant to filter out 0's that are logged during OOBE. If the + // entries_size is greater than zero it should be logged. + if (entries_size == 0) { + return; + } + } + metrics_recorder_->RecordTotalCount(entries_size); } void WifiConfigurationBridge::OnReadAllMetadata(
diff --git a/chromeos/components/sync_wifi/wifi_configuration_bridge.h b/chromeos/components/sync_wifi/wifi_configuration_bridge.h index 4b04dd9..81dfe217 100644 --- a/chromeos/components/sync_wifi/wifi_configuration_bridge.h +++ b/chromeos/components/sync_wifi/wifi_configuration_bridge.h
@@ -22,6 +22,9 @@ #include "components/sync/model/model_type_store.h" #include "components/sync/model/model_type_sync_bridge.h" +class PrefRegistrySimple; +class PrefService; + namespace syncer { class ModelTypeChangeProcessor; } // namespace syncer @@ -33,6 +36,8 @@ namespace sync_wifi { +const char kIsFirstRun[] = "sync_wifi.is_first_run"; + class LocalNetworkCollector; class SyncedNetworkMetricsLogger; class SyncedNetworkUpdater; @@ -50,10 +55,13 @@ NetworkConfigurationHandler* network_configuration_handler, SyncedNetworkMetricsLogger* metrics_recorder, TimerFactory* timer_factory, + PrefService* pref_service, std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor, syncer::OnceModelTypeStoreFactory create_store_callback); ~WifiConfigurationBridge() override; + static void RegisterPrefs(PrefRegistrySimple* registry); + // syncer::ModelTypeSyncBridge: std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList() override; @@ -141,6 +149,7 @@ NetworkConfigurationHandler* network_configuration_handler_; SyncedNetworkMetricsLogger* metrics_recorder_; TimerFactory* timer_factory_; + PrefService* pref_service_; base::WeakPtr<NetworkMetadataStore> network_metadata_store_; base::WeakPtrFactory<WifiConfigurationBridge> weak_ptr_factory_{this};
diff --git a/chromeos/components/sync_wifi/wifi_configuration_bridge_unittest.cc b/chromeos/components/sync_wifi/wifi_configuration_bridge_unittest.cc index 8bb5a21..3964f5d 100644 --- a/chromeos/components/sync_wifi/wifi_configuration_bridge_unittest.cc +++ b/chromeos/components/sync_wifi/wifi_configuration_bridge_unittest.cc
@@ -61,6 +61,7 @@ const char kSsidHonk[] = "honk"; const char kSyncPsk[] = "sync_psk"; const char kLocalPsk[] = "local_psk"; +const char kIsFirstRun[] = "sync_wifi.is_first_run"; syncer::EntityData GenerateWifiEntityData( const sync_pb::WifiConfigurationSpecifics& data) { @@ -157,6 +158,9 @@ device_prefs_ = std::make_unique<TestingPrefServiceSimple>(); NetworkMetadataStore::RegisterPrefs(user_prefs_->registry()); NetworkMetadataStore::RegisterPrefs(device_prefs_->registry()); + + user_prefs_->registry()->RegisterBooleanPref(kIsFirstRun, true); + network_metadata_store_ = std::make_unique<NetworkMetadataStore>( /*network_configuration_handler=*/nullptr, /*network_connection_handler=*/nullptr, @@ -164,13 +168,23 @@ user_prefs_.get(), device_prefs_.get(), /*is_enterprise_enrolled=*/false); + base::HistogramTester histogram_tester; bridge_ = std::make_unique<WifiConfigurationBridge>( synced_network_updater(), local_network_collector(), /*network_configuration_handler=*/nullptr, metrics_logger_.get(), - timer_factory_.get(), mock_processor_.CreateForwardingProcessor(), + timer_factory_.get(), user_prefs_.get(), + mock_processor_.CreateForwardingProcessor(), syncer::ModelTypeStoreTestUtil::MoveStoreToFactory(std::move(store_))); bridge_->SetNetworkMetadataStore(network_metadata_store_->GetWeakPtr()); base::RunLoop().RunUntilIdle(); + + // Assert that an incorrect metric was not logged. + histogram_tester.ExpectTotalCount(kTotalCountHistogram, 0); + } + + void TearDown() override { + // TODO(cvandermerwe) Put the shutdown logic into network_test_helper. + NetworkHandler::Shutdown(); } void DisableBridge() {
diff --git a/chromeos/components/sync_wifi/wifi_configuration_sync_service.cc b/chromeos/components/sync_wifi/wifi_configuration_sync_service.cc index 22d8dee..e739e855 100644 --- a/chromeos/components/sync_wifi/wifi_configuration_sync_service.cc +++ b/chromeos/components/sync_wifi/wifi_configuration_sync_service.cc
@@ -46,7 +46,7 @@ bridge_ = std::make_unique<sync_wifi::WifiConfigurationBridge>( updater_.get(), collector_.get(), network_handler->network_configuration_handler(), metrics_logger_.get(), - timer_factory_.get(), + timer_factory_.get(), pref_service, std::make_unique<syncer::ClientTagBasedModelTypeProcessor>( syncer::WIFI_CONFIGURATIONS, base::BindRepeating(&syncer::ReportUnrecoverableError, channel)),
diff --git a/chromeos/components/telemetry_extension_ui/probe_service_converters.cc b/chromeos/components/telemetry_extension_ui/probe_service_converters.cc index 13bda94..799f219f 100644 --- a/chromeos/components/telemetry_extension_ui/probe_service_converters.cc +++ b/chromeos/components/telemetry_extension_ui/probe_service_converters.cc
@@ -56,7 +56,7 @@ } health::mojom::UInt64ValuePtr UncheckedConvertPtr( - cros_healthd::mojom::UInt64ValuePtr input) { + cros_healthd::mojom::NullableUint64Ptr input) { return health::mojom::UInt64Value::New(input->value); }
diff --git a/chromeos/components/telemetry_extension_ui/probe_service_converters.h b/chromeos/components/telemetry_extension_ui/probe_service_converters.h index f4d4ea045..c15c945 100644 --- a/chromeos/components/telemetry_extension_ui/probe_service_converters.h +++ b/chromeos/components/telemetry_extension_ui/probe_service_converters.h
@@ -32,7 +32,7 @@ cros_healthd::mojom::ProbeErrorPtr input); health::mojom::UInt64ValuePtr UncheckedConvertPtr( - cros_healthd::mojom::UInt64ValuePtr input); + cros_healthd::mojom::NullableUint64Ptr input); health::mojom::BatteryInfoPtr UncheckedConvertPtr( cros_healthd::mojom::BatteryInfoPtr input);
diff --git a/chromeos/components/telemetry_extension_ui/probe_service_converters_unittest.cc b/chromeos/components/telemetry_extension_ui/probe_service_converters_unittest.cc index 5499510c..8c34bb4 100644 --- a/chromeos/components/telemetry_extension_ui/probe_service_converters_unittest.cc +++ b/chromeos/components/telemetry_extension_ui/probe_service_converters_unittest.cc
@@ -95,7 +95,7 @@ TEST(ProbeServiceConvertors, UInt64ValuePtr) { constexpr uint64_t kValue = (1ULL << 63) + 3000000000; - EXPECT_EQ(ConvertPtr(cros_healthd::mojom::UInt64Value::New(kValue)), + EXPECT_EQ(ConvertPtr(cros_healthd::mojom::NullableUint64::New(kValue)), health::mojom::UInt64Value::New(kValue)); } @@ -130,7 +130,7 @@ input->technology = kTechnology; input->status = kStatus; input->manufacture_date = kManufactureDate; - input->temperature = cros_healthd::mojom::UInt64Value::New(kTemperature); + input->temperature = cros_healthd::mojom::NullableUint64::New(kTemperature); } EXPECT_EQ( @@ -189,7 +189,8 @@ input->write_time_seconds_since_last_boot = kWriteTimeSecondsSinceLastBoot; input->io_time_seconds_since_last_boot = kIoTimeSecondsSinceLastBoot; input->discard_time_seconds_since_last_boot = - cros_healthd::mojom::UInt64Value::New(kDiscardTimeSecondsSinceLastBoot); + cros_healthd::mojom::NullableUint64::New( + kDiscardTimeSecondsSinceLastBoot); } EXPECT_EQ(
diff --git a/chromeos/components/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.cc b/chromeos/components/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.cc index 6b2198de..0cc3c9c 100644 --- a/chromeos/components/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.cc +++ b/chromeos/components/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.cc
@@ -118,7 +118,7 @@ battery_info->status = "Charging"; battery_info->manufacture_date = "2020-07-30"; battery_info->temperature = - chromeos::cros_healthd::mojom::UInt64Value::New(7777777777777777); + chromeos::cros_healthd::mojom::NullableUint64::New(7777777777777777); telemetry_info->battery_result = chromeos::cros_healthd::mojom::BatteryResult::NewBatteryInfo( @@ -139,7 +139,7 @@ block_device_info->write_time_seconds_since_last_boot = 6666666666666666; block_device_info->io_time_seconds_since_last_boot = 1111111111111; block_device_info->discard_time_seconds_since_last_boot = - chromeos::cros_healthd::mojom::UInt64Value::New(77777777777777); + chromeos::cros_healthd::mojom::NullableUint64::New(77777777777777); // Need to put some placeholder values, otherwise Mojo will crash, because // mandatory union fields cannot be nullptr.
diff --git a/chromeos/policy/weekly_time/weekly_time.cc b/chromeos/policy/weekly_time/weekly_time.cc index 861492d..f4c9a42 100644 --- a/chromeos/policy/weekly_time/weekly_time.cc +++ b/chromeos/policy/weekly_time/weekly_time.cc
@@ -12,6 +12,7 @@ namespace policy { namespace { + constexpr base::TimeDelta kWeek = base::TimeDelta::FromDays(7); constexpr base::TimeDelta kDay = base::TimeDelta::FromDays(1); constexpr base::TimeDelta kHour = base::TimeDelta::FromHours(1); @@ -31,6 +32,11 @@ } // namespace +// static +const char WeeklyTime::kDayOfWeek[] = "day_of_week"; +const char WeeklyTime::kTime[] = "time"; +const char WeeklyTime::kTimezoneOffset[] = "timezon_offset"; + WeeklyTime::WeeklyTime(int day_of_week, int milliseconds, base::Optional<int> timezone_offset) @@ -49,10 +55,10 @@ std::unique_ptr<base::DictionaryValue> WeeklyTime::ToValue() const { auto weekly_time = std::make_unique<base::DictionaryValue>(); - weekly_time->SetInteger("day_of_week", day_of_week_); - weekly_time->SetInteger("time", milliseconds_); + weekly_time->SetInteger(kDayOfWeek, day_of_week_); + weekly_time->SetInteger(kTime, milliseconds_); if (timezone_offset_) - weekly_time->SetInteger("timezone_offset", timezone_offset_.value()); + weekly_time->SetInteger(kTimezoneOffset, timezone_offset_.value()); return weekly_time; } @@ -137,4 +143,35 @@ timezone_offset); } +// static +std::unique_ptr<WeeklyTime> WeeklyTime::ExtractFromValue( + const base::Value* value, + base::Optional<int> timezone_offset) { + if (!value) { + LOG(ERROR) << "Passed nullptr value."; + return nullptr; + } + auto day_of_week = value->FindIntKey(kDayOfWeek); + if (!day_of_week.has_value() || day_of_week.value() < 1 || + day_of_week.value() > 7) { + LOG(ERROR) << "Day of week is absent or invalid"; + return nullptr; + } + auto time_of_day = value->FindIntKey(kTime); + if (!time_of_day.has_value()) { + LOG(ERROR) << "Time is absent"; + return nullptr; + } + + if (!(time_of_day.value() >= 0 && + time_of_day.value() < kDay.InMilliseconds())) { + LOG(ERROR) << "Invalid time value: " << time_of_day.value() + << ", the value should be in [0; " << kDay.InMilliseconds() + << ")."; + return nullptr; + } + return std::make_unique<WeeklyTime>(day_of_week.value(), time_of_day.value(), + timezone_offset); +} + } // namespace policy
diff --git a/chromeos/policy/weekly_time/weekly_time.h b/chromeos/policy/weekly_time/weekly_time.h index 0431465e3..ae48e714d 100644 --- a/chromeos/policy/weekly_time/weekly_time.h +++ b/chromeos/policy/weekly_time/weekly_time.h
@@ -21,6 +21,11 @@ // beginning of the day. class CHROMEOS_EXPORT WeeklyTime { public: + // Dictionary value key constants for testing. + static const char kDayOfWeek[]; + static const char kTime[]; + static const char kTimezoneOffset[]; + WeeklyTime(int day_of_week, int milliseconds, base::Optional<int> timezone_offset); @@ -77,6 +82,16 @@ const enterprise_management::WeeklyTimeProto& container, base::Optional<int> timezone_offset); + // Return WeeklyTime structure from Value in format: + // { "day_of_week" : int # value is from 1 to 7 (1 = Monday, 2 = Tuesday, + // etc.) + // "time" : int # in milliseconds from the beginning of the day. + // }. + // Return nullptr if WeeklyTime structure isn't correct. + static std::unique_ptr<WeeklyTime> ExtractFromValue( + const base::Value* value, + base::Optional<int> timezone_offset); + // Return the current time in GMT in WeeklyTime structure. static WeeklyTime GetCurrentGmtWeeklyTime(base::Clock* clock);
diff --git a/chromeos/policy/weekly_time/weekly_time_interval.cc b/chromeos/policy/weekly_time/weekly_time_interval.cc index f10ed355..afaa1ea 100644 --- a/chromeos/policy/weekly_time/weekly_time_interval.cc +++ b/chromeos/policy/weekly_time/weekly_time_interval.cc
@@ -11,6 +11,10 @@ namespace policy { +// static +const char WeeklyTimeInterval::kStart[] = "start"; +const char WeeklyTimeInterval::kEnd[] = "end"; + WeeklyTimeInterval::WeeklyTimeInterval(const WeeklyTime& start, const WeeklyTime& end) : start_(start), end_(end) { @@ -25,8 +29,8 @@ std::unique_ptr<base::DictionaryValue> WeeklyTimeInterval::ToValue() const { auto interval = std::make_unique<base::DictionaryValue>(); - interval->SetDictionary("start", start_.ToValue()); - interval->SetDictionary("end", end_.ToValue()); + interval->SetDictionary(kStart, start_.ToValue()); + interval->SetDictionary(kEnd, end_.ToValue()); return interval; } @@ -54,4 +58,21 @@ return std::make_unique<WeeklyTimeInterval>(*start, *end); } +// static +std::unique_ptr<WeeklyTimeInterval> WeeklyTimeInterval::ExtractFromValue( + const base::Value* value, + base::Optional<int> timezone_offset) { + if (!value || !value->FindDictKey(kStart) || !value->FindDictKey(kEnd)) { + LOG(WARNING) << "Interval without start or/and end."; + return nullptr; + } + auto start = + WeeklyTime::ExtractFromValue(value->FindDictKey(kStart), timezone_offset); + auto end = + WeeklyTime::ExtractFromValue(value->FindDictKey(kEnd), timezone_offset); + if (!start || !end) + return nullptr; + return std::make_unique<WeeklyTimeInterval>(*start, *end); +} + } // namespace policy
diff --git a/chromeos/policy/weekly_time/weekly_time_interval.h b/chromeos/policy/weekly_time/weekly_time_interval.h index 376b5c7f..1800708 100644 --- a/chromeos/policy/weekly_time/weekly_time_interval.h +++ b/chromeos/policy/weekly_time/weekly_time_interval.h
@@ -21,6 +21,10 @@ // Both WeeklyTimes need to have the same timezone_offset. class CHROMEOS_EXPORT WeeklyTimeInterval { public: + // Dictionary value key constants for testing. + static const char kStart[]; + static const char kEnd[]; + WeeklyTimeInterval(const WeeklyTime& start, const WeeklyTime& end); WeeklyTimeInterval(const WeeklyTimeInterval& rhs); @@ -60,6 +64,20 @@ const enterprise_management::WeeklyTimeIntervalProto& container, base::Optional<int> timezone_offset); + // Return time interval made from Value in format: + // { "start" : WeeklyTime, + // "end" : WeeklyTime } + // WeeklyTime dictionary format: + // { "day_of_week" : int # value is from 1 to 7 (1 = Monday, 2 = Tuesday, + // etc.) + // "time" : int # in milliseconds from the beginning of the day. + // "timezone_offset" : int # in milliseconds, how much time ahead of GMT. + // } + // Return nullptr if value contains an invalid interval. + static std::unique_ptr<WeeklyTimeInterval> ExtractFromValue( + const base::Value* value, + base::Optional<int> timezone_offset); + WeeklyTime start() const { return start_; } WeeklyTime end() const { return end_; }
diff --git a/chromeos/policy/weekly_time/weekly_time_interval_unittest.cc b/chromeos/policy/weekly_time/weekly_time_interval_unittest.cc index f4ac232..9700f92e 100644 --- a/chromeos/policy/weekly_time/weekly_time_interval_unittest.cc +++ b/chromeos/policy/weekly_time/weekly_time_interval_unittest.cc
@@ -76,8 +76,10 @@ WeeklyTimeInterval interval = WeeklyTimeInterval(start, end); std::unique_ptr<base::DictionaryValue> interval_value = interval.ToValue(); base::DictionaryValue expected_interval_value; - expected_interval_value.SetDictionary("start", start.ToValue()); - expected_interval_value.SetDictionary("end", end.ToValue()); + expected_interval_value.SetDictionary(WeeklyTimeInterval::kStart, + start.ToValue()); + expected_interval_value.SetDictionary(WeeklyTimeInterval::kEnd, + end.ToValue()); EXPECT_EQ(*interval_value, expected_interval_value); } @@ -146,6 +148,90 @@ EXPECT_EQ(result->start().timezone_offset(), 0); } +TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromValue_Empty) { + base::DictionaryValue value; + auto result = WeeklyTimeInterval::ExtractFromValue(&value, 0); + ASSERT_FALSE(result); +} + +TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromValue_NoEnd) { + base::DictionaryValue value; + base::DictionaryValue start; + EXPECT_TRUE( + start.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[start_day_of_week()])); + EXPECT_TRUE(start.SetIntKey(WeeklyTime::kTime, start_time())); + value.SetKey(WeeklyTimeInterval::kStart, std::move(start)); + + auto result = WeeklyTimeInterval::ExtractFromValue(&value, 0); + ASSERT_FALSE(result); +} + +TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromValue_NoStart) { + base::DictionaryValue value; + base::DictionaryValue end; + EXPECT_TRUE( + end.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[end_day_of_week()])); + EXPECT_TRUE(end.SetIntKey(WeeklyTime::kTime, end_time())); + value.SetKey(WeeklyTimeInterval::kEnd, std::move(end)); + + auto result = WeeklyTimeInterval::ExtractFromValue(&value, 0); + ASSERT_FALSE(result); +} + +TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromValue_InvalidStart) { + base::DictionaryValue value; + base::DictionaryValue start; + EXPECT_TRUE(start.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[0])); + EXPECT_TRUE(start.SetIntKey(WeeklyTime::kTime, start_time())); + value.SetKey(WeeklyTimeInterval::kStart, std::move(start)); + base::DictionaryValue end; + EXPECT_TRUE( + end.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[end_day_of_week()])); + EXPECT_TRUE(end.SetIntKey(WeeklyTime::kTime, end_time())); + value.SetKey(WeeklyTimeInterval::kEnd, std::move(end)); + + auto result = WeeklyTimeInterval::ExtractFromValue(&value, 0); + ASSERT_FALSE(result); +} + +TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromValue_InvalidEnd) { + base::DictionaryValue value; + base::DictionaryValue start; + EXPECT_TRUE( + start.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[start_day_of_week()])); + EXPECT_TRUE(start.SetIntKey(WeeklyTime::kTime, start_time())); + value.SetKey(WeeklyTimeInterval::kStart, std::move(start)); + base::DictionaryValue end; + EXPECT_TRUE(end.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[0])); + EXPECT_TRUE(end.SetIntKey(WeeklyTime::kTime, end_time())); + value.SetKey(WeeklyTimeInterval::kEnd, std::move(end)); + + auto result = WeeklyTimeInterval::ExtractFromValue(&value, 0); + ASSERT_FALSE(result); +} + +TEST_P(SingleWeeklyTimeIntervalTest, ExtractFromValue_Valid) { + base::DictionaryValue value; + base::DictionaryValue start; + EXPECT_TRUE( + start.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[start_day_of_week()])); + EXPECT_TRUE(start.SetIntKey(WeeklyTime::kTime, start_time())); + value.SetKey(WeeklyTimeInterval::kStart, std::move(start)); + base::DictionaryValue end; + EXPECT_TRUE( + end.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[end_day_of_week()])); + EXPECT_TRUE(end.SetIntKey(WeeklyTime::kTime, end_time())); + value.SetKey(WeeklyTimeInterval::kEnd, std::move(end)); + + auto result = WeeklyTimeInterval::ExtractFromValue(&value, 0); + ASSERT_TRUE(result); + EXPECT_EQ(result->start().day_of_week(), start_day_of_week()); + EXPECT_EQ(result->start().milliseconds(), start_time()); + EXPECT_EQ(result->end().day_of_week(), end_day_of_week()); + EXPECT_EQ(result->end().milliseconds(), end_time()); + EXPECT_EQ(result->start().timezone_offset(), 0); +} + INSTANTIATE_TEST_SUITE_P(OneMinuteInterval, SingleWeeklyTimeIntervalTest, testing::Values(std::make_tuple(kWednesday,
diff --git a/chromeos/policy/weekly_time/weekly_time_unittest.cc b/chromeos/policy/weekly_time/weekly_time_unittest.cc index b0282705..6a58dbb 100644 --- a/chromeos/policy/weekly_time/weekly_time_unittest.cc +++ b/chromeos/policy/weekly_time/weekly_time_unittest.cc
@@ -79,10 +79,11 @@ std::unique_ptr<base::DictionaryValue> weekly_time_value = weekly_time.ToValue(); base::DictionaryValue expected_weekly_time; - expected_weekly_time.SetInteger("day_of_week", day_of_week()); - expected_weekly_time.SetInteger("time", minutes() * kMinute.InMilliseconds()); + expected_weekly_time.SetInteger(WeeklyTime::kDayOfWeek, day_of_week()); + expected_weekly_time.SetInteger(WeeklyTime::kTime, + minutes() * kMinute.InMilliseconds()); if (timezone_offset()) { - expected_weekly_time.SetInteger("timezone_offset", + expected_weekly_time.SetInteger(WeeklyTime::kTimezoneOffset, timezone_offset().value()); } EXPECT_EQ(*weekly_time_value, expected_weekly_time); @@ -117,6 +118,50 @@ EXPECT_EQ(result->timezone_offset(), timezone_offset()); } +TEST_P(SingleWeeklyTimeTest, ExtractFromValue_UnspecifiedDay) { + int milliseconds = minutes() * kMinute.InMilliseconds(); + base::DictionaryValue value; + EXPECT_TRUE(value.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[0])); + EXPECT_TRUE(value.SetIntKey(WeeklyTime::kTime, milliseconds)); + auto result = WeeklyTime::ExtractFromValue(&value, timezone_offset()); + ASSERT_FALSE(result); +} + +TEST_P(SingleWeeklyTimeTest, ExtractFromValue_InvalidDay) { + int milliseconds = minutes() * kMinute.InMilliseconds(); + base::DictionaryValue value; + EXPECT_TRUE(value.SetIntKey(WeeklyTime::kDayOfWeek, -1)); + EXPECT_TRUE(value.SetIntKey(WeeklyTime::kTime, milliseconds)); + auto result = WeeklyTime::ExtractFromValue(&value, timezone_offset()); + ASSERT_FALSE(result); + + EXPECT_TRUE(value.SetIntKey(WeeklyTime::kDayOfWeek, 8)); + result = WeeklyTime::ExtractFromValue(&value, timezone_offset()); + ASSERT_FALSE(result); +} + +TEST_P(SingleWeeklyTimeTest, ExtractFromValue_InvalidTime) { + base::DictionaryValue value; + EXPECT_TRUE( + value.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[day_of_week()])); + EXPECT_TRUE(value.SetIntKey(WeeklyTime::kTime, -1)); + auto result = WeeklyTime::ExtractFromValue(&value, timezone_offset()); + ASSERT_FALSE(result); +} + +TEST_P(SingleWeeklyTimeTest, ExtractFromValue_Valid) { + int milliseconds = minutes() * kMinute.InMilliseconds(); + base::DictionaryValue value; + EXPECT_TRUE( + value.SetIntKey(WeeklyTime::kDayOfWeek, kWeekdays[day_of_week()])); + EXPECT_TRUE(value.SetIntKey(WeeklyTime::kTime, milliseconds)); + auto result = WeeklyTime::ExtractFromValue(&value, timezone_offset()); + ASSERT_TRUE(result); + EXPECT_EQ(result->day_of_week(), day_of_week()); + EXPECT_EQ(result->milliseconds(), milliseconds); + EXPECT_EQ(result->timezone_offset(), timezone_offset()); +} + INSTANTIATE_TEST_SUITE_P( TheSmallestCase, SingleWeeklyTimeTest,
diff --git a/chromeos/services/cros_healthd/public/mojom/BUILD.gn b/chromeos/services/cros_healthd/public/mojom/BUILD.gn index 8aa10511..1c5c4f81 100644 --- a/chromeos/services/cros_healthd/public/mojom/BUILD.gn +++ b/chromeos/services/cros_healthd/public/mojom/BUILD.gn
@@ -11,6 +11,7 @@ "cros_healthd_diagnostics.mojom", "cros_healthd_events.mojom", "cros_healthd_probe.mojom", + "nullable_primitives.mojom", ] public_deps = [
diff --git a/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom b/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom index 48b998ba..3418690 100644 --- a/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom +++ b/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom
@@ -10,6 +10,7 @@ module chromeos.cros_healthd.mojom; +import "chromeos/services/cros_healthd/public/mojom/nullable_primitives.mojom"; import "chromeos/services/network_health/public/mojom/network_health.mojom"; // An enumeration of CPU architectures. @@ -60,13 +61,6 @@ string msg; }; -// Optional uint64 field. Since primitives numeric types cannot be optional, -// wrap uint64 in a struct that can be nulled. -struct UInt64Value { - // The value of the uint64. - uint64 value; -}; - // An enumeration of states a process can be in. [Extensible] enum ProcessState { @@ -166,7 +160,7 @@ // Manufacture date converted to yyyy-mm-dd format. string? manufacture_date; // Temperature in 0.1K. Included when the main battery is a Smart Battery. - UInt64Value? temperature; + NullableUint64? temperature; }; // Non-removable block device probe result. Can either be populated with the @@ -236,7 +230,7 @@ uint64 io_time_seconds_since_last_boot; // Time spent discarding since last boot. Discarding is writing to clear // blocks which are no longer in use. Supported on kernels 4.18+. - UInt64Value? discard_time_seconds_since_last_boot; + NullableUint64? discard_time_seconds_since_last_boot; // Device identification. @@ -492,7 +486,7 @@ // The chassis type of the device. The values reported by chassis type are // mapped in // www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.0.0.pdf. - UInt64Value? chassis_type; + NullableUint64? chassis_type; // The product name (model) of the system. string? product_name; // The OS version of the system.
diff --git a/chromeos/services/cros_healthd/public/mojom/nullable_primitives.mojom b/chromeos/services/cros_healthd/public/mojom/nullable_primitives.mojom new file mode 100644 index 0000000..cd20c94e --- /dev/null +++ b/chromeos/services/cros_healthd/public/mojom/nullable_primitives.mojom
@@ -0,0 +1,26 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file contains Mojo structs representing nullable primitives - since Mojo +// doesn't support these natively, when we want a primitive parameter or return +// value to be optional, we need to wrap it in a nullable struct. +// TODO(crbug/657632): Remove this file if Mojo adds support for nullable +// primitives. + +// NOTE: This mojom should be kept in sync with the copy in Chromium's repo in +// src/platform2/diagnostics/mojo/nullable_primitives.mojom. + +module chromeos.cros_healthd.mojom; + +// Optional uint32 field. +struct NullableUint32 { + // The value of the uint32. + uint32 value; +}; + +// Optional uint64 field. +struct NullableUint64 { + // The value of the uint64. + uint64 value; +};
diff --git a/chromeos/ui/base/chromeos_ui_constants.h b/chromeos/ui/base/chromeos_ui_constants.h index be7998f70..4828fd8 100644 --- a/chromeos/ui/base/chromeos_ui_constants.h +++ b/chromeos/ui/base/chromeos_ui_constants.h
@@ -9,6 +9,9 @@ namespace chromeos { +// Radius of the header's top corners when the window is restored. +constexpr int kTopCornerRadiusWhenRestored = 2; + // In the window corners, the resize areas don't actually expand bigger, but the // 16 px at the end of each edge triggers diagonal resizing. constexpr int kResizeAreaCornerSize = 16;
diff --git a/chromeos/ui/base/window_properties.cc b/chromeos/ui/base/window_properties.cc index 073e76d..48b5842 100644 --- a/chromeos/ui/base/window_properties.cc +++ b/chromeos/ui/base/window_properties.cc
@@ -4,6 +4,7 @@ #include "chromeos/ui/base/window_properties.h" +#include "chromeos/ui/base/chromeos_ui_constants.h" #include "chromeos/ui/base/window_pin_type.h" #include "chromeos/ui/base/window_state_type.h" #include "ui/base/class_property.h" @@ -14,6 +15,11 @@ namespace chromeos { +DEFINE_UI_CLASS_PROPERTY_KEY(SkColor, kFrameActiveColorKey, kDefaultFrameColor) +DEFINE_UI_CLASS_PROPERTY_KEY(SkColor, + kFrameInactiveColorKey, + kDefaultFrameColor) + DEFINE_UI_CLASS_PROPERTY_KEY(bool, kFrameRestoreLookKey, false) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kHideShelfWhenFullscreenKey, true)
diff --git a/chromeos/ui/base/window_properties.h b/chromeos/ui/base/window_properties.h index d44a19a..0c65c0da 100644 --- a/chromeos/ui/base/window_properties.h +++ b/chromeos/ui/base/window_properties.h
@@ -6,6 +6,7 @@ #define CHROMEOS_UI_BASE_WINDOW_PROPERTIES_H_ #include "base/component_export.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/base/class_property.h" namespace gfx { @@ -21,6 +22,14 @@ // Alphabetical sort. +// A property key to store the active color on the window frame. +COMPONENT_EXPORT(CHROMEOS_UI_BASE) +extern const ui::ClassProperty<SkColor>* const kFrameActiveColorKey; + +// A property key to store the inactive color on the window frame. +COMPONENT_EXPORT(CHROMEOS_UI_BASE) +extern const ui::ClassProperty<SkColor>* const kFrameInactiveColorKey; + // A property key that is set to true when the window frame should look like it // is in restored state, but actually isn't. Set while dragging a maximized // window.
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index bfddf385..6f135fb 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -27,6 +27,8 @@ "enterprise/arc_data_snapshotd_bridge.h", "enterprise/arc_data_snapshotd_manager.cc", "enterprise/arc_data_snapshotd_manager.h", + "enterprise/snapshot_hours_policy_service.cc", + "enterprise/snapshot_hours_policy_service.h", "ime/arc_ime_bridge.h", "ime/arc_ime_bridge_impl.cc", "ime/arc_ime_bridge_impl.h", @@ -103,6 +105,8 @@ "//ash/keyboard/ui", "//ash/public/cpp", "//base", + "//base/util/timer", + "//chromeos", "//chromeos/audio", "//chromeos/constants", "//chromeos/dbus", @@ -386,6 +390,7 @@ "clipboard/arc_clipboard_bridge_unittest.cc", "enterprise/arc_data_snapshotd_bridge_unittest.cc", "enterprise/arc_data_snapshotd_manager_unittest.cc", + "enterprise/snapshot_hours_policy_service_unittest.cc", "ime/arc_ime_service_unittest.cc", "ime/key_event_result_receiver_unittest.cc", "intent_helper/activity_icon_loader_unittest.cc", @@ -417,6 +422,8 @@ "//ash/public/cpp", "//base", "//base/test:test_support", + "//base/util/timer", + "//chromeos", "//chromeos/constants", "//chromeos/cryptohome:test_support", "//chromeos/dbus:test_support",
diff --git a/components/arc/DEPS b/components/arc/DEPS index 3dbe0a7df..fb99258 100644 --- a/components/arc/DEPS +++ b/components/arc/DEPS
@@ -4,6 +4,7 @@ "+chromeos/cryptohome", "+chromeos/dbus", "+chromeos/memory", + "+chromeos/policy", "+chromeos/system", "+components/guest_os", "+components/account_id",
diff --git a/components/arc/arc_prefs.cc b/components/arc/arc_prefs.cc index 6d624f80..3dd63ff 100644 --- a/components/arc/arc_prefs.cc +++ b/components/arc/arc_prefs.cc
@@ -103,9 +103,6 @@ // the user directory (i.e., the user finished required migration.) const char kArcCompatibleFilesystemChosen[] = "arc.compatible_filesystem.chosen"; -// Integer pref indicating the ecryptfs to ext4 migration strategy. One of -// options: forbidden = 0, migrate = 1, wipe = 2 or minimal migrate = 4. -const char kEcryptfsMigrationStrategy[] = "ecryptfs_migration_strategy"; // Preferences for storing engagement time data, as per // GuestOsEngagementMetrics. const char kEngagementPrefsPrefix[] = "arc.metrics"; @@ -160,9 +157,6 @@ registry->RegisterBooleanPref(kArcBackupRestoreEnabled, false); registry->RegisterBooleanPref(kArcLocationServiceEnabled, false); - // This is used to decide whether migration from ecryptfs to ext4 is allowed. - registry->RegisterIntegerPref(prefs::kEcryptfsMigrationStrategy, 0); - registry->RegisterIntegerPref( kArcSupervisionTransition, static_cast<int>(ArcSupervisionTransition::NO_TRANSITION));
diff --git a/components/arc/enterprise/snapshot_hours_policy_service.cc b/components/arc/enterprise/snapshot_hours_policy_service.cc new file mode 100644 index 0000000..12def9f --- /dev/null +++ b/components/arc/enterprise/snapshot_hours_policy_service.cc
@@ -0,0 +1,186 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/arc/enterprise/snapshot_hours_policy_service.h" + +#include <utility> + +#include "base/bind.h" +#include "base/callback_helpers.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/time/default_clock.h" +#include "base/time/tick_clock.h" +#include "base/values.h" +#include "chromeos/policy/weekly_time/time_utils.h" +#include "components/arc/arc_prefs.h" +#include "components/prefs/pref_service.h" +#include "components/user_manager/user_manager.h" + +namespace arc { +namespace data_snapshotd { + +SnapshotHoursPolicyService::SnapshotHoursPolicyService(PrefService* local_state) + : local_state_(local_state) { + DCHECK(local_state_); + pref_change_registrar_.Init(local_state_); + pref_change_registrar_.Add( + prefs::kArcSnapshotHours, + base::BindRepeating(&SnapshotHoursPolicyService::UpdatePolicy, + weak_ptr_factory_.GetWeakPtr())); + UpdatePolicy(); +} + +SnapshotHoursPolicyService::~SnapshotHoursPolicyService() = default; + +void SnapshotHoursPolicyService::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void SnapshotHoursPolicyService::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void SnapshotHoursPolicyService::StartObservingPrimaryProfilePrefs( + PrefService* profile_prefs) { + if (!user_manager::UserManager::Get() || + !user_manager::UserManager::Get()->IsLoggedInAsPublicAccount()) { + // Do not care about ArcEnabled policy for other than MGS. + return; + } + profile_prefs_ = profile_prefs; + profile_pref_change_registrar_.Init(profile_prefs_); + profile_pref_change_registrar_.Add( + prefs::kArcEnabled, + base::BindRepeating(&SnapshotHoursPolicyService::UpdatePolicy, + weak_ptr_factory_.GetWeakPtr())); + UpdatePolicy(); +} + +void SnapshotHoursPolicyService::StopObservingPrimaryProfilePrefs() { + if (!profile_prefs_) + return; + profile_pref_change_registrar_.RemoveAll(); + profile_prefs_ = nullptr; + UpdatePolicy(); +} + +void SnapshotHoursPolicyService::UpdatePolicy() { + intervals_.clear(); + base::ScopedClosureRunner snapshot_disabler( + base::BindOnce(&SnapshotHoursPolicyService::DisableSnapshots, + weak_ptr_factory_.GetWeakPtr())); + if (!IsArcEnabled()) + return; + + const auto* dict = local_state_->GetDictionary(prefs::kArcSnapshotHours); + if (!dict) + return; + + const auto* timezone = dict->FindStringKey("timezone"); + if (!timezone) + return; + + int offset; + if (!policy::weekly_time_utils::GetOffsetFromTimezoneToGmt( + *timezone, base::DefaultClock::GetInstance(), &offset)) { + return; + } + + const auto* intervals = dict->FindListKey("intervals"); + if (!intervals) + return; + + for (const auto& entry : intervals->GetList()) { + if (!entry.is_dict()) + continue; + auto interval = + policy::WeeklyTimeInterval::ExtractFromValue(&entry, -offset); + if (interval) + intervals_.push_back(*interval); + } + intervals_ = policy::weekly_time_utils::ConvertIntervalsToGmt(intervals_); + if (intervals_.empty()) + return; + + ignore_result(snapshot_disabler.Release()); + EnableSnapshots(); +} + +void SnapshotHoursPolicyService::DisableSnapshots() { + if (!is_snapshot_enabled_) + return; + + is_snapshot_enabled_ = false; + StopTimer(); + SetEndTime(base::Time()); + NotifySnapshotsDisabled(); +} + +void SnapshotHoursPolicyService::EnableSnapshots() { + if (is_snapshot_enabled_) + return; + is_snapshot_enabled_ = true; + + UpdateTimer(); + NotifySnapshotsEnabled(); +} + +void SnapshotHoursPolicyService::UpdateTimer() { + auto current_time = policy::WeeklyTime::GetCurrentGmtWeeklyTime( + base::DefaultClock::GetInstance()); + for (const auto& interval : intervals_) { + if (interval.Contains(current_time)) { + auto remaining_timer_duration = + current_time.GetDurationTo(interval.end()); + SetEndTime(base::Time::Now() + remaining_timer_duration); + StartTimer(remaining_timer_duration); + return; + } + } + StartTimer(policy::weekly_time_utils::GetDeltaTillNextTimeInterval( + current_time, intervals_)); + SetEndTime(base::Time()); +} + +void SnapshotHoursPolicyService::StartTimer(base::TimeDelta delay) { + DCHECK_GT(delay, base::TimeDelta()); + timer_.Start(FROM_HERE, base::DefaultClock::GetInstance()->Now() + delay, + base::BindOnce(&SnapshotHoursPolicyService::UpdateTimer, + weak_ptr_factory_.GetWeakPtr())); +} + +void SnapshotHoursPolicyService::StopTimer() { + timer_.Stop(); +} + +void SnapshotHoursPolicyService::SetEndTime(base::Time end_time) { + if (snapshot_update_end_time_ == end_time) + return; + snapshot_update_end_time_ = end_time; + NotifySnapshotUpdateEndTimeChanged(); +} + +void SnapshotHoursPolicyService::NotifySnapshotsDisabled() { + for (auto& observer : observers_) + observer.OnSnapshotsDisabled(); +} + +void SnapshotHoursPolicyService::NotifySnapshotsEnabled() { + for (auto& observer : observers_) + observer.OnSnapshotsEnabled(); +} + +void SnapshotHoursPolicyService::NotifySnapshotUpdateEndTimeChanged() { + for (auto& observer : observers_) + observer.OnSnapshotUpdateEndTimeChanged(); +} + +bool SnapshotHoursPolicyService::IsArcEnabled() const { + // Assume ARC is enabled if there is no profile prefs. + return !profile_prefs_ || profile_prefs_->GetBoolean(prefs::kArcEnabled); +} + +} // namespace data_snapshotd +} // namespace arc
diff --git a/components/arc/enterprise/snapshot_hours_policy_service.h b/components/arc/enterprise/snapshot_hours_policy_service.h new file mode 100644 index 0000000..640aa4e --- /dev/null +++ b/components/arc/enterprise/snapshot_hours_policy_service.h
@@ -0,0 +1,135 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_ARC_ENTERPRISE_SNAPSHOT_HOURS_POLICY_SERVICE_H_ +#define COMPONENTS_ARC_ENTERPRISE_SNAPSHOT_HOURS_POLICY_SERVICE_H_ + +#include <vector> + +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "base/observer_list_types.h" +#include "base/time/time.h" +#include "base/util/timer/wall_clock_timer.h" +#include "chromeos/policy/weekly_time/weekly_time_interval.h" +#include "components/prefs/pref_change_registrar.h" + +class PrefService; + +namespace arc { +namespace data_snapshotd { + +// This class handles "DeviceArcDataSnapshotHours" policy, enables/disables ARC +// data snapshot feature, handles ARC data snapshot update intervals. +// +// ArcDataSnapshotdManager is an owner of this object. +class SnapshotHoursPolicyService { + public: + // Observer interface. + class Observer : public base::CheckedObserver { + public: + // Called once ARC data snapshot feature gets disabled by policy. + virtual void OnSnapshotsDisabled() {} + // Called once ARC data snapshot feature gets enabled by policy. + virtual void OnSnapshotsEnabled() {} + // Called once the interval for allowed ARC data snapshot update has + // started/finished. + // The observer can get an end time for started interval via + // snapshot_update_end_time(). + virtual void OnSnapshotUpdateEndTimeChanged() {} + }; + + explicit SnapshotHoursPolicyService(PrefService* local_state); + SnapshotHoursPolicyService(const SnapshotHoursPolicyService&) = delete; + SnapshotHoursPolicyService& operator=(const SnapshotHoursPolicyService&) = + delete; + ~SnapshotHoursPolicyService(); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + // Starts observing primary profile prefs only for MGS. + void StartObservingPrimaryProfilePrefs(PrefService* profile_prefs); + // Stops observing primary profile prefs. + void StopObservingPrimaryProfilePrefs(); + + // Returns the end time of the current interval when ARC data snapshot update + // is possible. + // Returns null outside of the interval. + base::Time snapshot_update_end_time() const { + return snapshot_update_end_time_; + } + + bool is_snapshot_enabled() const { return is_snapshot_enabled_; } + + const std::vector<policy::WeeklyTimeInterval>& get_intervals_for_testing() + const { + return intervals_; + } + const util::WallClockTimer* get_timer_for_testing() const { return &timer_; } + + private: + // Processes the policy update: either ArcEnabled and + // DeviceArcDataSnapshotHours. + void UpdatePolicy(); + + // Disables ARC data snapshot feature and notifies observers if necessary. + void DisableSnapshots(); + // Enables ARC data snaoshot feature and notifies observers if necessary. + void EnableSnapshots(); + + // Updates ARC data snapshot update timer according to the policy. + void UpdateTimer(); + + // Starts timer with |delay|. + void StartTimer(base::TimeDelta delay); + // Stops timer. + void StopTimer(); + // Changes |snapshot_update_end_time_| and notifies observers if necessary. + void SetEndTime(base::Time end_time); + + // Notifies observers about relevant events. + void NotifySnapshotsDisabled(); + void NotifySnapshotsEnabled(); + void NotifySnapshotUpdateEndTimeChanged(); + + // Returns false if ARC is disabled for a logged-in MGS, otherwise returns + // true. + bool IsArcEnabled() const; + + // The feature is disabled when either kArcDataSnapshotHours policy is not set + // or ARC is disabled by policy for MGS. + bool is_snapshot_enabled_ = false; + + // Not owned. + PrefService* const local_state_ = nullptr; + + // Owned by primary profile. + PrefService* profile_prefs_ = nullptr; + + // Registrar for pref changes in local_state_. + PrefChangeRegistrar pref_change_registrar_; + // Registrar for pref changes in profile_prefs_. + PrefChangeRegistrar profile_pref_change_registrar_; + + // The end time of the current interval if ARC data snapshot update is + // possible. The value is null outside of all intervals. + base::Time snapshot_update_end_time_; + + base::ObserverList<Observer> observers_; + + // Current "ArcDataSnapshotHours" time intervals. + std::vector<policy::WeeklyTimeInterval> intervals_; + + // Timer for updating ARC data snapshot at the begin of next interval or at + // the end of current interval. + util::WallClockTimer timer_; + + base::WeakPtrFactory<SnapshotHoursPolicyService> weak_ptr_factory_{this}; +}; + +} // namespace data_snapshotd +} // namespace arc + +#endif // COMPONENTS_ARC_ENTERPRISE_SNAPSHOT_HOURS_POLICY_SERVICE_H_
diff --git a/components/arc/enterprise/snapshot_hours_policy_service_unittest.cc b/components/arc/enterprise/snapshot_hours_policy_service_unittest.cc new file mode 100644 index 0000000..a4ec454 --- /dev/null +++ b/components/arc/enterprise/snapshot_hours_policy_service_unittest.cc
@@ -0,0 +1,350 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/arc/enterprise/snapshot_hours_policy_service.h" + +#include <memory> +#include <string> + +#include "base/bind_helpers.h" +#include "base/json/json_reader.h" +#include "base/optional.h" +#include "base/run_loop.h" +#include "base/test/task_environment.h" +#include "base/values.h" +#include "chromeos/policy/weekly_time/weekly_time_interval.h" +#include "components/arc/arc_prefs.h" +#include "components/prefs/testing_pref_service.h" +#include "components/user_manager/fake_user_manager.h" +#include "components/user_manager/scoped_user_manager.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace arc { +namespace data_snapshotd { + +namespace { + +constexpr char kPublicAccountEmail[] = "public-session-account@localhost"; + +// DeviceArcDataSnapshotHours policy with one correct interval. +constexpr char kJsonPolicy[] = + "{" + "\"intervals\": [" + "{" + "\"start\": {" + "\"day_of_week\": 1," + "\"time\": 1284000" + "}," + "\"end\": {" + "\"day_of_week\": 1," + "\"time\": 21720000" + "}" + "}" + "]," + "\"timezone\": \"GMT\"" + "}"; + +// DeviceArcDataSnapshotHours incorrect policy with missing timezone. +constexpr char kJsonPolicyNoTimezone[] = + "{" + "\"intervals\": [" + "{" + "\"start\": {" + "\"day_of_week\": 1," + "\"time\": 1284000" + "}," + "\"end\": {" + "\"day_of_week\": 1," + "\"time\": 21720000" + "}" + "}" + "]" + "}"; + +// DeviceArcDataSnapshotHours incorrect policy with incorrect intervals. +constexpr char kJsonPolicyIncorrectIntervals[] = + "{" + "\"intervals\": [" + "{" + "\"start\": {" + "\"day_of_week\": 1," + "\"time\": 1284000" + "}," + "\"end\": {" + "\"day_of_week\": 0," + "\"time\": 21720000" + "}" + "}" + "]," + "\"timezone\": \"GMT\"" + "}"; + +// DeviceArcDataSnapshotHours incorrect policy with missing intervals. +constexpr char kJsonPolicyNoIntervals[] = + "{" + "\"timezone\": \"GMT\"" + "}"; + +// DeviceArcDataSnapshotHours incorrect policy with empty intervals. +constexpr char kJsonPolicyEmptyIntervals[] = + "{" + "\"intervals\": [" + "]," + "\"timezone\": \"GMT\"" + "}"; + +// DeviceArcDataSnapshotHours incorrect policy with empty timezone. +constexpr char kJsonPolicyWrongOffset[] = + "{" + "\"intervals\": [" + "{" + "\"start\": {" + "\"day_of_week\": 1," + "\"time\": 1284000" + "}," + "\"end\": {" + "\"day_of_week\": 1," + "\"time\": 21720000" + "}" + "}" + "]," + "\"timezone\": \"\"" + "}"; + +class FakeObserver : public SnapshotHoursPolicyService::Observer { + public: + FakeObserver() = default; + FakeObserver(const FakeObserver&) = delete; + FakeObserver& operator=(const FakeObserver&) = delete; + ~FakeObserver() override = default; + + void OnSnapshotsDisabled() override { disabled_calls_num_++; } + + void OnSnapshotsEnabled() override { enabled_calls_num_++; } + + void OnSnapshotUpdateEndTimeChanged() override { changed_calls_num_++; } + + int disabled_calls_num() const { return disabled_calls_num_; } + int enabled_calls_num() const { return enabled_calls_num_; } + int changed_calls_num() const { return changed_calls_num_; } + + private: + int disabled_calls_num_ = 0; + int enabled_calls_num_ = 0; + int changed_calls_num_ = 0; +}; + +} // namespace + +// Tests SnapshotHoursPolicyService class instance. +class SnapshotHoursPolicyServiceTest + : public testing::TestWithParam<std::string> { + protected: + SnapshotHoursPolicyServiceTest() = default; + + void SetUp() override { + arc::prefs::RegisterLocalStatePrefs(local_state_.registry()); + policy_service_ = + std::make_unique<SnapshotHoursPolicyService>(local_state()); + observer_ = std::make_unique<FakeObserver>(); + policy_service()->AddObserver(observer_.get()); + + fake_user_manager_ = new user_manager::FakeUserManager(); + scoped_user_manager_ = std::make_unique<user_manager::ScopedUserManager>( + base::WrapUnique(fake_user_manager_)); + } + + void TearDown() override { + policy_service()->RemoveObserver(observer_.get()); + policy_service_.reset(); + local_state_.ClearPref(prefs::kArcSnapshotHours); + } + + const std::string& policy() const { return GetParam(); } + + // Ensure the feature disabled. + void EnsureSnapshotDisabled(int disabled_calls_num = 0) { + EXPECT_FALSE(policy_service()->is_snapshot_enabled()); + EXPECT_FALSE(policy_service()->get_timer_for_testing()->IsRunning()); + EXPECT_TRUE(policy_service()->snapshot_update_end_time().is_null()); + EXPECT_EQ(observer_->disabled_calls_num(), disabled_calls_num); + } + + // Ensure the feature enabled. + void EnsureSnapshotEnabled(int enabled_calls_num = 1) { + EXPECT_TRUE(policy_service()->is_snapshot_enabled()); + EXPECT_TRUE(policy_service()->get_timer_for_testing()->IsRunning()); + + EXPECT_EQ(policy_service()->get_intervals_for_testing().size(), 1u); + EXPECT_EQ(observer_->enabled_calls_num(), enabled_calls_num); + } + + // Enable feature and check. + void EnableSnapshot(int enabled_calls_num = 1) { + base::Optional<base::Value> policy = base::JSONReader::Read(kJsonPolicy); + EXPECT_TRUE(policy.has_value()); + local_state()->Set(arc::prefs::kArcSnapshotHours, policy.value()); + EnsureSnapshotEnabled(enabled_calls_num); + } + + // Fire the next timer. + void FastForwardToTimer() { + if (policy_service()->snapshot_update_end_time().is_null()) { + task_environment_.FastForwardBy( + policy_service()->get_timer_for_testing()->desired_run_time() - + base::Time::Now()); + task_environment_.RunUntilIdle(); + } + EXPECT_FALSE(policy_service()->snapshot_update_end_time().is_null()); + } + + void LoginAsPublicSession() { + auto account_id = AccountId::FromUserEmail(kPublicAccountEmail); + user_manager()->AddPublicAccountUser(account_id); + user_manager()->UserLoggedIn(account_id, account_id.GetUserEmail(), false, + false); + } + + SnapshotHoursPolicyService* policy_service() { return policy_service_.get(); } + TestingPrefServiceSimple* local_state() { return &local_state_; } + FakeObserver* observer() { return observer_.get(); } + user_manager::FakeUserManager* user_manager() { return fake_user_manager_; } + + base::test::TaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + + private: + std::unique_ptr<FakeObserver> observer_; + std::unique_ptr<SnapshotHoursPolicyService> policy_service_; + TestingPrefServiceSimple local_state_; + user_manager::FakeUserManager* fake_user_manager_; + std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_; +}; + +// Test that the feature is disabled by default. +TEST_F(SnapshotHoursPolicyServiceTest, Disabled) { + EnsureSnapshotDisabled(); +} + +TEST_F(SnapshotHoursPolicyServiceTest, OneIntervalEnabled) { + EnableSnapshot(); +} + +TEST_F(SnapshotHoursPolicyServiceTest, DoubleDisable) { + EnableSnapshot(); + + { + base::Optional<base::Value> policy_value = + base::JSONReader::Read(kJsonPolicyEmptyIntervals); + EXPECT_TRUE(policy_value.has_value()); + local_state()->Set(arc::prefs::kArcSnapshotHours, policy_value.value()); + + EnsureSnapshotDisabled(1 /* disabled_calls_num */); + } + + { + // User a different JSON to ensure the policy value is updated. + base::Optional<base::Value> policy_value = + base::JSONReader::Read(kJsonPolicyNoIntervals); + EXPECT_TRUE(policy_value.has_value()); + local_state()->Set(arc::prefs::kArcSnapshotHours, policy_value.value()); + + // Do not notify the second time. + EnsureSnapshotDisabled(1 /* disabled_calls_num */); + } +} + +TEST_F(SnapshotHoursPolicyServiceTest, DoubleEnable) { + EnableSnapshot(); + // Do not notify the second time. + EnableSnapshot(); +} + +// Test that once the feature enabled, the time is outside interval. +TEST_F(SnapshotHoursPolicyServiceTest, OutsideInterval) { + EnableSnapshot(); + EXPECT_TRUE(policy_service()->snapshot_update_end_time().is_null()); + EXPECT_EQ(observer()->changed_calls_num(), 0); + + FastForwardToTimer(); + EXPECT_EQ(observer()->changed_calls_num(), 1); + EXPECT_FALSE(policy_service()->snapshot_update_end_time().is_null()); +} + +// Test that once the feature enabled, the time is outside interval. +TEST_F(SnapshotHoursPolicyServiceTest, InsideInterval) { + EnableSnapshot(); + EXPECT_TRUE(policy_service()->snapshot_update_end_time().is_null()); + EXPECT_EQ(observer()->changed_calls_num(), 0); + + FastForwardToTimer(); + EXPECT_EQ(observer()->changed_calls_num(), 1); + EXPECT_FALSE(policy_service()->snapshot_update_end_time().is_null()); + + // Disable snapshots. + { + base::Optional<base::Value> policy_value = + base::JSONReader::Read(kJsonPolicyNoIntervals); + EXPECT_TRUE(policy_value.has_value()); + local_state()->Set(arc::prefs::kArcSnapshotHours, policy_value.value()); + + EnsureSnapshotDisabled(1 /* disabled_calls_num */); + EXPECT_EQ(observer()->changed_calls_num(), 2); + } + + EnableSnapshot(2 /* enabled_calls_num */); + EXPECT_EQ(observer()->changed_calls_num(), 3); + EXPECT_FALSE(policy_service()->snapshot_update_end_time().is_null()); +} + +// Test that if ARC is disabled by user policy (not for public session +// account), it does not disable the feature. +TEST_F(SnapshotHoursPolicyServiceTest, DisableByUserPolicyForUser) { + EnableSnapshot(); + + TestingPrefServiceSimple profile_prefs; + arc::prefs::RegisterProfilePrefs(profile_prefs.registry()); + profile_prefs.SetBoolean(arc::prefs::kArcEnabled, false); + policy_service()->StartObservingPrimaryProfilePrefs(&profile_prefs); + EnsureSnapshotEnabled(); + policy_service()->StopObservingPrimaryProfilePrefs(); +} + +// Test that if ARC is disabled for public session account, it disables +// the feature. +TEST_F(SnapshotHoursPolicyServiceTest, DisableByUserPolicyForMGS) { + LoginAsPublicSession(); + EnableSnapshot(); + + TestingPrefServiceSimple profile_prefs; + arc::prefs::RegisterProfilePrefs(profile_prefs.registry()); + profile_prefs.SetBoolean(arc::prefs::kArcEnabled, false); + policy_service()->StartObservingPrimaryProfilePrefs(&profile_prefs); + EnsureSnapshotDisabled(1 /* disabled_calls_num */); + policy_service()->StopObservingPrimaryProfilePrefs(); + EnsureSnapshotEnabled(2 /* enabled_calls_num */); +} + +TEST_P(SnapshotHoursPolicyServiceTest, DisabledByPolicy) { + EnableSnapshot(); + + base::Optional<base::Value> policy_value = base::JSONReader::Read(policy()); + EXPECT_TRUE(policy_value.has_value()); + local_state()->Set(arc::prefs::kArcSnapshotHours, policy_value.value()); + + EnsureSnapshotDisabled(1 /* disabled_calls_num */); +} + +INSTANTIATE_TEST_SUITE_P( + /* no prefix */, + SnapshotHoursPolicyServiceTest, + testing::Values(kJsonPolicyNoTimezone, + kJsonPolicyIncorrectIntervals, + kJsonPolicyNoIntervals, + kJsonPolicyEmptyIntervals, + kJsonPolicyWrongOffset)); + +} // namespace data_snapshotd +} // namespace arc
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index c1cf47b..4c81821 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -2079,9 +2079,21 @@ base::FeatureList::IsEnabled( features::kAutofillSectionUponRedundantNameInfo); + // Creates a unique name for the section that starts with |field|. + // TODO(crbug/896689): Cleanup once experiment is launched. + auto get_section_name = [](const AutofillField& field) { + if (base::FeatureList::IsEnabled( + features::kAutofillNameSectionsWithRendererIds)) { + return base::StrCat( + {field.name, base::ASCIIToUTF16("_"), + base::NumberToString16(field.unique_renderer_id.value())}); + } else { + return field.unique_name(); + } + }; + if (!has_author_specified_sections || is_enabled_autofill_new_sectioning) { - // Name sections after the first field in the section. - base::string16 current_section = fields_.front()->unique_name(); + base::string16 current_section = get_section_name(*fields_.front()); // Keep track of the types we've seen in this section. std::set<ServerFieldType> seen_types; @@ -2203,7 +2215,7 @@ } // The end of a section, so start a new section. - current_section = field->unique_name(); + current_section = get_section_name(*field); if (is_enabled_autofill_new_sectioning) { // The section described in the autocomplete section attribute
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h index d8f8ad7..58a8a8d48 100644 --- a/components/autofill/core/browser/form_structure.h +++ b/components/autofill/core/browser/form_structure.h
@@ -398,11 +398,12 @@ private: friend class AutofillMergeTest; friend class FormStructureTestImpl; + friend class ParameterizedFormStructureTest; FRIEND_TEST_ALL_PREFIXES(AutofillDownloadTest, QueryAndUploadTest); FRIEND_TEST_ALL_PREFIXES(FormStructureTestImpl, FindLongestCommonPrefix); FRIEND_TEST_ALL_PREFIXES(FormStructureTestImpl, FindLongestCommonAffixLength); FRIEND_TEST_ALL_PREFIXES(FormStructureTestImpl, IsValidParseableName); - FRIEND_TEST_ALL_PREFIXES(FormStructureTestImpl, + FRIEND_TEST_ALL_PREFIXES(ParameterizedFormStructureTest, RationalizePhoneNumber_RunsOncePerSection); class SectionedFieldsIndexes {
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc index b404c39..99c2e6a9 100644 --- a/components/autofill/core/browser/form_structure_unittest.cc +++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -120,6 +120,10 @@ {}); } + FieldRendererId MakeFieldRendererId() { + return FieldRendererId(++id_counter_); + } + protected: TestPatternProvider test_pattern_provider_; @@ -132,6 +136,7 @@ field_trial_->group(); } + uint32_t id_counter_ = 10; base::test::ScopedFeatureList scoped_feature_list_; scoped_refptr<base::FieldTrial> field_trial_; }; @@ -225,6 +230,7 @@ field.label = ASCIIToUTF16("username"); field.name = ASCIIToUTF16("username"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // With min required fields enabled. @@ -235,6 +241,7 @@ field.label = ASCIIToUTF16("password"); field.name = ASCIIToUTF16("password"); field.form_control_type = "password"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); EXPECT_FALSE(FormIsAutofillable(form)); @@ -244,6 +251,7 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullname"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); EXPECT_FALSE(FormIsAutofillable(form)); @@ -253,6 +261,7 @@ field.label = ASCIIToUTF16("Address Line 1"); field.name = ASCIIToUTF16("address1"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); EXPECT_FALSE(FormIsAutofillable(form)); @@ -261,6 +270,7 @@ field.label = ASCIIToUTF16("Email"); field.name = ASCIIToUTF16("email"); field.form_control_type = "email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); EXPECT_TRUE(FormIsAutofillable(form)); @@ -286,6 +296,7 @@ FormFieldData::CheckStatus::kCheckableButUnchecked; checkable_field.name = ASCIIToUTF16("radiobtn"); checkable_field.form_control_type = "radio"; + checkable_field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(checkable_field); // A form with a single checkable field isn't interesting. @@ -294,6 +305,7 @@ // Add a second checkable field. checkable_field.name = ASCIIToUTF16("checkbox"); checkable_field.form_control_type = "checkbox"; + checkable_field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(checkable_field); // A form with a only checkable fields isn't interesting. @@ -304,6 +316,7 @@ field.label = ASCIIToUTF16("username"); field.name = ASCIIToUTF16("username"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Single text field forms shouldn't be parsed if all of the minimums are @@ -314,11 +327,13 @@ field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("firstname"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastname"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Three text field forms should always be parsed. @@ -339,16 +354,19 @@ field.label = ASCIIToUTF16("Email"); field.name = ASCIIToUTF16("email"); field.form_control_type = "email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state"); field.form_control_type = "select-one"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); field.form_control_type = "select-one"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); EXPECT_TRUE(FormShouldBeParsed(form)) << "text + selects"; @@ -362,6 +380,7 @@ field.label = ASCIIToUTF16("Password"); field.name = ASCIIToUTF16("pw"); field.form_control_type = "password"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); EXPECT_TRUE(FormShouldBeParsed(form)) << "password"; @@ -369,6 +388,7 @@ field.label = ASCIIToUTF16("New password"); field.name = ASCIIToUTF16("new_pw"); field.form_control_type = "password"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); EXPECT_TRUE(FormShouldBeParsed(form)) << "new password"; } @@ -382,18 +402,21 @@ field.name = ASCIIToUTF16("name"); field.form_control_type = "text"; field.autocomplete_attribute = "name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Email"); field.name = ASCIIToUTF16("email"); field.form_control_type = "text"; field.autocomplete_attribute = "email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.form_control_type = "text"; field.autocomplete_attribute = "address-line1"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Baseline, HTTP should work. @@ -463,12 +486,14 @@ field.name = ASCIIToUTF16("name"); field.form_control_type = "name"; field.autocomplete_attribute = "name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("Address"); field.form_control_type = "select-one"; field.autocomplete_attribute = ""; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1056,11 +1081,15 @@ FormFieldData field; field.form_control_type = "text"; + field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("firstname"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastname"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); EXPECT_FALSE(FormShouldRunHeuristics(form)); @@ -1096,11 +1125,13 @@ field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("firstname"); field.autocomplete_attribute = "given-name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastname"); field.autocomplete_attribute = ""; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); EXPECT_FALSE(FormShouldRunHeuristics(form)); @@ -1138,20 +1169,24 @@ field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("firstname"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastname"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Email"); field.name = ASCIIToUTF16("email"); field.autocomplete_attribute = "username"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Password"); field.name = ASCIIToUTF16("Password"); field.form_control_type = "password"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -1173,28 +1208,37 @@ // Some fields will have no section specified. These fall into the default // section. field.autocomplete_attribute = "email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // We allow arbitrary section names. field.autocomplete_attribute = "section-foo email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // "shipping" and "billing" are special section tokens that don't require the // "section-" prefix. field.autocomplete_attribute = "shipping email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.autocomplete_attribute = "billing email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // "shipping" and "billing" can be combined with other section names. field.autocomplete_attribute = "section-foo shipping email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.autocomplete_attribute = "section-foo billing email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // We don't do anything clever to try to coalesce sections; it's up to site // authors to avoid typos. field.autocomplete_attribute = "section--foo email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // "shipping email" and "section--shipping" email should be parsed as @@ -1202,10 +1246,12 @@ // implement implicit section names from attributes like "shipping email"; see // the implementation for more details. field.autocomplete_attribute = "section--shipping email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Credit card fields are implicitly in a separate section from other fields. field.autocomplete_attribute = "section-foo cc-number"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -1238,20 +1284,29 @@ // Some fields will have no section specified. These fall into the default // section. field.autocomplete_attribute = "email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Specifying "section-" is equivalent to not specifying a section. field.autocomplete_attribute = "section- email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Invalid tokens should prevent us from setting a section name. field.autocomplete_attribute = "garbage section-foo email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.autocomplete_attribute = "garbage section-bar email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.autocomplete_attribute = "garbage shipping email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.autocomplete_attribute = "garbage billing email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -1281,8 +1336,11 @@ field.form_control_type = "text"; field.autocomplete_attribute = "section-foo email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.autocomplete_attribute = "section-foo address-line1"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -1313,15 +1371,22 @@ field.name = ASCIIToUTF16("one"); field.autocomplete_attribute = "address-line1"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.name = base::string16(); field.autocomplete_attribute = "section-foo email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.name = base::string16(); field.autocomplete_attribute = "name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.name = ASCIIToUTF16("two"); field.autocomplete_attribute = "address-line1"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -1349,43 +1414,53 @@ field.label = ASCIIToUTF16("Your First Name:"); field.name = ASCIIToUTF16("bill.first"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Your Last Name:"); field.name = ASCIIToUTF16("bill.last"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Street Address Line 1:"); field.name = ASCIIToUTF16("bill.street1"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Street Address Line 2:"); field.name = ASCIIToUTF16("bill.street2"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("bill.city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State (U.S.):"); field.name = ASCIIToUTF16("bill.state"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Zip/Postal Code:"); field.name = ASCIIToUTF16("BillTo.PostalCode"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country:"); field.name = ASCIIToUTF16("bill.country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Phone Number:"); field.name = ASCIIToUTF16("BillTo.Phone"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = base::string16(); field.name = ASCIIToUTF16("Submit"); field.form_control_type = "submit"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1427,32 +1502,39 @@ field.label = ASCIIToUTF16("E-mail address"); field.name = ASCIIToUTF16("email"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Full name"); field.name = ASCIIToUTF16("name"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Company"); field.name = ASCIIToUTF16("company"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Zip Code"); field.name = ASCIIToUTF16("Home.PostalCode"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = base::string16(); field.name = ASCIIToUTF16("Submit"); field.value = ASCIIToUTF16("continue"); field.form_control_type = "submit"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1490,35 +1572,43 @@ field.label = ASCIIToUTF16("First Name"); field.name = base::string16(); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last Name"); field.name = base::string16(); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Email"); field.name = base::string16(); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Phone"); field.name = base::string16(); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = base::string16(); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = base::string16(); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Zip code"); field.name = base::string16(); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = base::string16(); field.name = ASCIIToUTF16("Submit"); field.form_control_type = "submit"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1556,27 +1646,33 @@ field.label = ASCIIToUTF16("Name on Card"); field.name = ASCIIToUTF16("name_on_card"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Card Number"); field.name = ASCIIToUTF16("card_number"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Exp Month"); field.name = ASCIIToUTF16("ccmonth"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Exp Year"); field.name = ASCIIToUTF16("ccyear"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Verification"); field.name = ASCIIToUTF16("verification"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = base::string16(); field.name = ASCIIToUTF16("Submit"); field.form_control_type = "submit"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1611,33 +1707,40 @@ field.label = ASCIIToUTF16("Name on Card"); field.name = ASCIIToUTF16("name_on_card"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // This is not a field we know how to process. But we should skip over it // and process the other fields in the card block. field.label = ASCIIToUTF16("Card image"); field.name = ASCIIToUTF16("card_image"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Card Number"); field.name = ASCIIToUTF16("card_number"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Exp Month"); field.name = ASCIIToUTF16("ccmonth"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Exp Year"); field.name = ASCIIToUTF16("ccyear"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Verification"); field.name = ASCIIToUTF16("verification"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = base::string16(); field.name = ASCIIToUTF16("Submit"); field.form_control_type = "submit"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1674,18 +1777,22 @@ field.label = ASCIIToUTF16("Address Line1"); field.name = ASCIIToUTF16("Address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address Line2"); field.name = ASCIIToUTF16("Address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address Line3"); field.name = ASCIIToUTF16("Address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1715,18 +1822,22 @@ field.label = ASCIIToUTF16("Address Line1"); field.name = ASCIIToUTF16("shipping.address.addressLine1"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address Line2"); field.name = ASCIIToUTF16("shipping.address.addressLine2"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address Line3"); field.name = ASCIIToUTF16("billing.address.addressLine3"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address Line4"); field.name = ASCIIToUTF16("billing.address.addressLine4"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1759,18 +1870,22 @@ field.label = ASCIIToUTF16("Street:"); field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads1"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Suite or Apt:"); field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adap"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Street address second line"); field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads2"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City:"); field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adct"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1802,14 +1917,17 @@ field.label = ASCIIToUTF16("Address Line1"); field.name = ASCIIToUTF16("address1"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Floor number, suite number, etc"); field.name = ASCIIToUTF16("address2"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City:"); field.name = ASCIIToUTF16("city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1836,14 +1954,17 @@ field.label = ASCIIToUTF16("Address Line1"); field.name = ASCIIToUTF16("Address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address Line2"); field.name = ASCIIToUTF16("Address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State/Province/Region"); field.name = ASCIIToUTF16("State"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1871,46 +1992,57 @@ field.label = ASCIIToUTF16("First Name*:"); field.name = ASCIIToUTF16("editBillingAddress$firstNameBox"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last Name*:"); field.name = ASCIIToUTF16("editBillingAddress$lastNameBox"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Company Name:"); field.name = ASCIIToUTF16("editBillingAddress$companyBox"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address*:"); field.name = ASCIIToUTF16("editBillingAddress$addressLine1Box"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Apt/Suite :"); field.name = ASCIIToUTF16("editBillingAddress$addressLine2Box"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City*:"); field.name = ASCIIToUTF16("editBillingAddress$cityBox"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State/Province*:"); field.name = ASCIIToUTF16("editBillingAddress$stateDropDown"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country*:"); field.name = ASCIIToUTF16("editBillingAddress$countryDropDown"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Postal Code*:"); field.name = ASCIIToUTF16("editBillingAddress$zipCodeBox"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Phone*:"); field.name = ASCIIToUTF16("editBillingAddress$phoneBox"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Email Address*:"); field.name = ASCIIToUTF16("email$emailBox"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1944,11 +2076,13 @@ field.label = ASCIIToUTF16("Phone:"); field.name = ASCIIToUTF16("dayphone1"); field.max_length = 0; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("-"); field.name = ASCIIToUTF16("dayphone2"); field.max_length = 3; // Size of prefix is 3. + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("-"); @@ -1956,11 +2090,13 @@ field.max_length = 4; // Size of suffix is 4. If unlimited size is // passed, phone will be parsed as // <country code> - <area code> - <phone>. + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("ext.:"); field.name = ASCIIToUTF16("dayphone4"); field.max_length = 0; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -1989,22 +2125,27 @@ field.label = ASCIIToUTF16("Name on Card"); field.name = ASCIIToUTF16("name_on_card"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("billing_address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Card Number"); field.name = ASCIIToUTF16("card_number"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Expiration Date"); field.name = ASCIIToUTF16("expiration_month"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Expiration Year"); field.name = ASCIIToUTF16("expiration_year"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -2040,26 +2181,32 @@ field.label = ASCIIToUTF16("Card number"); field.name = ASCIIToUTF16("ccnumber"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("First name"); field.name = ASCIIToUTF16("first_name"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last name"); field.name = ASCIIToUTF16("last_name"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Expiration date"); field.name = ASCIIToUTF16("ccexpiresmonth"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = base::string16(); field.name = ASCIIToUTF16("ccexpiresyear"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("cvc number"); field.name = ASCIIToUTF16("csc"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -2099,26 +2246,32 @@ field.label = ASCIIToUTF16("Cardholder Name"); field.name = ASCIIToUTF16("cc_first_name"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last name"); field.name = ASCIIToUTF16("last_name"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Card number"); field.name = ASCIIToUTF16("ccnumber"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Expiration date"); field.name = ASCIIToUTF16("ccexpiresmonth"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = base::string16(); field.name = ASCIIToUTF16("ccexpiresyear"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("cvc number"); field.name = ASCIIToUTF16("csc"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -2154,22 +2307,27 @@ field.label = ASCIIToUTF16("Name on Card"); field.name = ASCIIToUTF16("name_on_card"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("billing_address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Card Number"); field.name = ASCIIToUTF16("card_number"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Expiration Date"); field.name = ASCIIToUTF16("expiration_month"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Expiration Year"); field.name = ASCIIToUTF16("expiration_year"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Add checkable field. @@ -2178,7 +2336,9 @@ FormFieldData::CheckStatus::kCheckableButUnchecked; checkable_field.label = ASCIIToUTF16("Checkable1"); checkable_field.name = ASCIIToUTF16("Checkable1"); + checkable_field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(checkable_field); + FormStructure form_structure(form); std::vector<FormStructure*> forms; @@ -2237,6 +2397,7 @@ for (size_t i = 0; i < 5; ++i) { field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); } @@ -2299,6 +2460,7 @@ for (size_t i = 0; i < 300; ++i) { field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); malformed_form.fields.push_back(field); } @@ -2426,6 +2588,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}, {AutofillProfile::UNVALIDATED}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last Name"); @@ -2433,6 +2596,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}, {AutofillProfile::UNVALIDATED}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Email"); @@ -2441,6 +2605,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}, {AutofillProfile::INVALID}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Phone"); @@ -2449,6 +2614,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {PHONE_HOME_WHOLE_NUMBER}, {AutofillProfile::EMPTY}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); @@ -2457,6 +2623,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {ADDRESS_HOME_COUNTRY}, {AutofillProfile::VALID}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Add checkable field. @@ -2468,6 +2635,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {ADDRESS_HOME_COUNTRY}, {AutofillProfile::VALID}); + checkable_field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(checkable_field); form_structure = std::make_unique<FormStructure>(form); @@ -2557,6 +2725,7 @@ field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, @@ -2625,6 +2794,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}, {AutofillProfile::UNVALIDATED}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last Name"); @@ -2632,6 +2802,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}, {AutofillProfile::UNVALIDATED}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Email"); @@ -2640,6 +2811,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}, {AutofillProfile::INVALID}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Phone"); @@ -2648,6 +2820,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {PHONE_HOME_WHOLE_NUMBER}, {AutofillProfile::EMPTY}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); @@ -2656,6 +2829,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {ADDRESS_HOME_COUNTRY}, {AutofillProfile::VALID}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Add checkable field. @@ -2667,6 +2841,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {ADDRESS_HOME_COUNTRY}, {AutofillProfile::VALID}); + checkable_field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(checkable_field); form_structure = std::make_unique<FormStructure>(form); @@ -2757,6 +2932,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}, {AutofillProfile::UNVALIDATED, AutofillProfile::VALID}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last Name"); @@ -2764,6 +2940,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}, {AutofillProfile::UNVALIDATED, AutofillProfile::VALID}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Email"); @@ -2772,6 +2949,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}, {AutofillProfile::INVALID, AutofillProfile::VALID}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Phone"); @@ -2781,6 +2959,7 @@ possible_field_types, possible_field_types_validities, {PHONE_HOME_WHOLE_NUMBER}, {AutofillProfile::EMPTY, AutofillProfile::VALID}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); @@ -2789,6 +2968,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {ADDRESS_HOME_COUNTRY}, {AutofillProfile::VALID, AutofillProfile::VALID}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Add checkable field. @@ -2800,6 +2980,7 @@ test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {ADDRESS_HOME_COUNTRY}, {AutofillProfile::VALID, AutofillProfile::VALID}); + checkable_field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(checkable_field); form_structure = std::make_unique<FormStructure>(form); @@ -2888,12 +3069,14 @@ field.name = ASCIIToUTF16("firstname"); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastname"); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Email"); @@ -2901,6 +3084,7 @@ field.form_control_type = "email"; test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Phone"); @@ -2909,6 +3093,7 @@ test::InitializePossibleTypesAndValidities(possible_field_types, possible_field_types_validities, {PHONE_HOME_WHOLE_NUMBER}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); @@ -2917,6 +3102,7 @@ test::InitializePossibleTypesAndValidities(possible_field_types, possible_field_types_validities, {ADDRESS_HOME_COUNTRY}); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Add checkable field. @@ -2928,6 +3114,7 @@ test::InitializePossibleTypesAndValidities(possible_field_types, possible_field_types_validities, {ADDRESS_HOME_COUNTRY}); + checkable_field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(checkable_field); form_structure = std::make_unique<FormStructure>(form); @@ -3017,6 +3204,7 @@ field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, @@ -3074,6 +3262,7 @@ field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, @@ -3112,35 +3301,45 @@ field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("firstname"); field.autocomplete_attribute = "given-name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}); + field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastname"); field.autocomplete_attribute = "family-name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}); + field.label = ASCIIToUTF16("Email"); field.name = ASCIIToUTF16("email"); field.form_control_type = "email"; field.autocomplete_attribute = "email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}); + field.label = ASCIIToUTF16("username"); field.name = ASCIIToUTF16("username"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {USERNAME}); + field.label = ASCIIToUTF16("password"); field.name = ASCIIToUTF16("password"); field.form_control_type = "password"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities(possible_field_types, possible_field_types_validities, {ACCOUNT_CREATION_PASSWORD}); + form_structure = std::make_unique<FormStructure>(form); ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); @@ -3241,22 +3440,28 @@ field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("firstname"); field.autocomplete_attribute = "given-name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}); + field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastname"); field.autocomplete_attribute = "family-name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}); + field.label = ASCIIToUTF16("Email"); field.name = ASCIIToUTF16("email"); field.form_control_type = "email"; field.autocomplete_attribute = "email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}); + form_structure = std::make_unique<FormStructure>(form); ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); @@ -3331,9 +3536,11 @@ field.autocomplete_attribute = "given-name"; field.css_classes = ASCIIToUTF16("class1 class2"); field.properties_mask = FieldPropertiesFlags::kHadFocus; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}); + field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastname"); field.name_attribute = field.name; @@ -3342,9 +3549,11 @@ field.css_classes = ASCIIToUTF16("class1 class2"); field.properties_mask = FieldPropertiesFlags::kHadFocus | FieldPropertiesFlags::kUserTyped; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}); + field.label = ASCIIToUTF16("Email"); field.name = ASCIIToUTF16("email"); field.name_attribute = field.name; @@ -3354,9 +3563,11 @@ field.css_classes = ASCIIToUTF16("class1 class2"); field.properties_mask = FieldPropertiesFlags::kHadFocus | FieldPropertiesFlags::kUserTyped; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}); + form_structure = std::make_unique<FormStructure>(form); ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); @@ -3429,22 +3640,28 @@ field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("firstname"); field.name_attribute = field.name; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}); + field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastname"); field.name_attribute = field.name; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}); + field.label = ASCIIToUTF16("Email"); field.name = ASCIIToUTF16("email"); field.name_attribute = field.name; field.form_control_type = "email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}); + form_structure = std::make_unique<FormStructure>(form); ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); @@ -3511,17 +3728,23 @@ field.form_control_type = "text"; // No label for the first field. + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}); + field.label = ASCIIToUTF16("Last Name"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}); + field.label = ASCIIToUTF16("Email"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}); + form_structure = std::make_unique<FormStructure>(form); ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); @@ -3583,19 +3806,25 @@ FormFieldData field; field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}); + field.css_classes = ASCIIToUTF16("last_name_field"); field.id_attribute = ASCIIToUTF16("lastname_id"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}); + field.css_classes = ASCIIToUTF16("email_field required_field"); field.id_attribute = ASCIIToUTF16("email_id"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}); + std::unique_ptr<FormStructure> form_structure(new FormStructure(form)); ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); @@ -3672,12 +3901,17 @@ FormFieldData field; field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}); + + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}); + + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}); @@ -3752,22 +3986,28 @@ // Some fields don't have "name" or "autocomplete" attributes, and some have // neither. // No label. + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}); + field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastname"); field.name_attribute = field.name; field.autocomplete_attribute = "family-name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}); + field.label = ASCIIToUTF16("Email"); field.form_control_type = "email"; field.autocomplete_attribute = "email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}); + form_structure = std::make_unique<FormStructure>(form); ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); @@ -3842,18 +4082,22 @@ field.id_attribute = ASCIIToUTF16("first_name"); field.autocomplete_attribute = "given-name"; field.css_classes = ASCIIToUTF16("class1 class2"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}); + field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastname"); field.name_attribute = field.name; field.id_attribute = ASCIIToUTF16("last_name"); field.autocomplete_attribute = "family-name"; field.css_classes = ASCIIToUTF16("class1 class2"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}); + field.label = ASCIIToUTF16("Email"); field.name = ASCIIToUTF16("email"); field.name_attribute = field.name; @@ -3861,9 +4105,11 @@ field.form_control_type = "email"; field.autocomplete_attribute = "email"; field.css_classes = ASCIIToUTF16("class1 class2"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}); + form_structure = std::make_unique<FormStructure>(form); ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); @@ -3927,16 +4173,19 @@ field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("first"); field.name_attribute = field.name; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("last"); field.name_attribute = field.name; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Email"); field.name = ASCIIToUTF16("email"); field.name_attribute = field.name; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -4213,6 +4462,7 @@ field.label = ASCIIToUTF16("email"); field.name = ASCIIToUTF16("email"); field.name_attribute = field.name; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS}); @@ -4220,6 +4470,7 @@ field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("first"); field.name_attribute = field.name; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_FIRST}); @@ -4227,6 +4478,7 @@ field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("last"); field.name_attribute = field.name; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities( possible_field_types, possible_field_types_validities, {NAME_LAST}); @@ -4234,6 +4486,7 @@ field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.name_attribute = field.name; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); test::InitializePossibleTypesAndValidities(possible_field_types, possible_field_types_validities, @@ -4358,14 +4611,17 @@ FormFieldData field; field.name = ASCIIToUTF16("email"); field.name_attribute = field.name; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.name = ASCIIToUTF16("first"); field.name_attribute = field.name; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.name = ASCIIToUTF16("last"); field.name_attribute = field.name; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -4387,6 +4643,7 @@ form.url = GURL("http://www.foo.com/"); FormFieldData field; field.name = ASCIIToUTF16("email"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form.is_form_tag = is_form_tag; @@ -4439,6 +4696,7 @@ field.aria_label = ASCIIToUTF16(f.aria_label); field.aria_description = ASCIIToUTF16(f.aria_description); field.css_classes = ASCIIToUTF16(f.css_classes); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); } RandomizedEncoder encoder("seed for testing", @@ -4580,6 +4838,7 @@ field.form_control_type = "text"; field.label = ASCIIToUTF16("email"); field.name = ASCIIToUTF16("email"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); TestingPrefServiceSimple prefs; @@ -4613,10 +4872,12 @@ field.label = ASCIIToUTF16("email"); field.name = ASCIIToUTF16("email"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("first"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Checkable fields shouldn't affect the signature. @@ -4624,6 +4885,7 @@ field.name = ASCIIToUTF16("Select"); field.form_control_type = "checkbox"; field.check_status = FormFieldData::CheckStatus::kCheckableButUnchecked; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); form_structure = std::make_unique<FormStructure>(form); @@ -4654,16 +4916,24 @@ field.label = ASCIIToUTF16("Random Field label"); field.name = ASCIIToUTF16("random1234"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.label = ASCIIToUTF16("Random Field label2"); field.name = ASCIIToUTF16("random12345"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.label = ASCIIToUTF16("Random Field label3"); field.name = ASCIIToUTF16("1ran12dom12345678"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.label = ASCIIToUTF16("Random Field label3"); field.name = ASCIIToUTF16("12345ran123456dom123"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + form_structure = std::make_unique<FormStructure>(form); EXPECT_EQ(FormStructureTestImpl::Hash64Bit( std::string("https://login.facebook.com&login_form&email&first&" @@ -4681,16 +4951,19 @@ field.label = ASCIIToUTF16("username"); field.name = ASCIIToUTF16("username"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("password"); field.name = ASCIIToUTF16("password"); field.form_control_type = "password"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = base::string16(); field.name = ASCIIToUTF16("Submit"); field.form_control_type = "submit"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); EXPECT_TRUE(form.SameFormAs(FormStructure(form).ToFormData())); @@ -4706,18 +4979,21 @@ field.label = ASCIIToUTF16("username"); field.name = ASCIIToUTF16("username"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("select"); field.name = ASCIIToUTF16("select"); field.form_control_type = "checkbox"; field.check_status = FormFieldData::CheckStatus::kCheckableButUnchecked; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = base::string16(); field.name = ASCIIToUTF16("email"); field.form_control_type = "text"; field.check_status = FormFieldData::CheckStatus::kNotCheckable; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -4761,16 +5037,19 @@ // No label on the first field. field.name = ASCIIToUTF16("username"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Enter your Email address"); field.name = ASCIIToUTF16("email"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Enter your Password"); field.name = ASCIIToUTF16("password"); field.form_control_type = "password"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); std::vector<FormStructure*> forms; @@ -4812,6 +5091,7 @@ // No label on the first field. field.name = ASCIIToUTF16("username"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // This label will be truncated in the XML request. @@ -4822,11 +5102,13 @@ "Exceeding A Certain Number Of Characters..."); field.name = ASCIIToUTF16("email"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Enter your Password"); field.name = ASCIIToUTF16("password"); field.form_control_type = "password"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -4869,6 +5151,7 @@ field.label = ASCIIToUTF16("username"); field.name = ASCIIToUTF16("username"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = base::string16(); @@ -4876,6 +5159,7 @@ field.name = ASCIIToUTF16(""); field.form_control_type = "text"; field.check_status = FormFieldData::CheckStatus::kNotCheckable; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -4923,12 +5207,14 @@ field.label = ASCIIToUTF16("username"); field.name = ASCIIToUTF16("username"); field.form_control_type = "text"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = base::string16(); field.name = ASCIIToUTF16("country"); field.form_control_type = "text"; field.check_status = FormFieldData::CheckStatus::kNotCheckable; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -4973,7 +5259,9 @@ field.option_values.push_back(ASCIIToUTF16("")); field.option_contents.push_back(ASCIIToUTF16("Germany")); field.option_values.push_back(ASCIIToUTF16("GRMNY")); + field.unique_renderer_id = MakeFieldRendererId(); form_data.fields.push_back(field); + FormStructure form_structure(form_data); form_structure.ParseFieldTypesFromAutocompleteAttributes(); @@ -4996,7 +5284,9 @@ // A freeform input (<input>) allows any value (overriding other <select>s). FormFieldData freeform_field; freeform_field.autocomplete_attribute = "billing country"; + field.unique_renderer_id = MakeFieldRendererId(); form_data.fields.push_back(freeform_field); + FormStructure form_structure2(form_data); form_structure2.ParseFieldTypesFromAutocompleteAttributes(); EXPECT_EQ(0U, form_structure2.PossibleValues(ADDRESS_BILLING_COUNTRY).size()); @@ -5253,15 +5543,18 @@ field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("fname"); + field.unique_renderer_id = MakeFieldRendererId(); form_data.fields.push_back(field); field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lname"); + field.unique_renderer_id = MakeFieldRendererId(); form_data.fields.push_back(field); field.label = ASCIIToUTF16("email"); field.name = ASCIIToUTF16("email"); field.autocomplete_attribute = "address-level2"; + field.unique_renderer_id = MakeFieldRendererId(); form_data.fields.push_back(field); FormStructure form(form_data); @@ -5312,10 +5605,12 @@ field.label = ASCIIToUTF16("fullname"); field.name = ASCIIToUTF16("fullname"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Checkable fields should be ignored in parsing @@ -5324,6 +5619,7 @@ checkable_field.form_control_type = "radio"; checkable_field.check_status = FormFieldData::CheckStatus::kCheckableButUnchecked; + checkable_field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(checkable_field); FormStructure form_structure(form); @@ -5334,11 +5630,13 @@ FormData form2; field.label = ASCIIToUTF16("email"); field.name = ASCIIToUTF16("email"); + field.unique_renderer_id = MakeFieldRendererId(); form2.fields.push_back(field); field.label = ASCIIToUTF16("password"); field.name = ASCIIToUTF16("password"); field.form_control_type = "password"; + field.unique_renderer_id = MakeFieldRendererId(); form2.fields.push_back(field); FormStructure form_structure2(form2); @@ -5403,6 +5701,7 @@ field.form_control_type = "email"; field.label = ASCIIToUTF16("emailaddress"); field.name = ASCIIToUTF16("emailaddress"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Add form to the vector needed by the response parsing function. @@ -5432,6 +5731,7 @@ field.form_control_type = "email"; field.label = ASCIIToUTF16("emailaddress"); field.name = ASCIIToUTF16("emailaddress"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Add form to the vector needed by the response parsing function. @@ -5473,12 +5773,14 @@ field.name = ASCIIToUTF16("email"); field.form_control_type = "text"; field.autocomplete_attribute = "email"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("password"); field.name = ASCIIToUTF16("password"); field.form_control_type = "password"; field.autocomplete_attribute = "new-password"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -5514,18 +5816,22 @@ field.label = ASCIIToUTF16("fullname"); field.name = ASCIIToUTF16("fullname"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("height"); field.name = ASCIIToUTF16("height"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("email"); field.name = ASCIIToUTF16("email"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -5561,14 +5867,17 @@ field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("fname"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lname"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("email"); field.name = ASCIIToUTF16("email"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -5603,22 +5912,27 @@ field.label = ASCIIToUTF16("Cardholder"); field.name = ASCIIToUTF16("fullname"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Card Number"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Month)"); field.name = ASCIIToUTF16("expiry_month"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Year"); field.name = ASCIIToUTF16("expiry_year"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Quantity"); field.name = ASCIIToUTF16("quantity"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -5662,18 +5976,22 @@ field.label = ASCIIToUTF16("Cardholder"); field.name = ASCIIToUTF16("fullname"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Card Number"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Expiry Date (MMYY)"); field.name = ASCIIToUTF16("expiry"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Quantity"); field.name = ASCIIToUTF16("quantity"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -5839,7 +6157,16 @@ EXPECT_EQ(ASCIIToUTF16(""), prefix); } -TEST_F(FormStructureTestImpl, RationalizePhoneNumber_RunsOncePerSection) { +TEST_P(ParameterizedFormStructureTest, + RationalizePhoneNumber_RunsOncePerSection) { + bool section_with_renderer_ids = GetParam(); + base::test::ScopedFeatureList scoped_features; + std::vector<base::Feature> enabled; + std::vector<base::Feature> disabled; + (section_with_renderer_ids ? &enabled : &disabled) + ->push_back(features::kAutofillNameSectionsWithRendererIds); + scoped_features.InitWithFeatures(enabled, disabled); + FormData form; form.url = GURL("http://foo.com"); FormFieldData field; @@ -5848,18 +6175,22 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Home Phone"); field.name = ASCIIToUTF16("homePhoneNumber"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Cell Phone"); field.name = ASCIIToUTF16("cellPhoneNumber"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -5880,9 +6211,15 @@ FormStructure::ParseApiQueryResponse( response_string, forms, test::GetEncodedSignatures(forms), nullptr); - EXPECT_FALSE(form_structure.phone_rationalized_["fullName_1-default"]); - form_structure.RationalizePhoneNumbersInSection("fullName_1-default"); - EXPECT_TRUE(form_structure.phone_rationalized_["fullName_1-default"]); + if (section_with_renderer_ids) { + EXPECT_FALSE(form_structure.phone_rationalized_["fullName_11-default"]); + form_structure.RationalizePhoneNumbersInSection("fullName_11-default"); + EXPECT_TRUE(form_structure.phone_rationalized_["fullName_11-default"]); + } else { + EXPECT_FALSE(form_structure.phone_rationalized_["fullName_1-default"]); + form_structure.RationalizePhoneNumbersInSection("fullName_1-default"); + EXPECT_TRUE(form_structure.phone_rationalized_["fullName_1-default"]); + } ASSERT_EQ(1U, forms.size()); ASSERT_EQ(4U, forms[0]->field_count()); EXPECT_EQ(NAME_FULL, forms[0]->field(0)->server_type()); @@ -5906,14 +6243,17 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -5953,18 +6293,22 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -6006,22 +6350,27 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -6067,26 +6416,32 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -6139,31 +6494,37 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.section = "Billing"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.section = "Billing"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); field.section = "Billing"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.section = "Shipping"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.section = "Shipping"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); field.section = "Shipping"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -6219,78 +6580,93 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.section = "Shipping"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.section = "Shipping"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.section = "Shipping"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); field.section = "Shipping"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Billing field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.section = "Billing"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.section = "Billing"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.section = "Billing"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.section = "Billing"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); field.section = "Billing"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Work address (not realistic) field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.section = "Work"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.section = "Work"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.section = "Work"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.section = "Work"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); field.section = "Work"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); field.section = "Work"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -6371,26 +6747,32 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -6446,39 +6828,48 @@ // Shipping field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Billing field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -6535,45 +6926,55 @@ // First Section field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Second Section field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Third Section field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Fourth Section field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -6637,18 +7038,22 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.section = "billing"; @@ -6657,54 +7062,64 @@ field.name = ASCIIToUTF16("country2"); field.form_control_type = "select-one"; field.is_focusable = false; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.is_focusable = true; // visible field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country2"); field.form_control_type = "select-one"; field.is_focusable = false; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country2"); field.form_control_type = "select-one"; field.is_focusable = false; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country2"); field.form_control_type = "select-one"; field.is_focusable = false; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.is_focusable = true; // visible field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.section = "billing-2"; field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -6770,74 +7185,88 @@ // First Section field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); field.form_control_type = "select-one"; field.is_focusable = false; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.is_focusable = true; // visible field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country2"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("city"); field.name = ASCIIToUTF16("City"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state2"); field.form_control_type = "select-one"; field.role = FormFieldData::RoleAttribute::kPresentation; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.role = FormFieldData::RoleAttribute::kOther; // visible field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Second Section field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("city"); field.name = ASCIIToUTF16("City"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Third Section field.label = ASCIIToUTF16("city"); field.name = ASCIIToUTF16("City"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state2"); field.form_control_type = "select-one"; field.role = FormFieldData::RoleAttribute::kPresentation; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.role = FormFieldData::RoleAttribute::kOther; // visible field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country2"); field.form_control_type = "select-one"; field.is_focusable = false; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -6915,28 +7344,33 @@ field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country2"); field.form_control_type = "select-one"; field.is_focusable = false; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country3"); field.form_control_type = "select-one"; field.is_focusable = false; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.is_focusable = true; // visible field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -6979,34 +7413,40 @@ field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country2"); field.form_control_type = "select-one"; field.is_focusable = false; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country3"); field.form_control_type = "select-one"; field.is_focusable = false; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.is_focusable = true; // visible field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state"); field.is_focusable = false; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("State"); field.name = ASCIIToUTF16("state2"); field.is_focusable = true; // visible + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -7066,22 +7506,26 @@ // Autocomplete Off, with server data. field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("firstName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Autocomplete Off, without server data. field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Autocomplete On, with server data. field.should_autocomplete = true; field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); // Autocomplete On, without server data. field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -7135,18 +7579,22 @@ // All fields with autocomplete off and no server data. field.label = ASCIIToUTF16("Cardholder Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Credit Card Number"); field.name = ASCIIToUTF16("cc-number"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Expiration Date"); field.name = ASCIIToUTF16("exp-date"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("CVC"); field.name = ASCIIToUTF16("cvc"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -7210,18 +7658,22 @@ // All fields with autocomplete off and no server data. field.label = ASCIIToUTF16("Cardholder Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Credit Card Number"); field.name = ASCIIToUTF16("cc-number"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Expiration Date"); field.name = ASCIIToUTF16("exp-date"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("CVC"); field.name = ASCIIToUTF16("cvc"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -7301,16 +7753,22 @@ // Just adding >=3 random fields to trigger rationalization. field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("firstName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.label = ASCIIToUTF16("Address"); field.name = ASCIIToUTF16("address"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Something under test"); field.name = ASCIIToUTF16("tested-thing"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -7361,17 +7819,22 @@ // Just adding >=3 random fields to trigger rationalization. field.label = ASCIIToUTF16("First Name"); field.name = ASCIIToUTF16("firstName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); + field.label = ASCIIToUTF16("Last Name"); field.name = ASCIIToUTF16("lastName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Some field with required type"); field.name = ASCIIToUTF16("some-name"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Something under test"); field.name = ASCIIToUTF16("tested-thing"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); AutofillQueryResponse response; @@ -7418,6 +7881,7 @@ for (size_t i = 0; i < 250; ++i) { field.form_control_type = "text"; field.name = ASCIIToUTF16("text") + base::NumberToString16(i); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); } @@ -7440,6 +7904,7 @@ FormFieldData field; field.name = ASCIIToUTF16("Password"); field.form_control_type = "password"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); EXPECT_FALSE(FormStructure(form).ShouldBeUploaded()); @@ -7465,9 +7930,15 @@ // Tests if a new logical form is started with the second appearance of a field // of type |NAME|. -TEST_F(FormStructureTestImpl, NoAutocompleteSectionNames) { - base::test::ScopedFeatureList enabled; - enabled.InitAndEnableFeature(features::kAutofillUseNewSectioningMethod); +TEST_P(ParameterizedFormStructureTest, NoAutocompleteSectionNames) { + bool section_with_renderer_ids = GetParam(); + base::test::ScopedFeatureList scoped_features; + std::vector<base::Feature> enabled; + std::vector<base::Feature> disabled; + enabled.push_back(features::kAutofillUseNewSectioningMethod); + (section_with_renderer_ids ? &enabled : &disabled) + ->push_back(features::kAutofillNameSectionsWithRendererIds); + scoped_features.InitWithFeatures(enabled, disabled); FormData form; form.url = GURL("http://foo.com"); @@ -7477,26 +7948,32 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Phone"); field.name = ASCIIToUTF16("phone"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Phone"); field.name = ASCIIToUTF16("phone"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -7515,12 +7992,21 @@ // Assert the correct number of fields. ASSERT_EQ(6U, form_structure.field_count()); - EXPECT_EQ("fullName_1-default", form_structure.field(0)->section); - EXPECT_EQ("fullName_1-default", form_structure.field(1)->section); - EXPECT_EQ("fullName_1-default", form_structure.field(2)->section); - EXPECT_EQ("fullName_2-default", form_structure.field(3)->section); - EXPECT_EQ("fullName_2-default", form_structure.field(4)->section); - EXPECT_EQ("fullName_2-default", form_structure.field(5)->section); + if (section_with_renderer_ids) { + EXPECT_EQ("fullName_11-default", form_structure.field(0)->section); + EXPECT_EQ("fullName_11-default", form_structure.field(1)->section); + EXPECT_EQ("fullName_11-default", form_structure.field(2)->section); + EXPECT_EQ("fullName_14-default", form_structure.field(3)->section); + EXPECT_EQ("fullName_14-default", form_structure.field(4)->section); + EXPECT_EQ("fullName_14-default", form_structure.field(5)->section); + } else { + EXPECT_EQ("fullName_1-default", form_structure.field(0)->section); + EXPECT_EQ("fullName_1-default", form_structure.field(1)->section); + EXPECT_EQ("fullName_1-default", form_structure.field(2)->section); + EXPECT_EQ("fullName_2-default", form_structure.field(3)->section); + EXPECT_EQ("fullName_2-default", form_structure.field(4)->section); + EXPECT_EQ("fullName_2-default", form_structure.field(5)->section); + } } // Tests that the immediate recurrence of the |PHONE_HOME_NUMBER| type does not @@ -7537,33 +8023,40 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Phone"); field.name = ASCIIToUTF16("phone"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Mobile Number"); field.name = ASCIIToUTF16("mobileNumber"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.autocomplete_attribute = "section-blue billing name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Phone"); field.name = ASCIIToUTF16("phone"); field.autocomplete_attribute = "section-blue billing tel"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Mobile Number"); field.name = ASCIIToUTF16("mobileNumber"); field.autocomplete_attribute = "section-blue billing tel"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -7594,9 +8087,15 @@ // Tests if a new logical form is started with the second appearance of a field // of type |ADDRESS_HOME_COUNTRY|. -TEST_F(FormStructureTestImpl, SplitByRecurringFieldType) { - base::test::ScopedFeatureList enabled; - enabled.InitAndEnableFeature(features::kAutofillUseNewSectioningMethod); +TEST_P(ParameterizedFormStructureTest, SplitByRecurringFieldType) { + bool section_with_renderer_ids = GetParam(); + base::test::ScopedFeatureList scoped_features; + std::vector<base::Feature> enabled; + std::vector<base::Feature> disabled; + enabled.push_back(features::kAutofillUseNewSectioningMethod); + (section_with_renderer_ids ? &enabled : &disabled) + ->push_back(features::kAutofillNameSectionsWithRendererIds); + scoped_features.InitWithFeatures(enabled, disabled); FormData form; form.url = GURL("http://foo.com"); @@ -7607,21 +8106,25 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.autocomplete_attribute = "section-blue shipping name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); field.autocomplete_attribute = "section-blue shipping country"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.autocomplete_attribute = "section-blue shipping name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); field.autocomplete_attribute = ""; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -7641,16 +8144,26 @@ EXPECT_EQ("blue-shipping-default", form_structure.field(0)->section); EXPECT_EQ("blue-shipping-default", form_structure.field(1)->section); EXPECT_EQ("blue-shipping-default", form_structure.field(2)->section); - EXPECT_EQ("country_2-default", form_structure.field(3)->section); + if (section_with_renderer_ids) { + EXPECT_EQ("country_14-default", form_structure.field(3)->section); + } else { + EXPECT_EQ("country_2-default", form_structure.field(3)->section); + } } // Tests if a new logical form is started with the second appearance of a field // of type |NAME_FULL| and another with the second appearance of a field of // type |ADDRESS_HOME_COUNTRY|. -TEST_F(FormStructureTestImpl, +TEST_P(ParameterizedFormStructureTest, SplitByNewAutocompleteSectionNameAndRecurringType) { - base::test::ScopedFeatureList enabled; - enabled.InitAndEnableFeature(features::kAutofillUseNewSectioningMethod); + bool section_with_renderer_ids = GetParam(); + base::test::ScopedFeatureList scoped_features; + std::vector<base::Feature> enabled; + std::vector<base::Feature> disabled; + enabled.push_back(features::kAutofillUseNewSectioningMethod); + (section_with_renderer_ids ? &enabled : &disabled) + ->push_back(features::kAutofillNameSectionsWithRendererIds); + scoped_features.InitWithFeatures(enabled, disabled); FormData form; form.url = GURL("http://foo.com"); @@ -7661,21 +8174,25 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.autocomplete_attribute = "section-blue shipping name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); field.autocomplete_attribute = "section-blue billing country"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.autocomplete_attribute = ""; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); field.autocomplete_attribute = ""; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -7696,7 +8213,11 @@ EXPECT_EQ("blue-shipping-default", form_structure.field(0)->section); EXPECT_EQ("blue-billing-default", form_structure.field(1)->section); EXPECT_EQ("blue-billing-default", form_structure.field(2)->section); - EXPECT_EQ("country_2-default", form_structure.field(3)->section); + if (section_with_renderer_ids) { + EXPECT_EQ("country_14-default", form_structure.field(3)->section); + } else { + EXPECT_EQ("country_2-default", form_structure.field(3)->section); + } } // Tests if a new logical form is started with the second appearance of a field @@ -7714,21 +8235,25 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.autocomplete_attribute = "section-blue shipping name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); field.autocomplete_attribute = ""; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.autocomplete_attribute = "section-blue billing name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); field.autocomplete_attribute = ""; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -7768,21 +8293,25 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); field.autocomplete_attribute = "section-blue shipping country"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.autocomplete_attribute = "section-blue billing name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("City"); field.name = ASCIIToUTF16("city"); field.autocomplete_attribute = ""; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -7820,11 +8349,13 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); field.autocomplete_attribute = "section-blue shipping country"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -7859,17 +8390,20 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Phone"); field.name = ASCIIToUTF16("phone"); field.is_focusable = false; // hidden + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("FullName"); field.name = ASCIIToUTF16("fullName"); field.is_focusable = true; // visible field.autocomplete_attribute = "shipping name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form); @@ -7906,11 +8440,13 @@ field.label = ASCIIToUTF16("Full Name"); field.name = ASCIIToUTF16("fullName"); field.autocomplete_attribute = "section-red ship name"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); field.label = ASCIIToUTF16("Country"); field.name = ASCIIToUTF16("country"); field.autocomplete_attribute = "section-blue shipping country"; + field.unique_renderer_id = MakeFieldRendererId(); form.fields.push_back(field); FormStructure form_structure(form);
diff --git a/components/autofill/core/browser/payments/autofill_save_card_infobar_mobile.h b/components/autofill/core/browser/payments/autofill_save_card_infobar_mobile.h index 969131b..99d93d80 100644 --- a/components/autofill/core/browser/payments/autofill_save_card_infobar_mobile.h +++ b/components/autofill/core/browser/payments/autofill_save_card_infobar_mobile.h
@@ -7,6 +7,8 @@ #include <memory> +#include "components/signin/public/identity_manager/account_info.h" + namespace infobars { class InfoBar; } @@ -15,9 +17,12 @@ class AutofillSaveCardInfoBarDelegateMobile; -// Creates an infobar for saving a credit card on a mobile device. +// Creates an Infobar for saving a credit card on a mobile device. If +// AccountInfo contains the user's data, an account indication footer will be +// shown at the bottom of the Infobar. std::unique_ptr<infobars::InfoBar> CreateSaveCardInfoBarMobile( - std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile> delegate); + std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile> delegate, + base::Optional<AccountInfo> accountInfo); } // namespace autofill
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index c67f781..d712e719 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -139,6 +139,12 @@ const base::Feature kAutofillRefillWithRendererIds{ "AutofillRefillWithRendererIds", base::FEATURE_DISABLED_BY_DEFAULT}; +// When enabled, Autofill will use FormRendererIds instead of +// unique_name() to create unique section names. +// TODO(crbug/896689): Remove once experiment is finished. +const base::Feature kAutofillNameSectionsWithRendererIds{ + "AutofillNameSectionsWithRendererIds", base::FEATURE_DISABLED_BY_DEFAULT}; + // When enabled, Autofill will use FieldRendererIds instead of unique_names // to align forms in FormStructure::RetrieveFromCache(). const base::Feature kAutofillRetrieveFromCacheWithRendererIds{
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h index 052440fa..695dbae 100644 --- a/components/autofill/core/common/autofill_features.h +++ b/components/autofill/core/common/autofill_features.h
@@ -43,6 +43,7 @@ extern const base::Feature kAutofillFixFillableFieldTypes; extern const base::Feature kAutofillRefillWithRendererIds; extern const base::Feature kAutofillRetrieveFromCacheWithRendererIds; +extern const base::Feature kAutofillNameSectionsWithRendererIds; extern const base::Feature kAutofillKeyboardAccessory; extern const base::Feature kAutofillLabelAffixRemoval; extern const base::Feature kAutofillPruneSuggestions;
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index 5d89d6e7..8d74f54 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -84,6 +84,12 @@ const base::Feature kAutofillEnableOffersInDownstream{ "kAutofillEnableOffersInDownstream", base::FEATURE_DISABLED_BY_DEFAULT}; +// When enabled and user is signed in, a footer indicating user's e-mail address +// and profile picture will appear at the bottom of SaveCardInfoBar. +const base::Feature kAutofillEnableSaveCardInfoBarAccountIndicationFooter{ + "AutofillEnableSaveCardInfoBarAccountIndicationFooter", + base::FEATURE_DISABLED_BY_DEFAULT}; + // When enabled, all payments related bubbles will not be dismissed upon page // navigation. const base::Feature kAutofillEnableStickyPaymentsBubble{
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index 29ab241..4cadf542 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -30,6 +30,8 @@ extern const base::Feature kAutofillEnableFixedPaymentsBubbleLogging; extern const base::Feature kAutofillEnableGoogleIssuedCard; extern const base::Feature kAutofillEnableOffersInDownstream; +extern const base::Feature + kAutofillEnableSaveCardInfoBarAccountIndicationFooter; extern const base::Feature kAutofillEnableStickyPaymentsBubble; extern const base::Feature kAutofillEnableToolbarStatusChip; extern const base::Feature kAutofillEnableVirtualCard;
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn index 52a8f4c62..1b06c8d 100644 --- a/components/autofill_assistant/browser/BUILD.gn +++ b/components/autofill_assistant/browser/BUILD.gn
@@ -205,6 +205,8 @@ "value_util.cc", "value_util.h", "viewport_mode.h", + "web/check_on_top_worker.cc", + "web/check_on_top_worker.h", "web/element_finder.cc", "web/element_finder.h", "web/element_position_getter.cc",
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h index c608a4eb..bb4265ab 100644 --- a/components/autofill_assistant/browser/actions/action_delegate.h +++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -102,6 +102,11 @@ virtual void FindElement(const Selector&, ElementFinder::Callback callback) const = 0; + // Find all elements matching |selector|. If there are no matches, the status + // will be ELEMENT_RESOLUTION_FAILED. + virtual void FindAllElements(const Selector& selector, + ElementFinder::Callback callback) const = 0; + // Click or tap the |element|. virtual void ClickOrTapElement( ClickType click_type, @@ -292,6 +297,13 @@ base::OnceCallback<void(const ClientStatus&, const std::string&)> callback) = 0; + // Return the outerHTML of each element in |elements|. |elements| must contain + // the object ID of a JS array containing the elements. + virtual void GetOuterHtmls( + const ElementFinder::Result& elements, + base::OnceCallback<void(const ClientStatus&, + const std::vector<std::string>&)> callback) = 0; + // Return the tag of the |element|. In case of an error, returns an empty // string. virtual void GetElementTag(
diff --git a/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc b/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc index ac0136f..60afcf9 100644 --- a/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc
@@ -17,6 +17,7 @@ #include "components/autofill_assistant/browser/actions/mock_action_delegate.h" #include "components/autofill_assistant/browser/mock_personal_data_manager.h" #include "components/autofill_assistant/browser/mock_website_login_manager.h" +#include "components/autofill_assistant/browser/test_util.h" #include "components/autofill_assistant/browser/user_model.h" #include "components/strings/grit/components_strings.h" #include "content/public/test/test_renderer_host.h" @@ -41,13 +42,6 @@ proto->set_day(day); } -MATCHER_P(EqualsProto, message, "") { - std::string expected_serialized, actual_serialized; - message.SerializeToString(&expected_serialized); - arg.SerializeToString(&actual_serialized); - return expected_serialized == actual_serialized; -} - using ::base::test::RunOnceCallback; using ::testing::_; using ::testing::ElementsAre; @@ -1189,14 +1183,14 @@ Property(&ProcessedActionProto::status, ACTION_APPLIED), Property(&ProcessedActionProto::collect_user_data_result, Property(&CollectUserDataResultProto::date_range_start_date, - EqualsProto(actual_pickup_date))), + Eq(actual_pickup_date))), Property( &ProcessedActionProto::collect_user_data_result, Property(&CollectUserDataResultProto::date_range_start_timeslot, Eq(actual_pickup_time))), Property(&ProcessedActionProto::collect_user_data_result, Property(&CollectUserDataResultProto::date_range_end_date, - EqualsProto(actual_return_date))), + Eq(actual_return_date))), Property( &ProcessedActionProto::collect_user_data_result, Property(&CollectUserDataResultProto::date_range_end_timeslot,
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h index 8ea81950..e465ff1 100644 --- a/components/autofill_assistant/browser/actions/mock_action_delegate.h +++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -73,6 +73,10 @@ MOCK_CONST_METHOD2(FindElement, void(const Selector& selector, ElementFinder::Callback)); + MOCK_CONST_METHOD2(FindAllElements, + void(const Selector& selector, + ElementFinder::Callback callback)); + MOCK_METHOD3(ClickOrTapElement, void(ClickType click_type, const ElementFinder::Result& element, @@ -239,6 +243,12 @@ base::OnceCallback<void(const ClientStatus&, const std::string&)> callback)); + MOCK_METHOD2( + GetOuterHtmls, + void(const ElementFinder::Result& elements, + base::OnceCallback<void(const ClientStatus&, + const std::vector<std::string>&)> callback)); + MOCK_METHOD2(GetElementTag, void(const ElementFinder::Result& element, base::OnceCallback<void(const ClientStatus&,
diff --git a/components/autofill_assistant/browser/actions/upload_dom_action.cc b/components/autofill_assistant/browser/actions/upload_dom_action.cc index 5b660cb..43552a8 100644 --- a/components/autofill_assistant/browser/actions/upload_dom_action.cc +++ b/components/autofill_assistant/browser/actions/upload_dom_action.cc
@@ -33,19 +33,34 @@ } delegate_->ShortWaitForElement( selector, - base::BindOnce(&UploadDomAction::OnWaitForElementTimed, - weak_ptr_factory_.GetWeakPtr(), - base::BindOnce(&UploadDomAction::OnWaitForElement, - weak_ptr_factory_.GetWeakPtr(), selector))); + base::BindOnce( + &UploadDomAction::OnWaitForElementTimed, + weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&UploadDomAction::OnWaitForElement, + weak_ptr_factory_.GetWeakPtr(), selector, + proto_.upload_dom().can_match_multiple_elements()))); } void UploadDomAction::OnWaitForElement(const Selector& selector, + bool can_match_multiple_elements, const ClientStatus& element_status) { if (!element_status.ok()) { EndAction(element_status); return; } + if (can_match_multiple_elements) { + delegate_->FindAllElements( + selector, + base::BindOnce(&action_delegate_util::TakeElementAndGetProperty< + std::vector<std::string>>, + base::BindOnce(&ActionDelegate::GetOuterHtmls, + delegate_->GetWeakPtr()), + base::BindOnce(&UploadDomAction::OnGetOuterHtmls, + weak_ptr_factory_.GetWeakPtr()))); + return; + } + delegate_->FindElement( selector, base::BindOnce( @@ -59,11 +74,25 @@ void UploadDomAction::OnGetOuterHtml(const ClientStatus& status, const std::string& outer_html) { if (status.ok()) { - processed_action_proto_->set_html_source(outer_html); + processed_action_proto_->mutable_upload_dom_result()->add_outer_htmls( + outer_html); } EndAction(status); } +void UploadDomAction::OnGetOuterHtmls( + const ClientStatus& status, + const std::vector<std::string>& outer_htmls) { + if (status.ok()) { + auto* result = processed_action_proto_->mutable_upload_dom_result(); + for (const auto& outer_html : outer_htmls) { + result->add_outer_htmls(outer_html); + } + } + + EndAction(status); +} + void UploadDomAction::EndAction(const ClientStatus& status) { UpdateProcessedAction(status); std::move(process_action_callback_).Run(std::move(processed_action_proto_));
diff --git a/components/autofill_assistant/browser/actions/upload_dom_action.h b/components/autofill_assistant/browser/actions/upload_dom_action.h index adc1961..9e42b9a5 100644 --- a/components/autofill_assistant/browser/actions/upload_dom_action.h +++ b/components/autofill_assistant/browser/actions/upload_dom_action.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "components/autofill_assistant/browser/actions/action.h" +#include "components/autofill_assistant/browser/web/element_finder.h" namespace autofill_assistant { @@ -24,9 +25,12 @@ void InternalProcessAction(ProcessActionCallback callback) override; void OnWaitForElement(const Selector& selector, + bool can_match_multiple_elements, const ClientStatus& element_status); void OnGetOuterHtml(const ClientStatus& status, const std::string& outer_html); + void OnGetOuterHtmls(const ClientStatus& status, + const std::vector<std::string>& outer_htmls); void EndAction(const ClientStatus& status); ProcessActionCallback process_action_callback_;
diff --git a/components/autofill_assistant/browser/actions/upload_dom_action_unittest.cc b/components/autofill_assistant/browser/actions/upload_dom_action_unittest.cc index dbf87d1f..352f0ed 100644 --- a/components/autofill_assistant/browser/actions/upload_dom_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/upload_dom_action_unittest.cc
@@ -10,6 +10,7 @@ #include "components/autofill_assistant/browser/actions/mock_action_delegate.h" #include "components/autofill_assistant/browser/selector.h" #include "components/autofill_assistant/browser/service.pb.h" +#include "components/autofill_assistant/browser/test_util.h" #include "testing/gmock/include/gmock/gmock.h" namespace autofill_assistant { @@ -18,6 +19,7 @@ using ::base::test::RunOnceCallback; using ::testing::_; using ::testing::AllOf; +using ::testing::Eq; using ::testing::InSequence; using ::testing::Pointee; using ::testing::Property; @@ -36,6 +38,15 @@ action.ProcessAction(callback_.Get()); } + UploadDomProto::Result UploadDomResult( + const std::vector<std::string>& outer_htmls) { + UploadDomProto::Result result; + for (const auto& outer_html : outer_htmls) { + result.add_outer_htmls(outer_html); + } + return result; + } + MockActionDelegate mock_action_delegate_; base::MockCallback<Action::ProcessActionCallback> callback_; UploadDomProto proto_; @@ -61,7 +72,8 @@ EXPECT_CALL( callback_, Run(Pointee(AllOf(Property(&ProcessedActionProto::status, TIMED_OUT), - Property(&ProcessedActionProto::html_source, ""))))); + Property(&ProcessedActionProto::upload_dom_result, + Eq(UploadDomResult({}))))))); Run(); } @@ -82,9 +94,9 @@ EXPECT_CALL( callback_, - Run(Pointee(AllOf( - Property(&ProcessedActionProto::status, ACTION_APPLIED), - Property(&ProcessedActionProto::html_source, "<html></html>"))))); + Run(Pointee(AllOf(Property(&ProcessedActionProto::status, ACTION_APPLIED), + Property(&ProcessedActionProto::upload_dom_result, + Eq(UploadDomResult({"<html></html>"}))))))); Run(); } @@ -109,7 +121,43 @@ callback_, Run(Pointee(AllOf( Property(&ProcessedActionProto::status, ELEMENT_RESOLUTION_FAILED), - Property(&ProcessedActionProto::html_source, ""))))); + Property(&ProcessedActionProto::upload_dom_result, + Eq(UploadDomResult({}))))))); + Run(); +} + +TEST_F(UploadDomActionTest, MultipleDomUpload) { + InSequence sequence; + + Selector selector({"#element"}); + *proto_.mutable_tree_root() = selector.proto; + proto_.set_can_match_multiple_elements(true); + + EXPECT_CALL(mock_action_delegate_, OnShortWaitForElement(selector, _)) + .WillOnce(RunOnceCallback<1>(OkClientStatus(), + base::TimeDelta::FromSeconds(0))); + + EXPECT_CALL(mock_action_delegate_, FindAllElements(selector, _)) + .WillOnce(testing::WithArgs<1>([](auto&& callback) { + auto element_result = std::make_unique<ElementFinder::Result>(); + element_result->object_id = "fake_object_id"; + std::move(callback).Run(OkClientStatus(), std::move(element_result)); + })); + + ElementFinder::Result expected_result; + expected_result.object_id = "fake_object_id"; + + std::vector<std::string> fake_htmls{"<div></div>", "<span></span>"}; + EXPECT_CALL(mock_action_delegate_, + GetOuterHtmls(EqualsElement(expected_result), _)) + .WillOnce(RunOnceCallback<1>(OkClientStatus(), fake_htmls)); + + EXPECT_CALL( + callback_, + Run(Pointee(AllOf( + Property(&ProcessedActionProto::status, ACTION_APPLIED), + Property(&ProcessedActionProto::upload_dom_result, + Eq(UploadDomResult({"<div></div>", "<span></span>"}))))))); Run(); }
diff --git a/components/autofill_assistant/browser/features.cc b/components/autofill_assistant/browser/features.cc index 795cdca..899f459 100644 --- a/components/autofill_assistant/browser/features.cc +++ b/components/autofill_assistant/browser/features.cc
@@ -19,6 +19,9 @@ const base::Feature kAutofillAssistantDirectActions{ "AutofillAssistantDirectActions", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kAutofillAssistantProactiveHelp{ + "AutofillAssistantProactiveHelp", base::FEATURE_DISABLED_BY_DEFAULT}; + // Use Chrome's TabHelper system to deal with the life cycle of WebContent's // depending Autofill Assistant objects. const base::Feature kAutofillAssistantWithTabHelper{
diff --git a/components/autofill_assistant/browser/features.h b/components/autofill_assistant/browser/features.h index 0c2f5e19..d8cd5cb 100644 --- a/components/autofill_assistant/browser/features.h +++ b/components/autofill_assistant/browser/features.h
@@ -16,6 +16,7 @@ extern const base::Feature kAutofillAssistant; extern const base::Feature kAutofillAssistantChromeEntry; extern const base::Feature kAutofillAssistantDirectActions; +extern const base::Feature kAutofillAssistantProactiveHelp; extern const base::Feature kAutofillAssistantWithTabHelper; } // namespace features
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc index 55f6afb..5c3e348 100644 --- a/components/autofill_assistant/browser/script_executor.cc +++ b/components/autofill_assistant/browser/script_executor.cc
@@ -321,6 +321,13 @@ std::move(callback)); } +void ScriptExecutor::FindAllElements(const Selector& selector, + ElementFinder::Callback callback) const { + DCHECK(!selector.empty()); + VLOG(3) << __func__ << " " << selector; + delegate_->GetWebController()->FindAllElements(selector, std::move(callback)); +} + void ScriptExecutor::WaitForDocumentToBecomeInteractive( const ElementFinder::Result& element, base::OnceCallback<void(const ClientStatus&)> callback) { @@ -653,6 +660,13 @@ delegate_->GetWebController()->GetOuterHtml(element, std::move(callback)); } +void ScriptExecutor::GetOuterHtmls( + const ElementFinder::Result& elements, + base::OnceCallback<void(const ClientStatus&, + const std::vector<std::string>&)> callback) { + delegate_->GetWebController()->GetOuterHtmls(elements, std::move(callback)); +} + void ScriptExecutor::GetElementTag( const ElementFinder::Result& element, base::OnceCallback<void(const ClientStatus&, const std::string&)>
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h index 5c15d8c7..9ce534b 100644 --- a/components/autofill_assistant/browser/script_executor.h +++ b/components/autofill_assistant/browser/script_executor.h
@@ -126,6 +126,8 @@ std::string GetBubbleMessage() override; void FindElement(const Selector& selector, ElementFinder::Callback callback) const override; + void FindAllElements(const Selector& selector, + ElementFinder::Callback callback) const override; void WaitForDocumentToBecomeInteractive( const ElementFinder::Result& element, base::OnceCallback<void(const ClientStatus&)> callback) override; @@ -222,6 +224,10 @@ const ElementFinder::Result& element, base::OnceCallback<void(const ClientStatus&, const std::string&)> callback) override; + void GetOuterHtmls(const ElementFinder::Result& elements, + base::OnceCallback<void(const ClientStatus&, + const std::vector<std::string>&)> + callback) override; void GetElementTag( const ElementFinder::Result& element, base::OnceCallback<void(const ClientStatus&, const std::string&)>
diff --git a/components/autofill_assistant/browser/selector.cc b/components/autofill_assistant/browser/selector.cc index dcd4584..72652c7 100644 --- a/components/autofill_assistant/browser/selector.cc +++ b/components/autofill_assistant/browser/selector.cc
@@ -70,6 +70,9 @@ b.on_top().accept_element_if_not_in_view()); case SelectorProto::Filter::kBoundingBox: + return a.bounding_box().require_nonempty() < + b.bounding_box().require_nonempty(); + case SelectorProto::Filter::kEnterFrame: case SelectorProto::Filter::kLabelled: return false; @@ -351,7 +354,11 @@ return out; case SelectorProto::Filter::kBoundingBox: - out << "bounding_box"; + if (f.bounding_box().require_nonempty()) { + out << "bounding_box (nonempty)"; + } else { + out << "bounding_box (any)"; + } return out; case SelectorProto::Filter::kNthMatch:
diff --git a/components/autofill_assistant/browser/selector_unittest.cc b/components/autofill_assistant/browser/selector_unittest.cc index 2d7bc09..7e8f184 100644 --- a/components/autofill_assistant/browser/selector_unittest.cc +++ b/components/autofill_assistant/browser/selector_unittest.cc
@@ -76,6 +76,25 @@ Selector({"a"}).MustBeVisible()); } +TEST(SelectorTest, Comparison_NonEmptyBoundingBox) { + Selector has_bounding_box_default = Selector({"a"}); + has_bounding_box_default.proto.add_filters()->mutable_bounding_box(); + + Selector has_bounding_box_explicit = Selector({"a"}); + has_bounding_box_explicit.proto.add_filters() + ->mutable_bounding_box() + ->set_require_nonempty(false); + + Selector has_nonempty_bounding_box = Selector({"a"}); + has_nonempty_bounding_box.proto.add_filters() + ->mutable_bounding_box() + ->set_require_nonempty(true); + + EXPECT_FALSE(has_bounding_box_default == has_nonempty_bounding_box); + EXPECT_FALSE(has_bounding_box_explicit == has_nonempty_bounding_box); + EXPECT_TRUE(has_bounding_box_default == has_bounding_box_explicit); +} + TEST(SelectorTest, Comparison_InnerText) { EXPECT_FALSE(Selector({"a"}).MatchingInnerText("a") == Selector({"a"}).MatchingInnerText("b"));
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 00e12c2..fad683b 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -701,7 +701,6 @@ oneof result_data { PromptProto.Result prompt_choice = 5; - string html_source = 12; // Should be set as a result of CollectUserDataAction. CollectUserDataResultProto collect_user_data_result = 15; // Should be set as a result of SetFormFieldValueAction. @@ -715,6 +714,8 @@ ShowGenericUiProto.Result show_generic_ui_result = 28; // Should be set as a result of GetElementStatusProto. GetElementStatusProto.Result get_element_status_result = 31; + // Should be set as a result of UploadDomProto. + UploadDomProto.Result upload_dom_result = 33; } // Reports information about navigation that happened while @@ -733,7 +734,7 @@ // selecting a chip on the UI. This is meant for monitoring and debugging. optional bool direct_action = 24; - reserved 3, 4, 6 to 11, 13, 14, 16, 18, 26, 27, 29, 30; + reserved 3, 4, 6 to 14, 16, 18, 26, 27, 29, 30; } // Extended information about the action status, which provides more details @@ -1002,7 +1003,7 @@ // // This is the equivalent of the old MUST_BE_VISIBLE flag. It's been // renamed as having a bounding box is not enough to imply visibility. - EmptyFilter bounding_box = 6; + BoundingBoxFilter bounding_box = 6; // Take the nth match. Fails with ELEMENT_RESOLUTION_FAILED if there are // not enough matches. @@ -1196,6 +1197,16 @@ optional int32 max_pairs = 5 [default = 50]; } + // Only keep elements that have a bounding box. + message BoundingBoxFilter { + // If require_nonempty=false, which is the default, require elements to have + // at least one bounding rect returned by Element.getClientRects() + // + // If require_nonempty=true, additionally require the element's bounding + // client rect to have a nonzero width and height. + optional bool require_nonempty = 1; + } + // Filter out elements covered by other elements, such as overlays. message OnTopFilter { // If true, scroll the element into view before checking whether @@ -1511,9 +1522,18 @@ // Volatile upload of a portion of the dom for backend analysis, does not store // anything. message UploadDomProto { + message Result { + // The outer HTML of the element(s) matched by |tree_root|. + repeated string outer_htmls = 1; + } + // The element that should be a root of uploaded DOM. If empty then the whole // page is returned. optional SelectorProto tree_root = 1; + + // Whether |tree_root| can match multiple elements. If false and multiple + // elements are matched, this action will fail with TOO_MANY_MATCHES. + optional bool can_match_multiple_elements = 2; } // Shows the progress bar.
diff --git a/components/autofill_assistant/browser/service/lite_service_util_unittest.cc b/components/autofill_assistant/browser/service/lite_service_util_unittest.cc index d2b8ec6..594796a8 100644 --- a/components/autofill_assistant/browser/service/lite_service_util_unittest.cc +++ b/components/autofill_assistant/browser/service/lite_service_util_unittest.cc
@@ -137,7 +137,7 @@ proto.set_status(ACTION_APPLIED); EXPECT_EQ(GetActionResponseType(proto), ActionResponseType::UNKNOWN); - proto.mutable_html_source(); + proto.mutable_upload_dom_result(); EXPECT_EQ(GetActionResponseType(proto), ActionResponseType::UNKNOWN); proto.mutable_collect_user_data_result(); EXPECT_EQ(GetActionResponseType(proto), ActionResponseType::UNKNOWN);
diff --git a/components/autofill_assistant/browser/web/check_on_top_worker.cc b/components/autofill_assistant/browser/web/check_on_top_worker.cc new file mode 100644 index 0000000..e6210dd --- /dev/null +++ b/components/autofill_assistant/browser/web/check_on_top_worker.cc
@@ -0,0 +1,96 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill_assistant/browser/web/check_on_top_worker.h" + +#include "base/logging.h" +#include "components/autofill_assistant/browser/web/web_controller_util.h" + +namespace autofill_assistant { + +CheckOnTopWorker::CheckOnTopWorker(DevtoolsClient* devtools_client) + : devtools_client_(devtools_client) {} + +CheckOnTopWorker::~CheckOnTopWorker() {} + +void CheckOnTopWorker::Start(const ElementFinder::Result& element, + Callback callback) { + callback_ = std::move(callback); + + // Each containing iframe must be checked to detect the case where an iframe + // element is covered by another element. The snippets might be run in + // parallel, if iframes run in different JavaScript contexts. + + JsSnippet js_snippet; + js_snippet.AddLine("function(element) {"); + AddReturnIfOnTop(&js_snippet, "element", + /* on_top= */ "true", + /* not_on_top= */ "false", + /* not_in_view= */ "false"); + js_snippet.AddLine("}"); + std::string function = js_snippet.ToString(); + + pending_result_count_ = element.frame_stack.size() + 1; + for (const auto& frame : element.frame_stack) { + CallFunctionOn(function, frame.node_frame_id, frame.object_id); + } + CallFunctionOn(function, element.node_frame_id, element.object_id); +} + +void CheckOnTopWorker::CallFunctionOn(const std::string& function, + const std::string& frame_id, + const std::string& object_id) { + std::vector<std::unique_ptr<runtime::CallArgument>> arguments; + AddRuntimeCallArgumentObjectId(object_id, &arguments); + devtools_client_->GetRuntime()->CallFunctionOn( + runtime::CallFunctionOnParams::Builder() + .SetObjectId(object_id) + .SetArguments(std::move(arguments)) + .SetFunctionDeclaration(function) + .SetReturnByValue(true) + .Build(), + frame_id, + base::BindOnce(&CheckOnTopWorker::OnReply, + weak_ptr_factory_.GetWeakPtr())); +} + +void CheckOnTopWorker::OnReply( + const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<runtime::CallFunctionOnResult> result) { + if (!callback_) { + // Already answered. + return; + } + + ClientStatus status = + CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__); + if (!status.ok()) { + VLOG(1) << __func__ << " Failed JavaScript with status: " << status; + std::move(callback_).Run(status); + return; + } + + bool onTop = false; + if (!SafeGetBool(result->GetResult(), &onTop)) { + VLOG(1) << __func__ << " JavaScript function failed to return a boolean."; + std::move(callback_).Run(UnexpectedErrorStatus(__FILE__, __LINE__)); + return; + } + + if (!onTop) { + std::move(callback_).Run(ClientStatus(ELEMENT_NOT_ON_TOP)); + return; + } + + if (pending_result_count_ == 1) { + std::move(callback_).Run(OkClientStatus()); + return; + } + + // Wait for a result from other frames. + DCHECK_GT(pending_result_count_, 1u); + pending_result_count_--; +} + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/web/check_on_top_worker.h b/components/autofill_assistant/browser/web/check_on_top_worker.h new file mode 100644 index 0000000..f133f0a --- /dev/null +++ b/components/autofill_assistant/browser/web/check_on_top_worker.h
@@ -0,0 +1,53 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_WEB_CHECK_ON_TOP_WORKER_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_WEB_CHECK_ON_TOP_WORKER_H_ + +#include <memory> +#include <vector> + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "components/autofill_assistant/browser/client_status.h" +#include "components/autofill_assistant/browser/devtools/devtools/domains/types_runtime.h" +#include "components/autofill_assistant/browser/devtools/devtools_client.h" +#include "components/autofill_assistant/browser/web/element_finder.h" +#include "components/autofill_assistant/browser/web/web_controller_worker.h" + +namespace autofill_assistant { + +// Worker class to check whether an element is on top, in all frames. +class CheckOnTopWorker : public WebControllerWorker { + public: + // |devtools_client| must be valid for the lifetime of the instance. + CheckOnTopWorker(DevtoolsClient* devtools_client); + ~CheckOnTopWorker() override; + + // Callback called when the worker is done. + using Callback = base::OnceCallback<void(const ClientStatus&)>; + + // Have the worker check |element| and report the result to |callback|. + void Start(const ElementFinder::Result& element, Callback callback); + + private: + void CallFunctionOn(const std::string& function, + const std::string& frame_id, + const std::string& object_id); + void OnReply(const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<runtime::CallFunctionOnResult> result); + + DevtoolsClient* const devtools_client_; + Callback callback_; + + // The number of successful results that are still expected before the check + // can be reported as successful. Note that an unsuccessful result is reported + // right away. + size_t pending_result_count_; + + base::WeakPtrFactory<CheckOnTopWorker> weak_ptr_factory_{this}; +}; +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_WEB_CHECK_ON_TOP_WORKER_H_
diff --git a/components/autofill_assistant/browser/web/element_finder.cc b/components/autofill_assistant/browser/web/element_finder.cc index da56607..7c4464a 100644 --- a/components/autofill_assistant/browser/web/element_finder.cc +++ b/components/autofill_assistant/browser/web/element_finder.cc
@@ -128,8 +128,16 @@ return true; case SelectorProto::Filter::kBoundingBox: - AddLine( - "elements = elements.filter((e) => e.getClientRects().length > 0);"); + if (filter.bounding_box().require_nonempty()) { + AddLine("elements = elements.filter((e) => {"); + AddLine(" const rect = e.getBoundingClientRect();"); + AddLine(" return rect.width != 0 && rect.height != 0;"); + AddLine("});"); + } else { + AddLine( + "elements = elements.filter((e) => e.getClientRects().length > " + "0);"); + } return true; case SelectorProto::Filter::kPseudoElementContent: {
diff --git a/components/autofill_assistant/browser/web/web_controller.cc b/components/autofill_assistant/browser/web/web_controller.cc index bdacd7f..8c32555 100644 --- a/components/autofill_assistant/browser/web/web_controller.cc +++ b/components/autofill_assistant/browser/web/web_controller.cc
@@ -160,6 +160,10 @@ const char* const kGetOuterHtmlScript = "function () { return this.outerHTML; }"; +// Javascript code to get the outerHTML of each node in a list. +const char* const kGetOuterHtmlsScript = + "function () { return this.map((e) => e.outerHTML); }"; + const char* const kGetElementTagScript = "function () { return this.tagName; }"; // Javascript code to query whether the document is ready for interact. @@ -347,6 +351,49 @@ std::move(callback).Run(status, value); } +void WebController::OnJavaScriptResultForStringArray( + base::OnceCallback<void(const ClientStatus&, + const std::vector<std::string>&)> callback, + const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<runtime::CallFunctionOnResult> result) { + ClientStatus status = + CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__); + if (!status.ok()) { + VLOG(1) << __func__ << "Failed JavaScript with status: " << status; + std::move(callback).Run(status, {}); + return; + } + + auto* remote_object = result->GetResult(); + if (!remote_object || !remote_object->HasValue() || + !remote_object->GetValue()->is_list()) { + VLOG(1) << __func__ << "JavaScript result is not an array."; + std::move(callback).Run( + JavaScriptErrorStatus(reply_status, __FILE__, __LINE__, + /* exception= */ nullptr), + {}); + return; + } + + auto values = remote_object->GetValue()->GetList(); + std::vector<std::string> v; + for (const base::Value& value : values) { + if (!value.is_string()) { + VLOG(1) << __func__ + << "JavaScript array content is not a string: " << value.type(); + std::move(callback).Run( + JavaScriptErrorStatus(reply_status, __FILE__, __LINE__, + /* exception= */ nullptr), + {}); + return; + } + + v.push_back(value.GetString()); + } + + std::move(callback).Run(status, v); +} + void WebController::ScrollIntoView( const ElementFinder::Result& element, base::OnceCallback<void(const ClientStatus&)> callback) { @@ -444,51 +491,28 @@ void WebController::CheckOnTop( const ElementFinder::Result& element, base::OnceCallback<void(const ClientStatus&)> callback) { - JsSnippet js_snippet; - js_snippet.AddLine("function(element) {"); - AddReturnIfOnTop(&js_snippet, "element", - /* on_top= */ "true", - /* not_on_top= */ "false", - /* not_in_view= */ "false"); - js_snippet.AddLine("}"); - - std::vector<std::unique_ptr<runtime::CallArgument>> arguments; - AddRuntimeCallArgumentObjectId(element.object_id, &arguments); - devtools_client_->GetRuntime()->CallFunctionOn( - runtime::CallFunctionOnParams::Builder() - .SetObjectId(element.object_id) - .SetArguments(std::move(arguments)) - .SetFunctionDeclaration(js_snippet.ToString()) - .SetReturnByValue(true) - .Build(), - element.node_frame_id, - base::BindOnce(&WebController::OnCheckOnTop, - weak_ptr_factory_.GetWeakPtr(), - base::BindOnce(&DecorateWebControllerStatus, - WebControllerErrorInfoProto::ON_TOP, - std::move(callback)))); + auto worker = std::make_unique<CheckOnTopWorker>(devtools_client_.get()); + auto* ptr = worker.get(); + pending_workers_.emplace_back(std::move(worker)); + ptr->Start(element, + base::BindOnce(&WebController::OnCheckOnTop, + weak_ptr_factory_.GetWeakPtr(), ptr, + base::BindOnce(&DecorateWebControllerStatus, + WebControllerErrorInfoProto::ON_TOP, + std::move(callback)))); } void WebController::OnCheckOnTop( + CheckOnTopWorker* worker_to_release, base::OnceCallback<void(const ClientStatus&)> callback, - const DevtoolsClient::ReplyStatus& reply_status, - std::unique_ptr<runtime::CallFunctionOnResult> result) { - ClientStatus status = - CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__); + const ClientStatus& status) { + base::EraseIf(pending_workers_, [worker_to_release](const auto& worker) { + return worker.get() == worker_to_release; + }); if (!status.ok()) { - VLOG(1) << __func__ << " Failed JavaScript with status: " << status; - std::move(callback).Run(status); - return; + VLOG(1) << __func__ << " Element is not on top: " << status; } - - bool onTop = false; - if (!SafeGetBool(result->GetResult(), &onTop)) { - VLOG(1) << __func__ << " JavaScript function failed to return a boolean."; - std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__)); - return; - } - std::move(callback).Run( - ClientStatus(onTop ? ACTION_APPLIED : ELEMENT_NOT_ON_TOP)); + std::move(callback).Run(status); } void WebController::WaitUntilElementIsStable( @@ -766,10 +790,24 @@ void WebController::FindElement(const Selector& selector, bool strict_mode, ElementFinder::Callback callback) { + RunElementFinder(selector, + strict_mode ? ElementFinder::ResultType::kExactlyOneMatch + : ElementFinder::ResultType::kAnyMatch, + std::move(callback)); +} + +void WebController::FindAllElements(const Selector& selector, + ElementFinder::Callback callback) { + RunElementFinder(selector, ElementFinder::ResultType::kMatchArray, + std::move(callback)); +} + +void WebController::RunElementFinder(const Selector& selector, + ElementFinder::ResultType result_type, + ElementFinder::Callback callback) { auto finder = std::make_unique<ElementFinder>( - web_contents_, devtools_client_.get(), selector, - strict_mode ? ElementFinder::ResultType::kExactlyOneMatch - : ElementFinder::ResultType::kAnyMatch); + web_contents_, devtools_client_.get(), selector, result_type); + auto* ptr = finder.get(); pending_workers_.emplace_back(std::move(finder)); ptr->Start(base::BindOnce(&WebController::OnFindElementResult, @@ -1407,6 +1445,26 @@ std::move(callback)))); } +void WebController::GetOuterHtmls( + const ElementFinder::Result& elements, + base::OnceCallback<void(const ClientStatus&, + const std::vector<std::string>&)> callback) { + devtools_client_->GetRuntime()->CallFunctionOn( + runtime::CallFunctionOnParams::Builder() + .SetObjectId(elements.object_id) + .SetFunctionDeclaration(std::string(kGetOuterHtmlsScript)) + .SetReturnByValue(true) + .Build(), + elements.node_frame_id, + base::BindOnce( + &WebController::OnJavaScriptResultForStringArray, + weak_ptr_factory_.GetWeakPtr(), + base::BindOnce( + &DecorateControllerStatusWithValue<std::vector<std::string>>, + WebControllerErrorInfoProto::GET_OUTER_HTML, + std::move(callback)))); +} + void WebController::GetElementTag( const ElementFinder::Result& element, base::OnceCallback<void(const ClientStatus&, const std::string&)>
diff --git a/components/autofill_assistant/browser/web/web_controller.h b/components/autofill_assistant/browser/web/web_controller.h index 24682da..084fa49 100644 --- a/components/autofill_assistant/browser/web/web_controller.h +++ b/components/autofill_assistant/browser/web/web_controller.h
@@ -22,6 +22,7 @@ #include "components/autofill_assistant/browser/rectf.h" #include "components/autofill_assistant/browser/selector.h" #include "components/autofill_assistant/browser/top_padding.h" +#include "components/autofill_assistant/browser/web/check_on_top_worker.h" #include "components/autofill_assistant/browser/web/element_finder.h" #include "components/autofill_assistant/browser/web/element_position_getter.h" #include "components/autofill_assistant/browser/web/element_rect_getter.h" @@ -81,6 +82,11 @@ bool strict_mode, ElementFinder::Callback callback); + // Find all elements matching |selector|. If there are no matches, the status + // will be ELEMENT_RESOLUTION_FAILED. + virtual void FindAllElements(const Selector& selector, + ElementFinder::Callback callback); + // Scroll the |element| into view. virtual void ScrollIntoView( const ElementFinder::Result& element, @@ -213,6 +219,13 @@ base::OnceCallback<void(const ClientStatus&, const std::string&)> callback); + // Return the outerHTML of each element in |elements|. |elements| must contain + // the object ID of a JS array containing the elements. + virtual void GetOuterHtmls( + const ElementFinder::Result& elements, + base::OnceCallback<void(const ClientStatus&, + const std::vector<std::string>&)> callback); + // Return the tag of the |element|. In case of an error, will return an empty // string. virtual void GetElementTag( @@ -307,12 +320,17 @@ callback, const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<runtime::CallFunctionOnResult> result); + void OnJavaScriptResultForStringArray( + base::OnceCallback<void(const ClientStatus&, + const std::vector<std::string>&)> callback, + const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<runtime::CallFunctionOnResult> result); void OnWaitForDocumentToBecomeInteractive( base::OnceCallback<void(const ClientStatus&)> callback, bool result); - void OnCheckOnTop(base::OnceCallback<void(const ClientStatus&)> callback, - const DevtoolsClient::ReplyStatus& reply_status, - std::unique_ptr<runtime::CallFunctionOnResult> result); + void OnCheckOnTop(CheckOnTopWorker* worker, + base::OnceCallback<void(const ClientStatus&)> callback, + const ClientStatus& status); void OnWaitUntilElementIsStable( ElementPositionGetter* getter_to_release, base::OnceCallback<void(const ClientStatus&)> callback, @@ -347,6 +365,9 @@ base::OnceCallback<void(const ClientStatus&)> callback, const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<runtime::EvaluateResult> result); + void RunElementFinder(const Selector& selector, + ElementFinder::ResultType result_type, + ElementFinder::Callback callback); void OnFindElementResult(ElementFinder* finder_to_release, ElementFinder::Callback callback, const ClientStatus& status,
diff --git a/components/autofill_assistant/browser/web/web_controller_browsertest.cc b/components/autofill_assistant/browser/web/web_controller_browsertest.cc index ceeea88..2768cc9 100644 --- a/components/autofill_assistant/browser/web/web_controller_browsertest.cc +++ b/components/autofill_assistant/browser/web/web_controller_browsertest.cc
@@ -397,6 +397,46 @@ std::move(done_callback), result_output, html_output)); } + ClientStatus GetOuterHtmls(const Selector& selector, + std::vector<std::string>* htmls_output) { + base::RunLoop run_loop; + ClientStatus result; + + web_controller_->FindAllElements( + selector, base::BindOnce(&WebControllerBrowserTest::OnFindAllElements, + base::Unretained(this), run_loop.QuitClosure(), + &result, htmls_output)); + + run_loop.Run(); + return result; + } + + void OnFindAllElements(base::OnceClosure done_callback, + ClientStatus* client_status_output, + std::vector<std::string>* htmls_output, + const ClientStatus& client_status, + std::unique_ptr<ElementFinder::Result> elements) { + EXPECT_EQ(ACTION_APPLIED, client_status.proto_status()); + ASSERT_TRUE(elements); + + web_controller_->GetOuterHtmls( + *elements, base::BindOnce(&WebControllerBrowserTest::OnGetOuterHtmls, + base::Unretained(this), std::move(elements), + std::move(done_callback), + client_status_output, htmls_output)); + } + + void OnGetOuterHtmls(std::unique_ptr<ElementFinder::Result> elements, + base::OnceClosure done_callback, + ClientStatus* client_status_output, + std::vector<std::string>* htmls_output, + const ClientStatus& client_status, + const std::vector<std::string>& htmls) { + *client_status_output = client_status; + *htmls_output = htmls; + std::move(done_callback).Run(); + } + ClientStatus GetElementTag(const Selector& selector, std::string* element_tag_output) { base::RunLoop run_loop; @@ -875,6 +915,22 @@ )")); } + // Hide the overlay in the main page. + void HideOverlay() { + EXPECT_TRUE(ExecJs(shell(), + R"( +document.getElementById("overlay").style.visibility='hidden'; +)")); + } + + // Hide the overlay in the first iframe. + void HideOverlayInFrame() { + EXPECT_TRUE(ExecJs(shell()->web_contents()->GetAllFrames()[1], + R"( +document.getElementById("overlay_in_frame").style.visibility='hidden'; +)")); + } + // Make sure scrolling is necessary for #scroll_container , no matter the // screen height void SetupScrollContainerHeights() { @@ -1040,6 +1096,32 @@ true); } +IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, RequireNonemptyBoundingBox) { + Selector button = Selector({"#button"}); + button.proto.add_filters()->mutable_bounding_box()->set_require_nonempty( + true); + RunLaxElementCheck(button, true); + + Selector hidden = Selector({"#hidden"}); + RunLaxElementCheck(hidden, true); + hidden.proto.add_filters()->mutable_bounding_box()->set_require_nonempty( + true); + RunLaxElementCheck(hidden, false); + + Selector emptydiv = Selector({"#emptydiv"}); + RunLaxElementCheck(emptydiv, true); + auto* emptydiv_box = emptydiv.proto.add_filters()->mutable_bounding_box(); + emptydiv_box->set_require_nonempty(true); + RunLaxElementCheck(emptydiv, false); + emptydiv_box->set_require_nonempty(false); + RunLaxElementCheck(emptydiv, true); + + EXPECT_TRUE(content::ExecJs(shell(), R"( + document.getElementById("emptydiv").style.height = '100px'; +)")); + RunLaxElementCheck(emptydiv, true); +} + IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, MultipleVisibleElementCheck) { // both visible RunLaxElementCheck(Selector({"#button,#select"}).MustBeVisible(), true); @@ -1764,6 +1846,18 @@ EXPECT_EQ(R"(<div id="divToRemove">Text</div>)", html); } +IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, GetOuterHtmls) { + std::vector<std::string> htmls; + + Selector div_selector({".label"}); + ASSERT_EQ(ACTION_APPLIED, GetOuterHtmls(div_selector, &htmls).proto_status()); + + EXPECT_THAT(htmls, + testing::ElementsAre(R"(<div class="label">Label 1</div>)", + R"(<div class="label">Label 2</div>)", + R"(<div class="label">Label 3</div>)")); +} + IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, GetElementTag) { std::string element_tag; @@ -2497,6 +2591,32 @@ EXPECT_EQ(WebControllerErrorInfoProto::ON_TOP, status.details().web_controller_error_info().failed_web_action()); } + +IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, CheckOnTopInFrame) { + ClientStatus status; + ElementFinder::Result element; + FindElement(Selector({"#iframe", "#button"}), &status, &element); + ASSERT_TRUE(status.ok()); + + // Make sure the button is visible. + EXPECT_TRUE( + ExecJs(shell()->web_contents()->GetAllFrames()[1], + "document.getElementById('button').scrollIntoViewIfNeeded();")); + + // The button is covered by an overlay in the main frame + ShowOverlay(); + EXPECT_EQ(ELEMENT_NOT_ON_TOP, CheckOnTop(element).proto_status()); + + // The button is covered by an overlay in the iframe + HideOverlay(); + ShowOverlayInFrame(); + EXPECT_EQ(ELEMENT_NOT_ON_TOP, CheckOnTop(element).proto_status()); + + // The button is not covered by any overlay + HideOverlayInFrame(); + EXPECT_EQ(ACTION_APPLIED, CheckOnTop(element).proto_status()); +} + IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, NthMatch) { Selector selector; selector.proto.add_filters()->set_css_selector(".nth_match_parent");
diff --git a/components/background_sync/background_sync_controller_impl.cc b/components/background_sync/background_sync_controller_impl.cc index 6a27b39..040a8b6 100644 --- a/components/background_sync/background_sync_controller_impl.cc +++ b/components/background_sync/background_sync_controller_impl.cc
@@ -65,8 +65,7 @@ void BackgroundSyncControllerImpl::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (content_type != ContentSettingsType::BACKGROUND_SYNC &&
diff --git a/components/background_sync/background_sync_controller_impl.h b/components/background_sync/background_sync_controller_impl.h index 6dc98b8..d06e045 100644 --- a/components/background_sync/background_sync_controller_impl.h +++ b/components/background_sync/background_sync_controller_impl.h
@@ -108,8 +108,7 @@ // content_settings::Observer overrides. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; bool IsOriginTracked(const url::Origin& origin) { return periodic_sync_origins_.find(origin) != periodic_sync_origins_.end();
diff --git a/components/content_settings/browser/page_specific_content_settings.cc b/components/content_settings/browser/page_specific_content_settings.cc index e5692b40..bb09f509 100644 --- a/components/content_settings/browser/page_specific_content_settings.cc +++ b/components/content_settings/browser/page_specific_content_settings.cc
@@ -813,10 +813,9 @@ void PageSpecificContentSettings::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { const ContentSettingsDetails details(primary_pattern, secondary_pattern, - content_type, resource_identifier); + content_type, std::string()); if (!details.update_all() && // The visible URL is the URL in the URL field of a tab. // Currently this should be matched by the |primary_pattern|.
diff --git a/components/content_settings/browser/page_specific_content_settings.h b/components/content_settings/browser/page_specific_content_settings.h index 9b53a59b..aa99ebfa 100644 --- a/components/content_settings/browser/page_specific_content_settings.h +++ b/components/content_settings/browser/page_specific_content_settings.h
@@ -507,8 +507,7 @@ // content_settings::Observer implementation. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // Clears settings changed by the user via PageInfo since the last navigation. void ClearContentSettingsChangedViaPageInfo();
diff --git a/components/content_settings/core/browser/content_settings_observable_provider.cc b/components/content_settings/core/browser/content_settings_observable_provider.cc index b4a3621..18308ae 100644 --- a/components/content_settings/core/browser/content_settings_observable_provider.cc +++ b/components/content_settings/core/browser/content_settings_observable_provider.cc
@@ -31,7 +31,7 @@ const std::string& resource_identifier) { for (Observer& observer : observer_list_) { observer.OnContentSettingChanged(primary_pattern, secondary_pattern, - content_type, resource_identifier); + content_type); } }
diff --git a/components/content_settings/core/browser/content_settings_observer.h b/components/content_settings/core/browser/content_settings_observer.h index db53e74..569c3b3 100644 --- a/components/content_settings/core/browser/content_settings_observer.h +++ b/components/content_settings/core/browser/content_settings_observer.h
@@ -17,8 +17,7 @@ virtual void OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) = 0; + ContentSettingsType content_type) = 0; protected: virtual ~Observer() {}
diff --git a/components/content_settings/core/browser/cookie_settings.cc b/components/content_settings/core/browser/cookie_settings.cc index ded5212..4bbbc66 100644 --- a/components/content_settings/core/browser/cookie_settings.cc +++ b/components/content_settings/core/browser/cookie_settings.cc
@@ -257,8 +257,7 @@ void CookieSettings::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { if (content_type == ContentSettingsType::COOKIES) { for (auto& observer : observers_) observer.OnCookieSettingChanged();
diff --git a/components/content_settings/core/browser/cookie_settings.h b/components/content_settings/core/browser/cookie_settings.h index 3e55808..5e7d1b9 100644 --- a/components/content_settings/core/browser/cookie_settings.h +++ b/components/content_settings/core/browser/cookie_settings.h
@@ -165,8 +165,7 @@ // content_settings::Observer: void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; void OnCookiePreferencesChanged();
diff --git a/components/content_settings/core/browser/host_content_settings_map.cc b/components/content_settings/core/browser/host_content_settings_map.cc index db302e2..18dd5230 100644 --- a/components/content_settings/core/browser/host_content_settings_map.cc +++ b/components/content_settings/core/browser/host_content_settings_map.cc
@@ -315,7 +315,7 @@ #endif OnContentSettingChanged(ContentSettingsPattern(), ContentSettingsPattern(), - ContentSettingsType::DEFAULT, std::string()); + ContentSettingsType::DEFAULT); } ContentSetting HostContentSettingsMap::GetDefaultContentSettingFromProvider( @@ -787,11 +787,10 @@ void HostContentSettingsMap::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { for (content_settings::Observer& observer : observers_) { observer.OnContentSettingChanged(primary_pattern, secondary_pattern, - content_type, std::string()); + content_type); } }
diff --git a/components/content_settings/core/browser/host_content_settings_map.h b/components/content_settings/core/browser/host_content_settings_map.h index 5493b86c..38bf582 100644 --- a/components/content_settings/core/browser/host_content_settings_map.h +++ b/components/content_settings/core/browser/host_content_settings_map.h
@@ -294,8 +294,7 @@ // content_settings::Observer implementation. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // Returns the ProviderType associated with the given source string. // TODO(estade): I regret adding this. At the moment there are no legitimate
diff --git a/components/drive/service/fake_drive_service_unittest.cc b/components/drive/service/fake_drive_service_unittest.cc index 97c745c..08dbfaed 100644 --- a/components/drive/service/fake_drive_service_unittest.cc +++ b/components/drive/service/fake_drive_service_unittest.cc
@@ -14,8 +14,8 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/hash/md5.h" +#include "base/ranges/algorithm.h" #include "base/run_loop.h" -#include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -1198,7 +1198,7 @@ ASSERT_TRUE(base::ReadFileToString(output_file_path, &content)); EXPECT_EQ("This is some test content.", content); ASSERT_TRUE(!download_progress_values.empty()); - EXPECT_TRUE(base::STLIsSorted(download_progress_values)); + EXPECT_TRUE(base::ranges::is_sorted(download_progress_values)); EXPECT_LE(0, download_progress_values.front().first); EXPECT_GE(26, download_progress_values.back().first); EXPECT_EQ(content, get_content_callback.GetConcatenatedData()); @@ -2034,7 +2034,7 @@ EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code); EXPECT_FALSE(entry); ASSERT_TRUE(!upload_progress_values.empty()); - EXPECT_TRUE(base::STLIsSorted(upload_progress_values)); + EXPECT_TRUE(base::ranges::is_sorted(upload_progress_values)); EXPECT_LE(0, upload_progress_values.front().first); EXPECT_GE(static_cast<int64_t>(contents.size() / 2), upload_progress_values.back().first); @@ -2053,7 +2053,7 @@ EXPECT_EQ(static_cast<int64_t>(contents.size()), entry->file_size()); EXPECT_TRUE(Exists(entry->file_id())); ASSERT_TRUE(!upload_progress_values.empty()); - EXPECT_TRUE(base::STLIsSorted(upload_progress_values)); + EXPECT_TRUE(base::ranges::is_sorted(upload_progress_values)); EXPECT_LE(0, upload_progress_values.front().first); EXPECT_GE(static_cast<int64_t>(contents.size() - contents.size() / 2), upload_progress_values.back().first); @@ -2096,7 +2096,7 @@ EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code); EXPECT_FALSE(entry); ASSERT_TRUE(!upload_progress_values.empty()); - EXPECT_TRUE(base::STLIsSorted(upload_progress_values)); + EXPECT_TRUE(base::ranges::is_sorted(upload_progress_values)); EXPECT_LE(0, upload_progress_values.front().first); EXPECT_GE(static_cast<int64_t>(contents.size() / 2), upload_progress_values.back().first); @@ -2115,7 +2115,7 @@ EXPECT_EQ(static_cast<int64_t>(contents.size()), entry->file_size()); EXPECT_TRUE(Exists(entry->file_id())); ASSERT_TRUE(!upload_progress_values.empty()); - EXPECT_TRUE(base::STLIsSorted(upload_progress_values)); + EXPECT_TRUE(base::ranges::is_sorted(upload_progress_values)); EXPECT_LE(0, upload_progress_values.front().first); EXPECT_GE(static_cast<int64_t>(contents.size() - contents.size() / 2), upload_progress_values.back().first);
diff --git a/components/exo/client_controlled_shell_surface.cc b/components/exo/client_controlled_shell_surface.cc index 48ac17e..842bf0dd 100644 --- a/components/exo/client_controlled_shell_surface.cc +++ b/components/exo/client_controlled_shell_surface.cc
@@ -744,8 +744,8 @@ ShellSurfaceBase::OnSetFrameColors(active_color, inactive_color); if (wide_frame_) { aura::Window* window = wide_frame_->GetWidget()->GetNativeWindow(); - window->SetProperty(ash::kFrameActiveColorKey, active_color); - window->SetProperty(ash::kFrameInactiveColorKey, inactive_color); + window->SetProperty(chromeos::kFrameActiveColorKey, active_color); + window->SetProperty(chromeos::kFrameInactiveColorKey, inactive_color); } }
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc index 797df9baef..7c4b1a5 100644 --- a/components/exo/shell_surface_base.cc +++ b/components/exo/shell_surface_base.cc
@@ -633,9 +633,9 @@ active_frame_color_ = SkColorSetA(active_color, SK_AlphaOPAQUE); inactive_frame_color_ = SkColorSetA(inactive_color, SK_AlphaOPAQUE); if (widget_) { - widget_->GetNativeWindow()->SetProperty(ash::kFrameActiveColorKey, + widget_->GetNativeWindow()->SetProperty(chromeos::kFrameActiveColorKey, active_frame_color_); - widget_->GetNativeWindow()->SetProperty(ash::kFrameInactiveColorKey, + widget_->GetNativeWindow()->SetProperty(chromeos::kFrameInactiveColorKey, inactive_frame_color_); } }
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java index 95fbd4f..80897ccf 100644 --- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java +++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
@@ -64,6 +64,7 @@ String PREVIEWS_OMNIBOX_UI_FEATURE = "IPH_PreviewsOmniboxUI"; String TRANSLATE_MENU_BUTTON_FEATURE = "IPH_TranslateMenuButton"; String EXPLORE_SITES_TILE_FEATURE = "IPH_ExploreSitesTile"; + String READ_LATER_CONTEXT_MENU_FEATURE = "IPH_ReadLaterContextMenu"; /** * An IPH feature that encourages users to get better translations by enabling access to page
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc index d62bc129..c9ca2cc 100644 --- a/components/feature_engagement/public/feature_constants.cc +++ b/components/feature_engagement/public/feature_constants.cc
@@ -75,6 +75,8 @@ "IPH_DownloadInfoBarDownloadsAreFaster", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHQuietNotificationPromptsFeature{ "IPH_QuietNotificationPrompts", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kIPHReadLaterContextMenuFeature{ + "IPH_ReadLaterContextMenu", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHEphemeralTabFeature{"IPH_EphemeralTab", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIPHFeedCardMenuFeature{"IPH_FeedCardMenu",
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h index 2a592ed..430dd77 100644 --- a/components/feature_engagement/public/feature_constants.h +++ b/components/feature_engagement/public/feature_constants.h
@@ -65,6 +65,7 @@ extern const base::Feature kIPHNewTabPageHomeButtonFeature; extern const base::Feature kIPHPreviewsOmniboxUIFeature; extern const base::Feature kIPHQuietNotificationPromptsFeature; +extern const base::Feature kIPHReadLaterContextMenuFeature; extern const base::Feature kIPHTabGroupsQuicklyComparePagesFeature; extern const base::Feature kIPHTabGroupsTapToSeeAnotherTabFeature; extern const base::Feature kIPHTabGroupsYourTabsAreTogetherFeature;
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc index 64897c6..7cb71bc 100644 --- a/components/feature_engagement/public/feature_list.cc +++ b/components/feature_engagement/public/feature_list.cc
@@ -49,6 +49,7 @@ &kIPHPreviewsOmniboxUIFeature, &kIPHPwaInstallAvailableFeature, &kIPHQuietNotificationPromptsFeature, + &kIPHReadLaterContextMenuFeature, &kIPHTabGroupsQuicklyComparePagesFeature, &kIPHTabGroupsTapToSeeAnotherTabFeature, &kIPHTabGroupsYourTabsAreTogetherFeature,
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h index 64dff4e..b5c166e 100644 --- a/components/feature_engagement/public/feature_list.h +++ b/components/feature_engagement/public/feature_list.h
@@ -99,6 +99,8 @@ "IPH_PwaInstallAvailableFeature"); DEFINE_VARIATION_PARAM(kIPHQuietNotificationPromptsFeature, "IPH_QuietNotificationPrompts"); +DEFINE_VARIATION_PARAM(kIPHReadLaterContextMenuFeature, + "IPH_ReadLaterContextMenu"); DEFINE_VARIATION_PARAM(kIPHTabGroupsQuicklyComparePagesFeature, "IPH_TabGroupsQuicklyComparePages"); DEFINE_VARIATION_PARAM(kIPHTabGroupsTapToSeeAnotherTabFeature, @@ -192,6 +194,7 @@ VARIATION_ENTRY(kIPHPreviewsOmniboxUIFeature), VARIATION_ENTRY(kIPHPwaInstallAvailableFeature), VARIATION_ENTRY(kIPHQuietNotificationPromptsFeature), + VARIATION_ENTRY(kIPHReadLaterContextMenuFeature), VARIATION_ENTRY(kIPHTabGroupsQuicklyComparePagesFeature), VARIATION_ENTRY(kIPHTabGroupsTapToSeeAnotherTabFeature), VARIATION_ENTRY(kIPHTabGroupsYourTabsAreTogetherFeature),
diff --git a/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarLayout.java b/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarLayout.java index 2f330b50..6685a32 100644 --- a/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarLayout.java +++ b/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarLayout.java
@@ -297,6 +297,13 @@ } /** + * Returns whether or not InfoBar has a footer. + */ + public boolean hasFooter() { + return mFooterViewGroup != null; + } + + /** * Returns the icon, or null if it doesn't exist. */ public ImageView getIcon() {
diff --git a/components/messages/android/java/res/layout/message_banner_view.xml b/components/messages/android/java/res/layout/message_banner_view.xml index 3306970..47d6a84 100644 --- a/components/messages/android/java/res/layout/message_banner_view.xml +++ b/components/messages/android/java/res/layout/message_banner_view.xml
@@ -73,17 +73,12 @@ android:layout_width="1dp" android:layout_height="match_parent" /> - <TextView - style="@style/TextAppearance.Button.Text.Blue" + <org.chromium.ui.widget.ButtonCompat + style="@style/TextButton" android:id="@+id/message_primary_button" - android:paddingStart="@dimen/message_button_padding" - android:paddingEnd="@dimen/message_button_padding" android:layout_weight="0" - android:gravity="center_vertical" - android:minWidth="@dimen/message_banner_button_min_width" - android:minHeight="@dimen/min_touch_target_size" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="center" - android:background="?attr/selectableItemBackground" /> + android:layout_gravity="center_vertical" + android:visibility="gone" /> </org.chromium.components.messages.MessageBannerView> \ No newline at end of file
diff --git a/components/messages/android/java/res/values/dimens.xml b/components/messages/android/java/res/values/dimens.xml index cc92061..42ab861f 100644 --- a/components/messages/android/java/res/values/dimens.xml +++ b/components/messages/android/java/res/values/dimens.xml
@@ -12,7 +12,6 @@ <!-- Min width to ensure the min touchable size. --> <dimen name="message_banner_button_min_width">12dp</dimen> <dimen name="message_icon_padding">12dp</dimen> - <dimen name="message_button_padding">16dp</dimen> <dimen name="message_divider_margin">12dp</dimen> <dimen name="message_shadow_top_margin">8dp</dimen> <dimen name="message_shadow_lateral_margin">12dp</dimen>
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageBannerView.java b/components/messages/android/java/src/org/chromium/components/messages/MessageBannerView.java index 8690acd..a749de02 100644 --- a/components/messages/android/java/src/org/chromium/components/messages/MessageBannerView.java +++ b/components/messages/android/java/src/org/chromium/components/messages/MessageBannerView.java
@@ -60,6 +60,7 @@ } void setPrimaryButtonText(String text) { + mPrimaryButton.setVisibility(VISIBLE); mPrimaryButton.setText(text); }
diff --git a/components/mirroring/service/rtp_stream_unittest.cc b/components/mirroring/service/rtp_stream_unittest.cc index 7395597..1231237 100644 --- a/components/mirroring/service/rtp_stream_unittest.cc +++ b/components/mirroring/service/rtp_stream_unittest.cc
@@ -92,7 +92,7 @@ auto video_sender = std::make_unique<media::cast::VideoSender>( cast_environment_, media::cast::GetDefaultVideoSenderConfig(), base::DoNothing(), base::DoNothing(), base::DoNothing(), &transport_, - base::DoNothing()); + base::DoNothing(), base::DoNothing()); VideoRtpStream video_stream(std::move(video_sender), client_.GetWeakPtr()); { base::RunLoop run_loop;
diff --git a/components/mirroring/service/session.cc b/components/mirroring/service/session.cc index 27624971..45fcad49 100644 --- a/components/mirroring/service/session.cc +++ b/components/mirroring/service/session.cc
@@ -771,6 +771,8 @@ weak_factory_.GetWeakPtr()), cast_transport_.get(), base::BindRepeating(&Session::SetTargetPlayoutDelay, + weak_factory_.GetWeakPtr()), + base::BindRepeating(&Session::ProcessFeedback, weak_factory_.GetWeakPtr())); video_stream_ = std::make_unique<VideoRtpStream>( std::move(video_sender), weak_factory_.GetWeakPtr()); @@ -834,6 +836,12 @@ video_stream_->SetTargetPlayoutDelay(playout_delay); } +void Session::ProcessFeedback(const media::VideoFrameFeedback& feedback) { + if (video_capture_client_) { + video_capture_client_->ProcessFeedback(feedback); + } +} + // TODO(issuetracker.google.com/159352836): Refactor to use libcast's // OFFER message format. void Session::CreateAndSendOffer() {
diff --git a/components/mirroring/service/session.h b/components/mirroring/service/session.h index 6231e73..63f7daf 100644 --- a/components/mirroring/service/session.h +++ b/components/mirroring/service/session.h
@@ -20,6 +20,7 @@ #include "components/mirroring/service/rtp_stream.h" #include "components/mirroring/service/wifi_status_monitor.h" #include "gpu/config/gpu_info.h" +#include "media/base/video_frame_feedback.h" #include "media/cast/cast_environment.h" #include "media/cast/net/cast_transport_defines.h" #include "media/mojo/mojom/video_encode_accelerator.mojom.h" @@ -141,6 +142,9 @@ // Callback by media::cast::VideoSender to set a new target playout delay. void SetTargetPlayoutDelay(base::TimeDelta playout_delay); + // Callback by media::cast::VideoSender to report resource utilization. + void ProcessFeedback(const media::VideoFrameFeedback& feedback); + media::VideoEncodeAccelerator::SupportedProfiles GetSupportedVeaProfiles(); // Create and send OFFER message.
diff --git a/components/mirroring/service/video_capture_client.cc b/components/mirroring/service/video_capture_client.cc index b5e59b6..3e9a265 100644 --- a/components/mirroring/service/video_capture_client.cc +++ b/components/mirroring/service/video_capture_client.cc
@@ -235,7 +235,7 @@ } frame->AddDestructionObserver( base::BindOnce(&VideoCaptureClient::DidFinishConsumingFrame, - frame->feedback(), std::move(buffer_finished_callback))); + std::move(buffer_finished_callback))); frame->set_metadata(info->metadata); if (info->color_space.has_value()) @@ -258,8 +258,7 @@ void VideoCaptureClient::OnClientBufferFinished( int buffer_id, - base::ReadOnlySharedMemoryMapping mapping, - media::VideoFrameFeedback feedback) { + base::ReadOnlySharedMemoryMapping mapping) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DVLOG(3) << __func__ << ": buffer_id=" << buffer_id; @@ -269,17 +268,23 @@ return; } - video_capture_host_->ReleaseBuffer(DeviceId(), buffer_id, feedback); + video_capture_host_->ReleaseBuffer(DeviceId(), buffer_id, feedback_); + feedback_ = media::VideoFrameFeedback(); } // static void VideoCaptureClient::DidFinishConsumingFrame( - const media::VideoFrameFeedback* feedback, BufferFinishedCallback callback) { // Note: This function may be called on any thread by the VideoFrame - // destructor. |feedback| is still valid for read-access at this point. + // destructor. DCHECK(!callback.is_null()); - std::move(callback).Run(*feedback); + std::move(callback).Run(); +} + +void VideoCaptureClient::ProcessFeedback( + const media::VideoFrameFeedback& feedback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + feedback_ = feedback; } } // namespace mirroring
diff --git a/components/mirroring/service/video_capture_client.h b/components/mirroring/service/video_capture_client.h index 35d0bc3..10bb39e 100644 --- a/components/mirroring/service/video_capture_client.h +++ b/components/mirroring/service/video_capture_client.h
@@ -48,6 +48,9 @@ void Resume(FrameDeliverCallback deliver_callback); + // Feedback callback. + void ProcessFeedback(const media::VideoFrameFeedback& feedback); + // Requests to receive a refreshed captured video frame. Do nothing if the // capturing device is not started or the capturing is paused. void RequestRefreshFrame(); @@ -61,16 +64,13 @@ void OnBufferDestroyed(int32_t buffer_id) override; private: - using BufferFinishedCallback = - base::OnceCallback<void(media::VideoFrameFeedback)>; + using BufferFinishedCallback = base::OnceCallback<void()>; // Called by the VideoFrame destructor. - static void DidFinishConsumingFrame(const media::VideoFrameFeedback* feedback, - BufferFinishedCallback callback); + static void DidFinishConsumingFrame(BufferFinishedCallback callback); // Reports the utilization, unmaps the shared memory, and returns the buffer. void OnClientBufferFinished(int buffer_id, - base::ReadOnlySharedMemoryMapping mapping, - media::VideoFrameFeedback feedback); + base::ReadOnlySharedMemoryMapping mapping); const media::VideoCaptureParams params_; const mojo::Remote<media::mojom::VideoCaptureHost> video_capture_host_; @@ -104,6 +104,9 @@ // |buffer_id| is the key to this map. MappingMap mapped_buffers_; + // Latest received feedback. + media::VideoFrameFeedback feedback_; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<VideoCaptureClient> weak_factory_{this};
diff --git a/components/mirroring/service/video_capture_client_unittest.cc b/components/mirroring/service/video_capture_client_unittest.cc index 888dd40..c3fa4bdd 100644 --- a/components/mirroring/service/video_capture_client_unittest.cc +++ b/components/mirroring/service/video_capture_client_unittest.cc
@@ -61,7 +61,7 @@ MOCK_METHOD1(OnFrameReceived, void(const gfx::Size&)); void OnFrameReady(scoped_refptr<media::VideoFrame> video_frame) { - *video_frame->feedback() = kFeedback; + client_->ProcessFeedback(kFeedback); OnFrameReceived(video_frame->coded_size()); }
diff --git a/components/password_manager/core/browser/store_metrics_reporter.cc b/components/password_manager/core/browser/store_metrics_reporter.cc index d14617b..d38c48c 100644 --- a/components/password_manager/core/browser/store_metrics_reporter.cc +++ b/components/password_manager/core/browser/store_metrics_reporter.cc
@@ -7,6 +7,7 @@ #include "base/metrics/histogram_functions.h" #include "base/sequenced_task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "components/password_manager/core/browser/password_feature_manager.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" #include "components/password_manager/core/browser/password_store.h" @@ -45,8 +46,9 @@ public: MultiStoreMetricsReporter(PasswordStore* profile_store, PasswordStore* account_store, + bool is_opted_in, base::OnceClosure done_callback) - : done_callback_(std::move(done_callback)) { + : is_opted_in_(is_opted_in), done_callback_(std::move(done_callback)) { DCHECK(profile_store); DCHECK(account_store); profile_store_consumer_ = std::make_unique<Consumer>( @@ -144,10 +146,24 @@ base::UmaHistogramCounts100( "PasswordManager.AccountStoreVsProfileStore.Conflicting", conflicting); + if (is_opted_in_) { + base::UmaHistogramCounts100( + "PasswordManager.AccountStoreVsProfileStore2.Additional", additional); + base::UmaHistogramCounts100( + "PasswordManager.AccountStoreVsProfileStore2.Missing", missing); + base::UmaHistogramCounts100( + "PasswordManager.AccountStoreVsProfileStore2.Identical", identical); + base::UmaHistogramCounts100( + "PasswordManager.AccountStoreVsProfileStore2.Conflicting", + conflicting); + } + std::move(done_callback_).Run(); // Note: |this| might be destroyed now. } + const bool is_opted_in_; + base::OnceClosure done_callback_; std::unique_ptr<Consumer> profile_store_consumer_; @@ -197,20 +213,23 @@ // delayed task runs. scoped_refptr<PasswordStore> retained_profile_store = profile_store; scoped_refptr<PasswordStore> retained_account_store = account_store; + bool is_opted_in = + client->GetPasswordFeatureManager()->IsOptedInForAccountStorage(); base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::BindOnce(&StoreMetricsReporter::ReportMultiStoreMetrics, weak_ptr_factory_.GetWeakPtr(), retained_profile_store, - retained_account_store), + retained_account_store, is_opted_in), base::TimeDelta::FromSeconds(30)); } } void StoreMetricsReporter::ReportMultiStoreMetrics( scoped_refptr<PasswordStore> profile_store, - scoped_refptr<PasswordStore> account_store) { + scoped_refptr<PasswordStore> account_store, + bool is_opted_in) { multi_store_reporter_ = std::make_unique<MultiStoreMetricsReporter>( - profile_store.get(), account_store.get(), + profile_store.get(), account_store.get(), is_opted_in, base::BindOnce(&StoreMetricsReporter::MultiStoreMetricsDone, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/components/password_manager/core/browser/store_metrics_reporter.h b/components/password_manager/core/browser/store_metrics_reporter.h index 5c017fb..0ff5b2a 100644 --- a/components/password_manager/core/browser/store_metrics_reporter.h +++ b/components/password_manager/core/browser/store_metrics_reporter.h
@@ -51,7 +51,8 @@ class MultiStoreMetricsReporter; void ReportMultiStoreMetrics(scoped_refptr<PasswordStore> profile_store, - scoped_refptr<PasswordStore> account_store); + scoped_refptr<PasswordStore> account_store, + bool is_opted_in); void MultiStoreMetricsDone(); std::unique_ptr<MultiStoreMetricsReporter> multi_store_reporter_;
diff --git a/components/password_manager/core/browser/store_metrics_reporter_unittest.cc b/components/password_manager/core/browser/store_metrics_reporter_unittest.cc index c67e23a8..351e853 100644 --- a/components/password_manager/core/browser/store_metrics_reporter_unittest.cc +++ b/components/password_manager/core/browser/store_metrics_reporter_unittest.cc
@@ -183,23 +183,52 @@ profile_store->AddLogin( CreateForm(kRealm2, "identicaluser1", "identicalpass1")); - base::HistogramTester histogram_tester; + for (bool opted_in : {false, true}) { + EXPECT_CALL(*client_.GetPasswordFeatureManager(), + IsOptedInForAccountStorage()) + .WillRepeatedly(Return(opted_in)); - StoreMetricsReporter reporter(&client_, sync_service(), identity_manager(), - &prefs_); - // Wait for the metrics to get reported. This is delayed by 30 seconds, and - // then involves queries to the stores, i.e. to background task runners. - FastForwardBy(base::TimeDelta::FromSeconds(30)); - RunUntilIdle(); + base::HistogramTester histogram_tester; - histogram_tester.ExpectUniqueSample( - "PasswordManager.AccountStoreVsProfileStore.Additional", 2, 1); - histogram_tester.ExpectUniqueSample( - "PasswordManager.AccountStoreVsProfileStore.Missing", 4, 1); - histogram_tester.ExpectUniqueSample( - "PasswordManager.AccountStoreVsProfileStore.Identical", 2, 1); - histogram_tester.ExpectUniqueSample( - "PasswordManager.AccountStoreVsProfileStore.Conflicting", 1, 1); + StoreMetricsReporter reporter(&client_, sync_service(), identity_manager(), + &prefs_); + // Wait for the metrics to get reported. This is delayed by 30 seconds, and + // then involves queries to the stores, i.e. to background task runners. + FastForwardBy(base::TimeDelta::FromSeconds(30)); + RunUntilIdle(); + + // The original version of the metrics (without "2") is still recorded, even + // if the user isn't opted in to the account storage. + histogram_tester.ExpectUniqueSample( + "PasswordManager.AccountStoreVsProfileStore.Additional", 2, 1); + histogram_tester.ExpectUniqueSample( + "PasswordManager.AccountStoreVsProfileStore.Missing", 4, 1); + histogram_tester.ExpectUniqueSample( + "PasswordManager.AccountStoreVsProfileStore.Identical", 2, 1); + histogram_tester.ExpectUniqueSample( + "PasswordManager.AccountStoreVsProfileStore.Conflicting", 1, 1); + + // Version "2" of the metrics is only recorded if the user is opted in. + if (opted_in) { + histogram_tester.ExpectUniqueSample( + "PasswordManager.AccountStoreVsProfileStore2.Additional", 2, 1); + histogram_tester.ExpectUniqueSample( + "PasswordManager.AccountStoreVsProfileStore2.Missing", 4, 1); + histogram_tester.ExpectUniqueSample( + "PasswordManager.AccountStoreVsProfileStore2.Identical", 2, 1); + histogram_tester.ExpectUniqueSample( + "PasswordManager.AccountStoreVsProfileStore2.Conflicting", 1, 1); + } else { + histogram_tester.ExpectTotalCount( + "PasswordManager.AccountStoreVsProfileStore2.Additional", 0); + histogram_tester.ExpectTotalCount( + "PasswordManager.AccountStoreVsProfileStore2.Missing", 0); + histogram_tester.ExpectTotalCount( + "PasswordManager.AccountStoreVsProfileStore2.Identical", 0); + histogram_tester.ExpectTotalCount( + "PasswordManager.AccountStoreVsProfileStore2.Conflicting", 0); + } + } account_store->ShutdownOnUIThread(); profile_store->ShutdownOnUIThread();
diff --git a/components/password_manager/core/common/password_manager_pref_names.cc b/components/password_manager/core/common/password_manager_pref_names.cc index 9c174792..2698fd7 100644 --- a/components/password_manager/core/common/password_manager_pref_names.cc +++ b/components/password_manager/core/common/password_manager_pref_names.cc
@@ -11,10 +11,6 @@ const char kCredentialsEnableAutosignin[] = "credentials_enable_autosignin"; const char kCredentialsEnableService[] = "credentials_enable_service"; -#if !defined(OS_APPLE) && !defined(OS_CHROMEOS) && defined(OS_POSIX) -const char kMigrationToLoginDBStep[] = "profile.migration_to_logindb_step"; -#endif - #if defined(OS_WIN) const char kOsPasswordBlank[] = "password_manager.os_password_blank"; const char kOsPasswordLastChanged[] =
diff --git a/components/password_manager/core/common/password_manager_pref_names.h b/components/password_manager/core/common/password_manager_pref_names.h index 28897b5c..04b9d7d 100644 --- a/components/password_manager/core/common/password_manager_pref_names.h +++ b/components/password_manager/core/common/password_manager_pref_names.h
@@ -24,11 +24,6 @@ // passwords. extern const char kCredentialsEnableService[]; -#if !defined(OS_APPLE) && !defined(OS_CHROMEOS) && defined(OS_POSIX) -// The current state of the migration to LoginDB from Keyring/Kwallet on Linux. -extern const char kMigrationToLoginDBStep[]; -#endif - #if defined(OS_WIN) // Whether the password was blank, only valid if OS password was last changed // on or before the value contained in kOsPasswordLastChanged.
diff --git a/components/password_manager/ios/js_password_manager.mm b/components/password_manager/ios/js_password_manager.mm index f74a844..0cac3846 100644 --- a/components/password_manager/ios/js_password_manager.mm +++ b/components/password_manager/ios/js_password_manager.mm
@@ -23,6 +23,16 @@ using autofill::kNotSetRendererID; using base::SysNSStringToUTF8; +// Converts FormRendererId to int value that can be used in Javascript methods. +int FormRendererIdToJsParameter(FormRendererId formID) { + return formID ? formID.value() : kNotSetRendererID; +} + +// Converts FieldRendererId to int value that can be used in Javascript methods. +int FieldRendererIdToJsParameter(FieldRendererId fieldID) { + return fieldID ? fieldID.value() : kNotSetRendererID; +} + namespace password_manager { std::unique_ptr<base::Value> SerializeFillData( @@ -34,14 +44,14 @@ const base::string16& password_value) { auto rootDict = std::make_unique<base::DictionaryValue>(); rootDict->SetString("origin", origin.spec()); - rootDict->SetInteger("unique_renderer_id", form_renderer_id.value()); + rootDict->SetInteger("unique_renderer_id", + FormRendererIdToJsParameter(form_renderer_id)); auto fieldList = std::make_unique<base::ListValue>(); auto usernameField = std::make_unique<base::DictionaryValue>(); - usernameField->SetInteger("unique_renderer_id", username_element - ? username_element.value() - : kNotSetRendererID); + usernameField->SetInteger("unique_renderer_id", + FieldRendererIdToJsParameter(username_element)); usernameField->SetString("value", username_value); fieldList->Append(std::move(usernameField)); @@ -119,9 +129,10 @@ completionHandler:(void (^)(BOOL))completionHandler { DCHECK(completionHandler); std::vector<base::Value> parameters; - parameters.emplace_back(static_cast<int>(formIdentifier.value())); - parameters.emplace_back(static_cast<int>(newPasswordIdentifier.value())); - parameters.emplace_back(static_cast<int>(confirmPasswordIdentifier.value())); + parameters.emplace_back(FormRendererIdToJsParameter(formIdentifier)); + parameters.emplace_back(FieldRendererIdToJsParameter(newPasswordIdentifier)); + parameters.emplace_back( + FieldRendererIdToJsParameter(confirmPasswordIdentifier)); parameters.push_back(base::Value(SysNSStringToUTF8(generatedPassword))); autofill::ExecuteJavaScriptFunction( "passwords.fillPasswordFormWithGeneratedPassword", parameters, frame,
diff --git a/components/password_manager/ios/resources/password_controller.js b/components/password_manager/ios/resources/password_controller.js index d31771f..c14ff98 100644 --- a/components/password_manager/ios/resources/password_controller.js +++ b/components/password_manager/ios/resources/password_controller.js
@@ -225,11 +225,15 @@ __gCrWeb.passwords['fillPasswordFormWithGeneratedPassword'] = function( formIdentifier, newPasswordIdentifier, confirmPasswordIdentifier, password) { + const hasFormTag = + formIdentifier.toString() !== __gCrWeb.fill.RENDERER_ID_NOT_SET; const form = __gCrWeb.form.getFormElementFromUniqueFormId(formIdentifier); - if (!form) { + if (!form && hasFormTag) { return false; } - const inputs = getFormInputElements(form); + const inputs = hasFormTag ? + getFormInputElements(form) : + __gCrWeb.fill.getUnownedAutofillableFormFieldElements(document.all, []); const newPasswordField = findInputByUniqueFieldId(inputs, newPasswordIdentifier); if (!newPasswordField) {
diff --git a/components/permissions/notification_permission_ui_selector.h b/components/permissions/notification_permission_ui_selector.h index 91e62fb..9100f0f0 100644 --- a/components/permissions/notification_permission_ui_selector.h +++ b/components/permissions/notification_permission_ui_selector.h
@@ -75,7 +75,8 @@ // Cancel the pending request, if any. After this, the |callback| is // guaranteed not to be invoked anymore, and another call to SelectUiToUse() - // can be issued. + // can be issued. Can be called when there is no pending request which will + // simply be a no-op. virtual void Cancel() {} };
diff --git a/components/permissions/permission_manager.cc b/components/permissions/permission_manager.cc index d5ed9f7..40a9b555 100644 --- a/components/permissions/permission_manager.cc +++ b/components/permissions/permission_manager.cc
@@ -607,8 +607,7 @@ void PermissionManager::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); std::vector<base::OnceClosure> callbacks; callbacks.reserve(subscriptions_.size());
diff --git a/components/permissions/permission_manager.h b/components/permissions/permission_manager.h index d11fb4b..47931b9 100644 --- a/components/permissions/permission_manager.h +++ b/components/permissions/permission_manager.h
@@ -170,8 +170,7 @@ // content_settings::Observer implementation. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; PermissionResult GetPermissionStatusHelper( ContentSettingsType permission,
diff --git a/components/permissions/permission_request_manager.cc b/components/permissions/permission_request_manager.cc index cc9da1d6..e59385d 100644 --- a/components/permissions/permission_request_manager.cc +++ b/components/permissions/permission_request_manager.cc
@@ -426,8 +426,8 @@ tab_is_hidden_(web_contents->GetVisibility() == content::Visibility::HIDDEN), auto_response_for_test_(NONE), - notification_permission_ui_selector_( - PermissionsClient::Get()->CreateNotificationPermissionUiSelector( + notification_permission_ui_selectors_( + PermissionsClient::Get()->CreateNotificationPermissionUiSelectors( web_contents->GetBrowserContext())) {} void PermissionRequestManager::ScheduleShowBubble() { @@ -474,14 +474,23 @@ } } - if (notification_permission_ui_selector_ && + if (!notification_permission_ui_selectors_.empty() && requests_.front()->GetPermissionRequestType() == PermissionRequestType::PERMISSION_NOTIFICATIONS) { - notification_permission_ui_selector_->SelectUiToUse( - requests_.front(), - base::BindOnce( - &PermissionRequestManager::OnSelectedUiToUseForNotifications, - weak_factory_.GetWeakPtr())); + DCHECK(!current_request_ui_to_use_.has_value()); + // Initialize the selector decisions vector. + DCHECK(selector_decisions_.empty()); + selector_decisions_.resize(notification_permission_ui_selectors_.size()); + + for (size_t selector_index = 0; + selector_index < notification_permission_ui_selectors_.size(); + ++selector_index) { + notification_permission_ui_selectors_[selector_index]->SelectUiToUse( + requests_.front(), + base::BindOnce( + &PermissionRequestManager::OnNotificationPermissionUiSelectorDone, + weak_factory_.GetWeakPtr(), selector_index)); + } } else { current_request_ui_to_use_ = UiDecision(UiDecision::UseNormalUi(), UiDecision::ShowNoWarning()); @@ -532,17 +541,6 @@ base::RecordAction(base::UserMetricsAction( "Notifications.Quiet.PermissionRequestShown")); } - - if (current_request_ui_to_use_->warning_reason) { - switch (*(current_request_ui_to_use_->warning_reason)) { - case WarningReason::kAbusiveRequests: - LogWarningToConsole(kAbusiveNotificationRequestsWarningMessage); - break; - case WarningReason::kAbusiveContent: - LogWarningToConsole(kAbusiveNotificationContentWarningMessage); - break; - } - } } current_request_already_displayed_ = true; NotifyBubbleAdded(); @@ -614,11 +612,12 @@ } requests_.clear(); - if (notification_permission_ui_selector_) - notification_permission_ui_selector_->Cancel(); + for (const auto& selector : notification_permission_ui_selectors_) + selector->Cancel(); current_request_already_displayed_ = false; current_request_ui_to_use_.reset(); + selector_decisions_.clear(); if (view_) DeleteBubble(); @@ -716,7 +715,7 @@ return false; // ContentSettingImageModel might call into this method if the user switches - // between tabs while the |notification_permission_ui_selector_| is pending. + // between tabs while the |notification_permission_ui_selectors_| are pending. return current_request_ui_to_use_ && current_request_ui_to_use_->quiet_ui_reason; } @@ -740,10 +739,49 @@ observer.OnBubbleRemoved(); } -void PermissionRequestManager::OnSelectedUiToUseForNotifications( +void PermissionRequestManager::OnNotificationPermissionUiSelectorDone( + size_t selector_index, const UiDecision& decision) { - current_request_ui_to_use_ = decision; - ScheduleShowBubble(); + if (decision.warning_reason) { + switch (*(decision.warning_reason)) { + case WarningReason::kAbusiveRequests: + LogWarningToConsole(kAbusiveNotificationRequestsWarningMessage); + break; + case WarningReason::kAbusiveContent: + LogWarningToConsole(kAbusiveNotificationContentWarningMessage); + break; + } + } + + // We have already made a decision because of a higher priority selector + // therefore this selector's decision can be discarded. + if (current_request_ui_to_use_.has_value()) + return; + + CHECK_LT(selector_index, selector_decisions_.size()); + selector_decisions_[selector_index] = decision; + + size_t decision_index = 0; + while (decision_index < selector_decisions_.size() && + selector_decisions_[decision_index].has_value()) { + const UiDecision& current_decision = + selector_decisions_[decision_index++].value(); + + if (current_decision.quiet_ui_reason.has_value()) { + current_request_ui_to_use_ = current_decision; + break; + } + } + + // All decisions have been considered and none was conclusive. + if (decision_index == selector_decisions_.size() && + !current_request_ui_to_use_.has_value()) { + current_request_ui_to_use_ = UiDecision::UseNormalUiAndShowNoWarning(); + } + + if (current_request_ui_to_use_.has_value()) { + ScheduleShowBubble(); + } } PermissionPromptDisposition
diff --git a/components/permissions/permission_request_manager.h b/components/permissions/permission_request_manager.h index cdf4938..85ff592 100644 --- a/components/permissions/permission_request_manager.h +++ b/components/permissions/permission_request_manager.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_PERMISSIONS_PERMISSION_REQUEST_MANAGER_H_ #define COMPONENTS_PERMISSIONS_PERMISSION_REQUEST_MANAGER_H_ +#include <algorithm> #include <unordered_map> #include <utility> #include <vector> @@ -145,10 +146,24 @@ web_contents_supports_permission_requests; } - // For testing only, used to override the default UI selector. + // For testing only, used to override the default UI selectors and instead use + // a new one. void set_notification_permission_ui_selector_for_testing( std::unique_ptr<NotificationPermissionUiSelector> selector) { - notification_permission_ui_selector_ = std::move(selector); + clear_notification_permission_ui_selector_for_testing(); + add_notification_permission_ui_selector_for_testing(std::move(selector)); + } + + // For testing only, used to add a new selector without overriding the + // existing ones. + void add_notification_permission_ui_selector_for_testing( + std::unique_ptr<NotificationPermissionUiSelector> selector) { + notification_permission_ui_selectors_.emplace_back(std::move(selector)); + } + + // For testing only, clear the existing ui selectors. + void clear_notification_permission_ui_selector_for_testing() { + notification_permission_ui_selectors_.clear(); } void set_view_factory_for_testing(PermissionPrompt::Factory view_factory) { @@ -209,7 +224,8 @@ void NotifyBubbleAdded(); void NotifyBubbleRemoved(); - void OnSelectedUiToUseForNotifications(const UiDecision& decision); + void OnNotificationPermissionUiSelectorDone(size_t selector_index, + const UiDecision& decision); PermissionPromptDisposition DetermineCurrentRequestUIDispositionForUMA(); @@ -256,10 +272,17 @@ // origin requesting the permission. bool is_notification_prompt_cooldown_active_ = false; - // Decides if the quiet prompt UI should be used to display notification - // permission requests. - std::unique_ptr<NotificationPermissionUiSelector> - notification_permission_ui_selector_; + // A vector of selectors which decide if the quiet prompt UI should be used + // to display notification permission requests. Sorted from the highest + // priority to the lowest priority selector. + std::vector<std::unique_ptr<NotificationPermissionUiSelector>> + notification_permission_ui_selectors_; + + // Holds the decisions returned by selectors. Needed in case a lower priority + // selector returns a decision first and we need to wait for the decisions of + // higher priority selectors before making use of it. + std::vector<base::Optional<NotificationPermissionUiSelector::Decision>> + selector_decisions_; // Whether the view for the current |requests_| has been shown to the user at // least once. @@ -267,7 +290,7 @@ // Whether to use the normal or quiet UI to display the current permission // |requests_|, and whether to show warnings. This will be nullopt if we are - // still waiting on the result from |notification_permission_ui_selector_|. + // still waiting on the result from |notification_permission_ui_selectors_|. base::Optional<UiDecision> current_request_ui_to_use_; // Whether the bubble is being destroyed by this class, rather than in
diff --git a/components/permissions/permission_request_manager_unittest.cc b/components/permissions/permission_request_manager_unittest.cc index 9c2e28c..80f5821 100644 --- a/components/permissions/permission_request_manager_unittest.cc +++ b/components/permissions/permission_request_manager_unittest.cc
@@ -3,10 +3,12 @@ // found in the LICENSE file. #include <stddef.h> +#include <memory> #include <string> #include "base/bind.h" #include "base/command_line.h" +#include "base/optional.h" #include "base/run_loop.h" #include "base/test/metrics/histogram_tester.h" #include "base/threading/sequenced_task_runner_handle.h" @@ -576,7 +578,7 @@ static void CreateForManager(PermissionRequestManager* manager, base::Optional<QuietUiReason> quiet_ui_reason, bool async) { - manager->set_notification_permission_ui_selector_for_testing( + manager->add_notification_permission_ui_selector_for_testing( std::make_unique<MockNotificationPermissionUiSelector>(quiet_ui_reason, async)); } @@ -589,6 +591,7 @@ TEST_F(PermissionRequestManagerTest, UiSelectorNotUsedForPermissionsOtherThanNotification) { for (auto* request : {&request_mic_, &request_camera_, &request_ptz_}) { + manager_->clear_notification_permission_ui_selector_for_testing(); MockNotificationPermissionUiSelector::CreateForManager( manager_, NotificationPermissionUiSelector::QuietUiReason::kEnabledInPrefs, @@ -620,6 +623,7 @@ }; for (const auto& test : kTests) { + manager_->clear_notification_permission_ui_selector_for_testing(); MockNotificationPermissionUiSelector::CreateForManager( manager_, test.quiet_ui_reason, test.async); @@ -644,6 +648,7 @@ TEST_F(PermissionRequestManagerTest, UiSelectionHappensSeparatelyForEachRequest) { using QuietUiReason = NotificationPermissionUiSelector::QuietUiReason; + manager_->clear_notification_permission_ui_selector_for_testing(); MockNotificationPermissionUiSelector::CreateForManager( manager_, QuietUiReason::kEnabledInPrefs, true); MockPermissionRequest request1( @@ -657,6 +662,7 @@ MockPermissionRequest request2( "request2", PermissionRequestType::PERMISSION_NOTIFICATIONS, PermissionRequestGestureType::GESTURE); + manager_->clear_notification_permission_ui_selector_for_testing(); MockNotificationPermissionUiSelector::CreateForManager( manager_, NotificationPermissionUiSelector::Decision::UseNormalUi(), true); @@ -677,4 +683,80 @@ manager_->AddRequest(web_contents()->GetMainFrame(), &request2_); EXPECT_TRUE(request2_.cancelled()); } + +TEST_F(PermissionRequestManagerTest, MultipleUiSelectors) { + using QuietUiReason = NotificationPermissionUiSelector::QuietUiReason; + + const struct { + std::vector<base::Optional<QuietUiReason>> quiet_ui_reasons; + std::vector<bool> simulate_delayed_decision; + base::Optional<QuietUiReason> expected_reason; + } kTests[] = { + // Simple sync selectors, first one should take priority. + {{QuietUiReason::kTriggeredByCrowdDeny, QuietUiReason::kEnabledInPrefs}, + {false, false}, + QuietUiReason::kTriggeredByCrowdDeny}, + // First selector is async but should still take priority even if it + // returns later. + {{QuietUiReason::kTriggeredByCrowdDeny, QuietUiReason::kEnabledInPrefs}, + {true, false}, + QuietUiReason::kTriggeredByCrowdDeny}, + // The first selector that has a quiet ui decision should be used. + {{base::nullopt, base::nullopt, + QuietUiReason::kTriggeredDueToAbusiveContent, + QuietUiReason::kEnabledInPrefs}, + {false, true, true, false}, + QuietUiReason::kTriggeredDueToAbusiveContent}, + // If all selectors return a normal ui, it should use a normal ui. + {{base::nullopt, base::nullopt}, {false, true}, base::nullopt}, + + // Use a bunch of selectors both async and sync. + {{base::nullopt, base::nullopt, base::nullopt, base::nullopt, + base::nullopt, QuietUiReason::kTriggeredDueToAbusiveRequests, + base::nullopt, QuietUiReason::kEnabledInPrefs}, + {false, true, false, true, true, true, false, false}, + QuietUiReason::kTriggeredDueToAbusiveRequests}, + // Use a bunch of selectors all sync. + {{base::nullopt, base::nullopt, base::nullopt, base::nullopt, + base::nullopt, QuietUiReason::kTriggeredDueToAbusiveRequests, + base::nullopt, QuietUiReason::kEnabledInPrefs}, + {false, false, false, false, false, false, false, false}, + QuietUiReason::kTriggeredDueToAbusiveRequests}, + // Use a bunch of selectors all async. + {{base::nullopt, base::nullopt, base::nullopt, base::nullopt, + base::nullopt, QuietUiReason::kTriggeredDueToAbusiveRequests, + base::nullopt, QuietUiReason::kEnabledInPrefs}, + {true, true, true, true, true, true, true, true}, + QuietUiReason::kTriggeredDueToAbusiveRequests}, + }; + + for (const auto& test : kTests) { + manager_->clear_notification_permission_ui_selector_for_testing(); + for (size_t i = 0; i < test.quiet_ui_reasons.size(); ++i) { + MockNotificationPermissionUiSelector::CreateForManager( + manager_, test.quiet_ui_reasons[i], + test.simulate_delayed_decision[i]); + } + + MockPermissionRequest request( + "foo", PermissionRequestType::PERMISSION_NOTIFICATIONS, + PermissionRequestGestureType::GESTURE); + + manager_->AddRequest(web_contents()->GetMainFrame(), &request); + WaitForBubbleToBeShown(); + + EXPECT_TRUE(prompt_factory_->is_visible()); + EXPECT_TRUE( + prompt_factory_->RequestTypeSeen(request.GetPermissionRequestType())); + if (test.expected_reason.has_value()) { + EXPECT_EQ(test.expected_reason, manager_->ReasonForUsingQuietUi()); + } else { + EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI()); + } + + Accept(); + EXPECT_TRUE(request.granted()); + } +} + } // namespace permissions
diff --git a/components/permissions/permissions_client.cc b/components/permissions/permissions_client.cc index 96dca126..19fa0bf 100644 --- a/components/permissions/permissions_client.cc +++ b/components/permissions/permissions_client.cc
@@ -68,10 +68,10 @@ #endif } -std::unique_ptr<NotificationPermissionUiSelector> -PermissionsClient::CreateNotificationPermissionUiSelector( +std::vector<std::unique_ptr<NotificationPermissionUiSelector>> +PermissionsClient::CreateNotificationPermissionUiSelectors( content::BrowserContext* browser_context) { - return nullptr; + return std::vector<std::unique_ptr<NotificationPermissionUiSelector>>(); } void PermissionsClient::OnPromptResolved(
diff --git a/components/permissions/permissions_client.h b/components/permissions/permissions_client.h index 406be4f..c8e8c1f 100644 --- a/components/permissions/permissions_client.h +++ b/components/permissions/permissions_client.h
@@ -121,11 +121,14 @@ // used. virtual PermissionRequest::IconId GetOverrideIconId(ContentSettingsType type); - // Allows the embedder to provide a selector for chossing the UI to use for - // notification permission requests. If the embedder returns null here, the - // normal UI will be used. - virtual std::unique_ptr<NotificationPermissionUiSelector> - CreateNotificationPermissionUiSelector( + // Allows the embedder to provide a list of selectors for choosing the UI to + // use for notification permission requests. If the embedder returns an empty + // list, the normal UI will be used always. Then for each request, if none of + // the returned selectors prescribe the quiet UI, the normal UI will be used. + // Otherwise the quiet UI will be used. Selectors at lower indices have higher + // priority when determining the quiet UI flavor. + virtual std::vector<std::unique_ptr<NotificationPermissionUiSelector>> + CreateNotificationPermissionUiSelectors( content::BrowserContext* browser_context); using QuietUiReason = NotificationPermissionUiSelector::QuietUiReason;
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index c74b699..b7427b6 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -3177,6 +3177,14 @@ // Extended error code if the extension installation failed due to CRX install // error. optional CrxInstallErrorDetail crx_install_error_detail = 18; + + // Fetch error code when failure_reason is CRX_FETCH_FAILED or + // MANIFEST_FETCH_FAILED. + optional int32 fetch_error_code = 19; + + // Number of fetch tries made when failure reason is CRX_FETCH_FAILED or + // MANIFEST_FETCH_FAILED. + optional int32 fetch_tries = 20; } // A single entry in the push-install log for an app.
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index a660144b..2d7921a7 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -16509,7 +16509,7 @@ 'id': 374, 'caption': '''Migration strategy for ecryptfs''', 'tags': [], - 'desc': '''This policy is deprecated in M61, please use EcryptfsMigrationStrategy instead. + 'desc': '''This policy was removed in M61. Specifies how a device should behave that shipped with ecryptfs and needs to transition to ext4 encryption. @@ -16549,17 +16549,19 @@ 'caption': '''Similar to Wipe (value 2), but tries to preserve login tokens so the user does not have to sign in again.''', }, ], - 'supported_on': ['chrome_os:61-'], + 'supported_on': ['chrome_os:61-87'], 'device_only': False, 'features': { 'dynamic_refresh': False, 'per_profile': False, }, + 'deprecated': True, 'example_value': 2, 'id': 376, 'caption': '''Migration strategy for ecryptfs''', 'tags': [], - 'desc': '''Setting the policy specifies the action to take when the user's home directory was created with ecryptfs encryption. Unless ecryptfs-encrypted home directories migrate to ext4-encryption, Android apps might stop running. + 'desc': '''This policy was removed in M87 and home directories will automatically migrate to ext4 at sign-in. + Setting the policy specifies the action to take when the user's home directory was created with ecryptfs encryption. Unless ecryptfs-encrypted home directories migrate to ext4-encryption, Android apps might stop running. Setting the policy to:
diff --git a/components/signin/core/browser/about_signin_internals.cc b/components/signin/core/browser/about_signin_internals.cc index 33491d64..e949c1b6 100644 --- a/components/signin/core/browser/about_signin_internals.cc +++ b/components/signin/core/browser/about_signin_internals.cc
@@ -330,8 +330,7 @@ void AboutSigninInternals::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { // If this is not a change to cookie settings, just ignore. if (content_type != ContentSettingsType::COOKIES) return;
diff --git a/components/signin/core/browser/about_signin_internals.h b/components/signin/core/browser/about_signin_internals.h index e9ec1605..289afad 100644 --- a/components/signin/core/browser/about_signin_internals.h +++ b/components/signin/core/browser/about_signin_internals.h
@@ -224,8 +224,7 @@ // content_settings::Observer implementation. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // AccountReconcilor::Observer implementation. void OnBlockReconcile() override;
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc index 399cc20..03a8ed0 100644 --- a/components/signin/core/browser/account_reconcilor.cc +++ b/components/signin/core/browser/account_reconcilor.cc
@@ -346,8 +346,7 @@ void AccountReconcilor::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { // If this is not a change to cookie settings, just ignore. if (content_type != ContentSettingsType::COOKIES) return;
diff --git a/components/signin/core/browser/account_reconcilor.h b/components/signin/core/browser/account_reconcilor.h index 5b5d0e8..5a1a867c 100644 --- a/components/signin/core/browser/account_reconcilor.h +++ b/components/signin/core/browser/account_reconcilor.h
@@ -265,8 +265,7 @@ // Overridden from content_settings::Observer. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; // Overridden from signin::IdentityManager::Observer. void OnEndBatchOfRefreshTokenStateChanges() override;
diff --git a/components/signin/core/browser/account_reconcilor_unittest.cc b/components/signin/core/browser/account_reconcilor_unittest.cc index 85720336..2cfd116 100644 --- a/components/signin/core/browser/account_reconcilor_unittest.cc +++ b/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -397,9 +397,9 @@ void AccountReconcilorTest::SimulateCookieContentSettingsChanged( content_settings::Observer* observer, const ContentSettingsPattern& primary_pattern) { - observer->OnContentSettingChanged( - primary_pattern, ContentSettingsPattern::Wildcard(), - ContentSettingsType::COOKIES, std::string()); + observer->OnContentSettingChanged(primary_pattern, + ContentSettingsPattern::Wildcard(), + ContentSettingsType::COOKIES); } void AccountReconcilorTest::SetAccountConsistency(
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc index 5b5127a3..ca5dd45 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
@@ -279,8 +279,9 @@ return; } - AsyncDocumentSubresourceFilter* filter = - FilterForFinishedNavigation(navigation_handle, throttle, frame_host); + bool did_inherit_opener_activation; + AsyncDocumentSubresourceFilter* filter = FilterForFinishedNavigation( + navigation_handle, throttle, frame_host, did_inherit_opener_activation); if (navigation_handle->IsInMainFrame()) { current_committed_load_has_notified_disallowed_load_ = false; @@ -296,11 +297,11 @@ kActivationConsoleMessage); } } - mojom::ActivationLevel level = + RecordUmaHistogramsForMainFrameNavigation( + navigation_handle, filter ? filter->activation_state().activation_level - : mojom::ActivationLevel::kDisabled; - UMA_HISTOGRAM_ENUMERATION("SubresourceFilter.PageLoad.ActivationState", - level); + : mojom::ActivationLevel::kDisabled, + did_inherit_opener_activation); } DestroyRulesetHandleIfNoLongerUsed(); @@ -310,11 +311,13 @@ ContentSubresourceFilterThrottleManager::FilterForFinishedNavigation( content::NavigationHandle* navigation_handle, ActivationStateComputingNavigationThrottle* throttle, - content::RenderFrameHost* frame_host) { + content::RenderFrameHost* frame_host, + bool& did_inherit_opener_activation) { DCHECK(navigation_handle); DCHECK(frame_host); std::unique_ptr<AsyncDocumentSubresourceFilter> filter; + did_inherit_opener_activation = false; if (navigation_handle->HasCommitted() && throttle) { CHECK_EQ(navigation_handle, throttle->navigation_handle()); @@ -334,6 +337,7 @@ content::WebContents::FromRenderFrameHost(opener_rfh))) { opener_activation = opener_throttle_manager->GetFrameActivationState(opener_rfh); + did_inherit_opener_activation = true; } if (opener_activation && opener_activation->activation_level != @@ -376,6 +380,22 @@ return raw_ptr; } +void ContentSubresourceFilterThrottleManager:: + RecordUmaHistogramsForMainFrameNavigation( + content::NavigationHandle* navigation_handle, + const mojom::ActivationLevel& activation_level, + bool did_inherit_opener_activation) { + DCHECK(navigation_handle->IsInMainFrame()); + + UMA_HISTOGRAM_ENUMERATION("SubresourceFilter.PageLoad.ActivationState", + activation_level); + if (did_inherit_opener_activation) { + UMA_HISTOGRAM_ENUMERATION( + "SubresourceFilter.PageLoad.ActivationState.DidInherit", + activation_level); + } +} + void ContentSubresourceFilterThrottleManager::DidFinishLoad( content::RenderFrameHost* render_frame_host, const GURL& validated_url) {
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h index 21fdb0c..ef0af55 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h
@@ -220,10 +220,18 @@ // filter, or returns |nullptr|. Also updates |frame_host_filter_map_| as // appropriate. |frame_host| is provided as |navigation_handle|'s getter // cannot be used when the navigation has not committed. + // `did_inherit_opener_activation` will be set according to whether the + // activation was inherited from the frame's same-origin opener. AsyncDocumentSubresourceFilter* FilterForFinishedNavigation( content::NavigationHandle* navigation_handle, ActivationStateComputingNavigationThrottle* throttle, - content::RenderFrameHost* frame_host); + content::RenderFrameHost* frame_host, + bool& did_inherit_opener_activation); + + void RecordUmaHistogramsForMainFrameNavigation( + content::NavigationHandle* navigation_handle, + const mojom::ActivationLevel& activation_level, + bool did_inherit_opener_activation); // For each RenderFrameHost where the last committed load has subresource // filtering activated, owns the corresponding AsyncDocumentSubresourceFilter.
diff --git a/components/test/data/autofill/heuristics/output/014_autocomplete_attribute_invalid.out b/components/test/data/autofill/heuristics/output/014_autocomplete_attribute_invalid.out index 52d67e8..4a593d2 100644 --- a/components/test/data/autofill/heuristics/output/014_autocomplete_attribute_invalid.out +++ b/components/test/data/autofill/heuristics/output/014_autocomplete_attribute_invalid.out
@@ -20,56 +20,56 @@ UNKNOWN_TYPE | | | | valid-pre-garbage_1-default UNKNOWN_TYPE | | | | valid-pre-garbage_1-default UNKNOWN_TYPE | | | | valid-pre-garbage_1-default -HTML_TYPE_EMAIL | valid-pre-order | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -UNKNOWN_TYPE | | | | valid-pre-order_1-default -HTML_TYPE_EMAIL | valid-pre-repetition | | | valid-pre-repetition_1-default -UNKNOWN_TYPE | | | | valid-pre-repetition_1-default -UNKNOWN_TYPE | | | | valid-pre-repetition_1-default -UNKNOWN_TYPE | | | | valid-pre-repetition_1-default -UNKNOWN_TYPE | | | | valid-pre-repetition_1-default -UNKNOWN_TYPE | | | | valid-pre-repetition_1-default -HTML_TYPE_EMAIL | valid-pre-combinations | | | valid-pre-combinations_1-default -UNKNOWN_TYPE | | | | valid-pre-combinations_1-default -UNKNOWN_TYPE | | | | valid-pre-combinations_1-default -UNKNOWN_TYPE | | | | valid-pre-combinations_1-default -UNKNOWN_TYPE | | | | valid-pre-combinations_1-default +HTML_TYPE_EMAIL | valid-pre-order | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +UNKNOWN_TYPE | | | | valid-pre-order_2-default +HTML_TYPE_EMAIL | valid-pre-repetition | | | valid-pre-repetition_3-default +UNKNOWN_TYPE | | | | valid-pre-repetition_3-default +UNKNOWN_TYPE | | | | valid-pre-repetition_3-default +UNKNOWN_TYPE | | | | valid-pre-repetition_3-default +UNKNOWN_TYPE | | | | valid-pre-repetition_3-default +UNKNOWN_TYPE | | | | valid-pre-repetition_3-default +HTML_TYPE_EMAIL | valid-pre-combinations | | | valid-pre-combinations_4-default +UNKNOWN_TYPE | | | | valid-pre-combinations_4-default +UNKNOWN_TYPE | | | | valid-pre-combinations_4-default +UNKNOWN_TYPE | | | | valid-pre-combinations_4-default +UNKNOWN_TYPE | | | | valid-pre-combinations_4-default
diff --git a/components/test/data/autofill/heuristics/output/017_checkout_advanceautoparts.com.out b/components/test/data/autofill/heuristics/output/017_checkout_advanceautoparts.com.out index e9a02b3..9acf5aca 100644 --- a/components/test/data/autofill/heuristics/output/017_checkout_advanceautoparts.com.out +++ b/components/test/data/autofill/heuristics/output/017_checkout_advanceautoparts.com.out
@@ -16,17 +16,17 @@ UNKNOWN_TYPE | sendMeEmail | Yes, please send me emails about news, special offers, exclusives and promotions from Advance Auto Parts. See our | checked | billingShippingSame_1-default UNKNOWN_TYPE | billPassword | Password: | | billingShippingSame_1-default UNKNOWN_TYPE | billPasswordVerify | Confirm Password: | | billingShippingSame_1-default -NAME_FIRST | shipFirstName | *First Name: | | shipFirstName_1-default -NAME_LAST | shipLastName | *Last Name: | | shipFirstName_1-default -ADDRESS_HOME_LINE1 | shipAddress1 | *Street Address 1: | | shipFirstName_1-default -ADDRESS_HOME_LINE2 | shipAddress2 | Street Address 2: | | shipFirstName_1-default -ADDRESS_HOME_CITY | shipCity | *City: | | shipFirstName_1-default -ADDRESS_HOME_STATE | shipState | *State: | AL | shipFirstName_1-default -ADDRESS_HOME_ZIP | shipZipCode | *Zip Code: | | shipFirstName_1-default -PHONE_HOME_CITY_CODE | shipDayPhonePart1 | *Day Phone: | | shipFirstName_1-default -PHONE_HOME_NUMBER | shipDayPhonePart2 | *Day Phone: | | shipFirstName_1-default -PHONE_HOME_NUMBER | shipDayPhonePart3 | *Day Phone: | | shipFirstName_1-default -PHONE_HOME_CITY_CODE | shipNightPhonePart1 | Night Phone: | | shipFirstName_1-default -PHONE_HOME_NUMBER | shipNightPhonePart2 | Night Phone: | | shipFirstName_1-default -PHONE_HOME_NUMBER | shipNightPhonePart3 | Night Phone: | | shipFirstName_1-default +NAME_FIRST | shipFirstName | *First Name: | | shipFirstName_2-default +NAME_LAST | shipLastName | *Last Name: | | shipFirstName_2-default +ADDRESS_HOME_LINE1 | shipAddress1 | *Street Address 1: | | shipFirstName_2-default +ADDRESS_HOME_LINE2 | shipAddress2 | Street Address 2: | | shipFirstName_2-default +ADDRESS_HOME_CITY | shipCity | *City: | | shipFirstName_2-default +ADDRESS_HOME_STATE | shipState | *State: | AL | shipFirstName_2-default +ADDRESS_HOME_ZIP | shipZipCode | *Zip Code: | | shipFirstName_2-default +PHONE_HOME_CITY_CODE | shipDayPhonePart1 | *Day Phone: | | shipFirstName_2-default +PHONE_HOME_NUMBER | shipDayPhonePart2 | *Day Phone: | | shipFirstName_2-default +PHONE_HOME_NUMBER | shipDayPhonePart3 | *Day Phone: | | shipFirstName_2-default +PHONE_HOME_CITY_CODE | shipNightPhonePart1 | Night Phone: | | shipFirstName_2-default +PHONE_HOME_NUMBER | shipNightPhonePart2 | Night Phone: | | shipFirstName_2-default +PHONE_HOME_NUMBER | shipNightPhonePart3 | Night Phone: | | shipFirstName_2-default UNKNOWN_TYPE | zipCode | | | zipCode_1-default
diff --git a/components/test/data/autofill/heuristics/output/018_checkout_ae.com.out b/components/test/data/autofill/heuristics/output/018_checkout_ae.com.out index 3899f96..f34ee96 100644 --- a/components/test/data/autofill/heuristics/output/018_checkout_ae.com.out +++ b/components/test/data/autofill/heuristics/output/018_checkout_ae.com.out
@@ -22,35 +22,35 @@ CREDIT_CARD_EXP_MONTH | expMonth | Expiration: | 1 | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | expYear | Expiration: | 2011 | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | ccSecCode | Security Code: CLOSEVisa, Mastercard & Discover:The security code is a 3-digit number found on the back of the card near the signature strip.American Express:The security code is a 4-digit number found on the front right side of the card. | | credit-card-cc -UNKNOWN_TYPE | birthMonthBMLField | Birthday: CLOSEWe need your birthday for the Bill Me Later® credit check process. | | ccType_1-default -UNKNOWN_TYPE | birthDayBMLField | Birthday: CLOSEWe need your birthday for the Bill Me Later® credit check process. | | ccType_1-default -UNKNOWN_TYPE | birthYearBMLField | Birthday: CLOSEWe need your birthday for the Bill Me Later® credit check process. | | ccType_1-default -UNKNOWN_TYPE | SSN | Last 4 digits of your social security #: CLOSEWe need the last 4 digits of your SSN for the Bill Me Later® credit check process. If you do not have an SSN, you can still pay by Credit Card or PayPal. | | ccType_1-default -UNKNOWN_TYPE | agree | I agree to have the Terms and Conditions presented electronically. | yes | ccType_1-default -UNKNOWN_TYPE | agreeTs | I agree to the Bill Me Later® Terms and Conditions. | yes | ccType_1-default -ADDRESS_HOME_COUNTRY | countryType | Country Type | usa | ccType_1-default -UNKNOWN_TYPE | billSameAsShip | My Billing & Shipping addresses are the same | yes | ccType_1-default -ADDRESS_HOME_COUNTRY | country | Country, APO/FPO | US | ccType_1-default -NAME_FIRST | firstName | First Name | | ccType_1-default -NAME_LAST | lastName | Last Name | | ccType_1-default -ADDRESS_HOME_LINE1 | address1 | Address | | ccType_1-default -ADDRESS_HOME_LINE2 | address2 | Address | | ccType_1-default -ADDRESS_HOME_CITY | city | City | | ccType_1-default -ADDRESS_HOME_STATE | state | State | | ccType_1-default -ADDRESS_HOME_ZIP | zip | Zip | | ccType_1-default -EMAIL_ADDRESS | email | Email CLOSEWe use this to send you an order confirmation and tracking info once your order ships. | | ccType_1-default -EMAIL_ADDRESS | confirmEmail | Re-Type Email | | ccType_1-default -PHONE_HOME_WHOLE_NUMBER | billingPhone | Billing Phone Number CLOSEThis must match the phone number on your credit card statement. Don't worry... we never share your number with anyone. | | ccType_1-default -UNKNOWN_TYPE | accessPassNumber | My AEREWARD$ # CLOSEAEREWARD$ NumberEnter the number found on the back of your AEREWARD$ card to earn rewards for your purchase.Learn More about AEREWARD$ | | ccType_1-default -UNKNOWN_TYPE | aeRewardsSignUp | Sign up now and receive 25 points just for signing up! Learn More | true | ccType_1-default -UNKNOWN_TYPE | aeAccount | Create my AE Account.CLOSECreate an AE Account to:Save Your Personal Info For Next TimeCheckout FasterTrack An Order Quicker Sign up now and receive 25 points just for signing up! Learn More | true | ccType_1-default -UNKNOWN_TYPE | aeAccountPass | Password (6-15 Letters & Numbers) | | ccType_1-default -UNKNOWN_TYPE | aeAccountPassConfirm | Confirm Password | | ccType_1-default -UNKNOWN_TYPE | birthMonthBillAddField | Birthday: CLOSEWe'd love to wish you a happy birthday when it's time! However, you need to be 13 or older to create an account. | | ccType_1-default -UNKNOWN_TYPE | birthDayBillAddField | Birthday: CLOSEWe'd love to wish you a happy birthday when it's time! However, you need to be 13 or older to create an account. | | ccType_1-default -UNKNOWN_TYPE | birthYearBillAddField | Birthday: CLOSEWe'd love to wish you a happy birthday when it's time! However, you need to be 13 or older to create an account. | | ccType_1-default -UNKNOWN_TYPE | aeEmail | AE | on | ccType_1-default -UNKNOWN_TYPE | aerieEmail | aerie | on | ccType_1-default -UNKNOWN_TYPE | kidsEmail | 77kids | on | ccType_1-default -UNKNOWN_TYPE | loyaltyTerms | I accept the Terms & Conditions | | ccType_1-default +UNKNOWN_TYPE | birthMonthBMLField | Birthday: CLOSEWe need your birthday for the Bill Me Later® credit check process. | | ccType_2-default +UNKNOWN_TYPE | birthDayBMLField | Birthday: CLOSEWe need your birthday for the Bill Me Later® credit check process. | | ccType_2-default +UNKNOWN_TYPE | birthYearBMLField | Birthday: CLOSEWe need your birthday for the Bill Me Later® credit check process. | | ccType_2-default +UNKNOWN_TYPE | SSN | Last 4 digits of your social security #: CLOSEWe need the last 4 digits of your SSN for the Bill Me Later® credit check process. If you do not have an SSN, you can still pay by Credit Card or PayPal. | | ccType_2-default +UNKNOWN_TYPE | agree | I agree to have the Terms and Conditions presented electronically. | yes | ccType_2-default +UNKNOWN_TYPE | agreeTs | I agree to the Bill Me Later® Terms and Conditions. | yes | ccType_2-default +ADDRESS_HOME_COUNTRY | countryType | Country Type | usa | ccType_2-default +UNKNOWN_TYPE | billSameAsShip | My Billing & Shipping addresses are the same | yes | ccType_2-default +ADDRESS_HOME_COUNTRY | country | Country, APO/FPO | US | ccType_2-default +NAME_FIRST | firstName | First Name | | ccType_2-default +NAME_LAST | lastName | Last Name | | ccType_2-default +ADDRESS_HOME_LINE1 | address1 | Address | | ccType_2-default +ADDRESS_HOME_LINE2 | address2 | Address | | ccType_2-default +ADDRESS_HOME_CITY | city | City | | ccType_2-default +ADDRESS_HOME_STATE | state | State | | ccType_2-default +ADDRESS_HOME_ZIP | zip | Zip | | ccType_2-default +EMAIL_ADDRESS | email | Email CLOSEWe use this to send you an order confirmation and tracking info once your order ships. | | ccType_2-default +EMAIL_ADDRESS | confirmEmail | Re-Type Email | | ccType_2-default +PHONE_HOME_WHOLE_NUMBER | billingPhone | Billing Phone Number CLOSEThis must match the phone number on your credit card statement. Don't worry... we never share your number with anyone. | | ccType_2-default +UNKNOWN_TYPE | accessPassNumber | My AEREWARD$ # CLOSEAEREWARD$ NumberEnter the number found on the back of your AEREWARD$ card to earn rewards for your purchase.Learn More about AEREWARD$ | | ccType_2-default +UNKNOWN_TYPE | aeRewardsSignUp | Sign up now and receive 25 points just for signing up! Learn More | true | ccType_2-default +UNKNOWN_TYPE | aeAccount | Create my AE Account.CLOSECreate an AE Account to:Save Your Personal Info For Next TimeCheckout FasterTrack An Order Quicker Sign up now and receive 25 points just for signing up! Learn More | true | ccType_2-default +UNKNOWN_TYPE | aeAccountPass | Password (6-15 Letters & Numbers) | | ccType_2-default +UNKNOWN_TYPE | aeAccountPassConfirm | Confirm Password | | ccType_2-default +UNKNOWN_TYPE | birthMonthBillAddField | Birthday: CLOSEWe'd love to wish you a happy birthday when it's time! However, you need to be 13 or older to create an account. | | ccType_2-default +UNKNOWN_TYPE | birthDayBillAddField | Birthday: CLOSEWe'd love to wish you a happy birthday when it's time! However, you need to be 13 or older to create an account. | | ccType_2-default +UNKNOWN_TYPE | birthYearBillAddField | Birthday: CLOSEWe'd love to wish you a happy birthday when it's time! However, you need to be 13 or older to create an account. | | ccType_2-default +UNKNOWN_TYPE | aeEmail | AE | on | ccType_2-default +UNKNOWN_TYPE | aerieEmail | aerie | on | ccType_2-default +UNKNOWN_TYPE | kidsEmail | 77kids | on | ccType_2-default +UNKNOWN_TYPE | loyaltyTerms | I accept the Terms & Conditions | | ccType_2-default UNKNOWN_TYPE | CouponCode | Discount Code: CLOSEApplying DiscountsEnter your 8 or 20 digit code into the Discount Code field without any spaces, then click the Apply Discount button.Learn More about how to find and apply discounts | | CouponCode_1-default
diff --git a/components/test/data/autofill/heuristics/output/019_checkout_bedbathandbeyond.com.out b/components/test/data/autofill/heuristics/output/019_checkout_bedbathandbeyond.com.out index a6f8fa8..4c3f829 100644 --- a/components/test/data/autofill/heuristics/output/019_checkout_bedbathandbeyond.com.out +++ b/components/test/data/autofill/heuristics/output/019_checkout_bedbathandbeyond.com.out
@@ -21,19 +21,19 @@ UNKNOWN_TYPE | promo_email_flag | Receive information on special offers and new arrivals at Bed Bath & Beyond. | Y | first_nm_1-default UNKNOWN_TYPE | mobile_offers_opt_in | Bed Bath & Beyond may deliver mobile offers and promotions via text message in the future. Check the box if you would like to receive these mobile offers and promotions on your mobile phone. View our Privacy policy. Message & data rates may apply. | Y | first_nm_1-default UNKNOWN_TYPE | shipping_options | Same as billing information | B | first_nm_1-default -NAME_FIRST | ship_first_nm | *First name | | ship_first_nm_1-default -NAME_MIDDLE | ship_mid_nm | Middle name | | ship_first_nm_1-default -NAME_LAST | ship_last_nm | *Last name | | ship_first_nm_1-default -COMPANY_NAME | ship_company | Company name | | ship_first_nm_1-default -ADDRESS_HOME_LINE1 | ship_addr1 | *Address 1 (No P.O. Boxes) | | ship_first_nm_1-default -ADDRESS_HOME_LINE2 | ship_addr2 | Address 2 | | ship_first_nm_1-default -ADDRESS_HOME_CITY | ship_city | *City | | ship_first_nm_1-default -ADDRESS_HOME_STATE | ship_addr_state | *State | | ship_first_nm_1-default -ADDRESS_HOME_ZIP | ship_zip | *Zip Code | | ship_first_nm_1-default -PHONE_HOME_CITY_CODE | ship_day_phone_part1 | *Day phone | | ship_first_nm_1-default -PHONE_HOME_NUMBER | ship_day_phone_part2 | *Day phone | | ship_first_nm_1-default -PHONE_HOME_NUMBER | ship_day_phone_part3 | *Day phone | | ship_first_nm_1-default -PHONE_HOME_CITY_CODE | ship_eve_phone_part1 | Evening phone | | ship_first_nm_1-default -PHONE_HOME_NUMBER | ship_eve_phone_part2 | Evening phone | | ship_first_nm_1-default -PHONE_HOME_NUMBER | ship_eve_phone_part3 | Evening phone | | ship_first_nm_1-default +NAME_FIRST | ship_first_nm | *First name | | ship_first_nm_2-default +NAME_MIDDLE | ship_mid_nm | Middle name | | ship_first_nm_2-default +NAME_LAST | ship_last_nm | *Last name | | ship_first_nm_2-default +COMPANY_NAME | ship_company | Company name | | ship_first_nm_2-default +ADDRESS_HOME_LINE1 | ship_addr1 | *Address 1 (No P.O. Boxes) | | ship_first_nm_2-default +ADDRESS_HOME_LINE2 | ship_addr2 | Address 2 | | ship_first_nm_2-default +ADDRESS_HOME_CITY | ship_city | *City | | ship_first_nm_2-default +ADDRESS_HOME_STATE | ship_addr_state | *State | | ship_first_nm_2-default +ADDRESS_HOME_ZIP | ship_zip | *Zip Code | | ship_first_nm_2-default +PHONE_HOME_CITY_CODE | ship_day_phone_part1 | *Day phone | | ship_first_nm_2-default +PHONE_HOME_NUMBER | ship_day_phone_part2 | *Day phone | | ship_first_nm_2-default +PHONE_HOME_NUMBER | ship_day_phone_part3 | *Day phone | | ship_first_nm_2-default +PHONE_HOME_CITY_CODE | ship_eve_phone_part1 | Evening phone | | ship_first_nm_2-default +PHONE_HOME_NUMBER | ship_eve_phone_part2 | Evening phone | | ship_first_nm_2-default +PHONE_HOME_NUMBER | ship_eve_phone_part3 | Evening phone | | ship_first_nm_2-default UNKNOWN_TYPE | email | Privacy policy - Your Privacy Rights | enter your email address | email_1-default
diff --git a/components/test/data/autofill/heuristics/output/020_checkout_cafepress.com.out b/components/test/data/autofill/heuristics/output/020_checkout_cafepress.com.out index 2dd4150..bc4a863 100644 --- a/components/test/data/autofill/heuristics/output/020_checkout_cafepress.com.out +++ b/components/test/data/autofill/heuristics/output/020_checkout_cafepress.com.out
@@ -12,25 +12,25 @@ UNKNOWN_TYPE | cbStoreSpecial | | on | BillName_1-default UNKNOWN_TYPE | ShipDestination | billaddress | billaddress | BillName_1-default UNKNOWN_TYPE | ShipDestination | Ship to my billing address | shipaddress | BillName_1-default -NAME_FULL | ShipName | Recipient Name* | | ShipName_1-default -ADDRESS_HOME_COUNTRY | ShipCountry | Country* | UNITED STATES | ShipName_1-default -ADDRESS_HOME_LINE1 | ShipStreet1 | Address* | | ShipName_1-default -ADDRESS_HOME_LINE2 | ShipStreet2 | Address* | | ShipName_1-default -ADDRESS_HOME_CITY | ShipCity | Town/City* | | ShipName_1-default -ADDRESS_HOME_STATE | ShipState | State/Province* | | ShipName_1-default -UNKNOWN_TYPE | ShipStateOther | State/Province* | | ShipName_1-default -ADDRESS_HOME_ZIP | ShipZip | Zip/Postal Code* | | ShipName_1-default -UNKNOWN_TYPE | ShowGiftMsg | This is a gift order. Check this box to see gift options. | on | ShipName_1-default -UNKNOWN_TYPE | GiftMessage | One message per order You have | | ShipName_1-default -UNKNOWN_TYPE | countdown | You have | 300 | ShipName_1-default -UNKNOWN_TYPE | ApplyGiftWrap | (+$0.00) | on | ShipName_1-default -UNKNOWN_TYPE | txtCoupon | Apply Promo Code | | ShipName_1-default -UNKNOWN_TYPE | PaymentMethod | PayByCafeCash | PayByCafeCash | ShipName_1-default -UNKNOWN_TYPE | PaymentMethod | PayByGC | PayByGC | ShipName_1-default -UNKNOWN_TYPE | PaymentMethod | PayByCCGC | PayByCCGC | ShipName_1-default -UNKNOWN_TYPE | PaymentMethod | PayByCC | PayByCC | ShipName_1-default +NAME_FULL | ShipName | Recipient Name* | | ShipName_2-default +ADDRESS_HOME_COUNTRY | ShipCountry | Country* | UNITED STATES | ShipName_2-default +ADDRESS_HOME_LINE1 | ShipStreet1 | Address* | | ShipName_2-default +ADDRESS_HOME_LINE2 | ShipStreet2 | Address* | | ShipName_2-default +ADDRESS_HOME_CITY | ShipCity | Town/City* | | ShipName_2-default +ADDRESS_HOME_STATE | ShipState | State/Province* | | ShipName_2-default +UNKNOWN_TYPE | ShipStateOther | State/Province* | | ShipName_2-default +ADDRESS_HOME_ZIP | ShipZip | Zip/Postal Code* | | ShipName_2-default +UNKNOWN_TYPE | ShowGiftMsg | This is a gift order. Check this box to see gift options. | on | ShipName_2-default +UNKNOWN_TYPE | GiftMessage | One message per order You have | | ShipName_2-default +UNKNOWN_TYPE | countdown | You have | 300 | ShipName_2-default +UNKNOWN_TYPE | ApplyGiftWrap | (+$0.00) | on | ShipName_2-default +UNKNOWN_TYPE | txtCoupon | Apply Promo Code | | ShipName_2-default +UNKNOWN_TYPE | PaymentMethod | PayByCafeCash | PayByCafeCash | ShipName_2-default +UNKNOWN_TYPE | PaymentMethod | PayByGC | PayByGC | ShipName_2-default +UNKNOWN_TYPE | PaymentMethod | PayByCCGC | PayByCCGC | ShipName_2-default +UNKNOWN_TYPE | PaymentMethod | PayByCC | PayByCC | ShipName_2-default CREDIT_CARD_NUMBER | txtCCAccount | Credit Card No.* | | credit-card-cc CREDIT_CARD_EXP_MONTH | ccExp$MonthDrop | Expiration Date* | 06 (June) | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | ccExp$YearDrop | Expiration Date* | 2011 | credit-card-cc -UNKNOWN_TYPE | PaymentMethod | Expiration Date* | PayByCheck | ShipName_1-default -UNKNOWN_TYPE | PaymentMethod | PayByPayPal | PayByPayPal | ShipName_1-default +UNKNOWN_TYPE | PaymentMethod | Expiration Date* | PayByCheck | ShipName_2-default +UNKNOWN_TYPE | PaymentMethod | PayByPayPal | PayByPayPal | ShipName_2-default
diff --git a/components/test/data/autofill/heuristics/output/021_checkout_cduniverse.com.out b/components/test/data/autofill/heuristics/output/021_checkout_cduniverse.com.out index c2e739c..e9a93f0 100644 --- a/components/test/data/autofill/heuristics/output/021_checkout_cduniverse.com.out +++ b/components/test/data/autofill/heuristics/output/021_checkout_cduniverse.com.out
@@ -11,12 +11,12 @@ PHONE_HOME_WHOLE_NUMBER | HT_phone | Phone | | HT_First_Name_1-default ADDRESS_HOME_COUNTRY | HT_Bill_Country | Country | USA | HT_First_Name_1-default NAME_FULL | HT_Ship_Name | Full Name | | HT_First_Name_1-default -ADDRESS_HOME_LINE1 | HT_Ship_Address1 | Address 1 | | HT_Ship_Address1_1-default -ADDRESS_HOME_LINE2 | HT_Ship_Address2 | Address 2 | | HT_Ship_Address1_1-default -ADDRESS_HOME_CITY | HT_Ship_City | City | | HT_Ship_Address1_1-default -ADDRESS_HOME_STATE | HT_Ship_State | State/Province | | HT_Ship_Address1_1-default -ADDRESS_HOME_ZIP | HT_Ship_Zip | Zip/Postal Code | | HT_Ship_Address1_1-default -ADDRESS_HOME_COUNTRY | HT_Ship_Country | Country | | HT_Ship_Address1_1-default -UNKNOWN_TYPE | HT_OK_to_email | Yes | -1 | HT_Ship_Address1_1-default -UNKNOWN_TYPE | HT_OK_to_email | No | 0 | HT_Ship_Address1_1-default -UNKNOWN_TYPE | HT_PrefersHTML | I prefer to receive HTML formatted email when available. | on | HT_Ship_Address1_1-default +ADDRESS_HOME_LINE1 | HT_Ship_Address1 | Address 1 | | HT_Ship_Address1_2-default +ADDRESS_HOME_LINE2 | HT_Ship_Address2 | Address 2 | | HT_Ship_Address1_2-default +ADDRESS_HOME_CITY | HT_Ship_City | City | | HT_Ship_Address1_2-default +ADDRESS_HOME_STATE | HT_Ship_State | State/Province | | HT_Ship_Address1_2-default +ADDRESS_HOME_ZIP | HT_Ship_Zip | Zip/Postal Code | | HT_Ship_Address1_2-default +ADDRESS_HOME_COUNTRY | HT_Ship_Country | Country | | HT_Ship_Address1_2-default +UNKNOWN_TYPE | HT_OK_to_email | Yes | -1 | HT_Ship_Address1_2-default +UNKNOWN_TYPE | HT_OK_to_email | No | 0 | HT_Ship_Address1_2-default +UNKNOWN_TYPE | HT_PrefersHTML | I prefer to receive HTML formatted email when available. | on | HT_Ship_Address1_2-default
diff --git a/components/test/data/autofill/heuristics/output/022_checkout_crutchfield.com.out b/components/test/data/autofill/heuristics/output/022_checkout_crutchfield.com.out index 916931b9..2fba472 100644 --- a/components/test/data/autofill/heuristics/output/022_checkout_crutchfield.com.out +++ b/components/test/data/autofill/heuristics/output/022_checkout_crutchfield.com.out
@@ -11,13 +11,13 @@ UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$chbox2 | Send me exclusive offers, deals and expert reviews. | on | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$same | Same as billing address. | same | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$giftOrder | Prices will not appear on invoice. This order is a gift. | gift | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default -NAME_FIRST | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname | First Name | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default -NAME_MIDDLE_INITIAL | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingMi | M.I. | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default -NAME_LAST | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingLastname | Last Name | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default -COMPANY_NAME | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingAddress2 | Company | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default -ADDRESS_HOME_LINE1 | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingAddress1 | Address | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default -ADDRESS_HOME_CITY | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingCity | City | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default -ADDRESS_HOME_STATE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingState | State | Select Your State | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default -ADDRESS_HOME_ZIP | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingZip | Zip/Postal Code | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default -PHONE_HOME_WHOLE_NUMBER | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingPhone | Shipping Phone | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default -UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$customerID | Customer # | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default +NAME_FIRST | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname | First Name | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_2-default +NAME_MIDDLE_INITIAL | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingMi | M.I. | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_2-default +NAME_LAST | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingLastname | Last Name | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_2-default +COMPANY_NAME | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingAddress2 | Company | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_2-default +ADDRESS_HOME_LINE1 | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingAddress1 | Address | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_2-default +ADDRESS_HOME_CITY | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingCity | City | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_2-default +ADDRESS_HOME_STATE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingState | State | Select Your State | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_2-default +ADDRESS_HOME_ZIP | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingZip | Zip/Postal Code | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_2-default +PHONE_HOME_WHOLE_NUMBER | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingPhone | Shipping Phone | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_2-default +UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$customerID | Customer # | | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_2-default
diff --git a/components/test/data/autofill/heuristics/output/023_checkout_gamestop.com.out b/components/test/data/autofill/heuristics/output/023_checkout_gamestop.com.out index 2e5e9e1f..c02ab128 100644 --- a/components/test/data/autofill/heuristics/output/023_checkout_gamestop.com.out +++ b/components/test/data/autofill/heuristics/output/023_checkout_gamestop.com.out
@@ -11,13 +11,13 @@ EMAIL_ADDRESS | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$txtEmailAddress | Purchaser's Email: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default EMAIL_ADDRESS | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$txtEmailAddressConfirm | Confirm Email: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default UNKNOWN_TYPE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$chkEmailOptIn | Confirm Email: | on | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default -NAME_FIRST | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName | First Name: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default -NAME_LAST | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textLastName | Last Name: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default -ADDRESS_HOME_LINE1 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textAddressLine1 | Address 1: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default -ADDRESS_HOME_LINE2 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textAddressLine2 | Address 2: (optional) | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default -ADDRESS_HOME_CITY | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textCity | City: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default -ADDRESS_HOME_STATE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$ddlState | State/Province: | -1 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default -ADDRESS_HOME_ZIP | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textZip | Zip/Postal: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default -ADDRESS_HOME_COUNTRY | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$ddlCountry | Country: | US | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default -PHONE_HOME_WHOLE_NUMBER | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textPhoneNumberDaytime | Phone Number: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default +NAME_FIRST | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName | First Name: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_2-default +NAME_LAST | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textLastName | Last Name: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_2-default +ADDRESS_HOME_LINE1 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textAddressLine1 | Address 1: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_2-default +ADDRESS_HOME_LINE2 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textAddressLine2 | Address 2: (optional) | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_2-default +ADDRESS_HOME_CITY | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textCity | City: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_2-default +ADDRESS_HOME_STATE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$ddlState | State/Province: | -1 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_2-default +ADDRESS_HOME_ZIP | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textZip | Zip/Postal: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_2-default +ADDRESS_HOME_COUNTRY | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$ddlCountry | Country: | US | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_2-default +PHONE_HOME_WHOLE_NUMBER | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textPhoneNumberDaytime | Phone Number: | | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_2-default UNKNOWN_TYPE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$chkSameAsBillingAddress | | on | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
diff --git a/components/test/data/autofill/heuristics/output/025_checkout_hsn.com.out b/components/test/data/autofill/heuristics/output/025_checkout_hsn.com.out index 0b32a50..6c8a086f 100644 --- a/components/test/data/autofill/heuristics/output/025_checkout_hsn.com.out +++ b/components/test/data/autofill/heuristics/output/025_checkout_hsn.com.out
@@ -18,14 +18,14 @@ EMAIL_ADDRESS | Body$NewEmailAddress2 | Email Address | | Body$BillingIsShippingCheckboxB_1-default UNKNOWN_TYPE | Body$WeeklyNewsletterSignup12 | Email me weekly HSN newsletters and special offers | on | Body$BillingIsShippingCheckboxB_1-default UNKNOWN_TYPE | Body$TSNewsletterSignup2 | Email me the daily Today's Special | on | Body$BillingIsShippingCheckboxB_1-default -NAME_FIRST | Body$ShippingAddress$_firstName | First Name | | Body$ShippingAddress$_firstName_1-default -NAME_LAST | Body$ShippingAddress$_lastName | Last Name | | Body$ShippingAddress$_firstName_1-default -ADDRESS_HOME_LINE1 | Body$ShippingAddress$_address1 | Address Line 1 | | Body$ShippingAddress$_firstName_1-default -ADDRESS_HOME_LINE2 | Body$ShippingAddress$_address2 | Address Line 2(optional) | | Body$ShippingAddress$_firstName_1-default -ADDRESS_HOME_CITY | Body$ShippingAddress$_city | City | | Body$ShippingAddress$_firstName_1-default -ADDRESS_HOME_STATE | Body$ShippingAddress$_state | State | | Body$ShippingAddress$_firstName_1-default -ADDRESS_HOME_ZIP | Body$ShippingAddress$_zipcode | Zip Code | | Body$ShippingAddress$_firstName_1-default -PHONE_HOME_WHOLE_NUMBER | Body$ShippingAddress$_telephone | Phone Number | | Body$ShippingAddress$_firstName_1-default +NAME_FIRST | Body$ShippingAddress$_firstName | First Name | | Body$ShippingAddress$_firstName_2-default +NAME_LAST | Body$ShippingAddress$_lastName | Last Name | | Body$ShippingAddress$_firstName_2-default +ADDRESS_HOME_LINE1 | Body$ShippingAddress$_address1 | Address Line 1 | | Body$ShippingAddress$_firstName_2-default +ADDRESS_HOME_LINE2 | Body$ShippingAddress$_address2 | Address Line 2(optional) | | Body$ShippingAddress$_firstName_2-default +ADDRESS_HOME_CITY | Body$ShippingAddress$_city | City | | Body$ShippingAddress$_firstName_2-default +ADDRESS_HOME_STATE | Body$ShippingAddress$_state | State | | Body$ShippingAddress$_firstName_2-default +ADDRESS_HOME_ZIP | Body$ShippingAddress$_zipcode | Zip Code | | Body$ShippingAddress$_firstName_2-default +PHONE_HOME_WHOLE_NUMBER | Body$ShippingAddress$_telephone | Phone Number | | Body$ShippingAddress$_firstName_2-default UNKNOWN_TYPE | PaymentTypeSelection | Pay with a Credit or Debit Card | 0 | Body$BillingIsShippingCheckboxB_1-default CREDIT_CARD_NUMBER | Body$CCNumber | Card Number | | credit-card-cc CREDIT_CARD_EXP_MONTH | Body$CCExpirationDateMonth | Expiration Date | 0 | credit-card-cc
diff --git a/components/test/data/autofill/heuristics/output/028_checkout_jr.com.out b/components/test/data/autofill/heuristics/output/028_checkout_jr.com.out index bea2013..1366bb9 100644 --- a/components/test/data/autofill/heuristics/output/028_checkout_jr.com.out +++ b/components/test/data/autofill/heuristics/output/028_checkout_jr.com.out
@@ -11,18 +11,18 @@ UNKNOWN_TYPE | customer.optIn | Yes, send me J&R's promotional email newsletter. | on | billingAddress.firstName_1-default UNKNOWN_TYPE | storePickup | Pickup In-Store (Park Row, New York NY) | on | billingAddress.firstName_1-default UNKNOWN_TYPE | shipToBillingAddress | Ship to my billing address | on | billingAddress.firstName_1-default -NAME_FIRST | shippingAddress.firstName | | | shippingAddress.firstName_1-default -NAME_LAST | shippingAddress.lastName | | | shippingAddress.firstName_1-default -ADDRESS_HOME_LINE1 | shippingAddress.address1 | | | shippingAddress.firstName_1-default -ADDRESS_HOME_LINE2 | shippingAddress.address2 | Street address or P.O. box | | shippingAddress.firstName_1-default -ADDRESS_HOME_CITY | shippingAddress.city | | | shippingAddress.firstName_1-default -ADDRESS_HOME_STATE | shippingAddress.stateCode | | XX | shippingAddress.firstName_1-default -ADDRESS_HOME_ZIP | shippingAddress.postalCode | | | shippingAddress.firstName_1-default -ADDRESS_HOME_COUNTRY | shippingAddress.country | | US | shippingAddress.firstName_1-default -PHONE_HOME_WHOLE_NUMBER | shippingAddress.phoneNumber | | | shippingAddress.firstName_1-default -UNKNOWN_TYPE | customOrderHeader.internationalBilling | International Billing | | shippingAddress.firstName_1-default -UNKNOWN_TYPE | customOrderHeader.salespersonNumber | Salesperson Number | | shippingAddress.firstName_1-default -UNKNOWN_TYPE | customOrderHeader.giftFromName | Gift From | | shippingAddress.firstName_1-default -UNKNOWN_TYPE | customOrderHeader.giftMessage | Gift Message | | shippingAddress.firstName_1-default -EMAIL_ADDRESS | customOrderHeader.giftEmailAddress | Gift Email | | shippingAddress.firstName_1-default -UNKNOWN_TYPE | customOrderHeader.giftHidePrices | Hide prices on the recipient's invoice and products on gift email. | on | shippingAddress.firstName_1-default +NAME_FIRST | shippingAddress.firstName | | | shippingAddress.firstName_2-default +NAME_LAST | shippingAddress.lastName | | | shippingAddress.firstName_2-default +ADDRESS_HOME_LINE1 | shippingAddress.address1 | | | shippingAddress.firstName_2-default +ADDRESS_HOME_LINE2 | shippingAddress.address2 | Street address or P.O. box | | shippingAddress.firstName_2-default +ADDRESS_HOME_CITY | shippingAddress.city | | | shippingAddress.firstName_2-default +ADDRESS_HOME_STATE | shippingAddress.stateCode | | XX | shippingAddress.firstName_2-default +ADDRESS_HOME_ZIP | shippingAddress.postalCode | | | shippingAddress.firstName_2-default +ADDRESS_HOME_COUNTRY | shippingAddress.country | | US | shippingAddress.firstName_2-default +PHONE_HOME_WHOLE_NUMBER | shippingAddress.phoneNumber | | | shippingAddress.firstName_2-default +UNKNOWN_TYPE | customOrderHeader.internationalBilling | International Billing | | shippingAddress.firstName_2-default +UNKNOWN_TYPE | customOrderHeader.salespersonNumber | Salesperson Number | | shippingAddress.firstName_2-default +UNKNOWN_TYPE | customOrderHeader.giftFromName | Gift From | | shippingAddress.firstName_2-default +UNKNOWN_TYPE | customOrderHeader.giftMessage | Gift Message | | shippingAddress.firstName_2-default +EMAIL_ADDRESS | customOrderHeader.giftEmailAddress | Gift Email | | shippingAddress.firstName_2-default +UNKNOWN_TYPE | customOrderHeader.giftHidePrices | Hide prices on the recipient's invoice and products on gift email. | on | shippingAddress.firstName_2-default
diff --git a/components/test/data/autofill/heuristics/output/029_checkout_kohls.com.out b/components/test/data/autofill/heuristics/output/029_checkout_kohls.com.out index e2899feb..76d33434 100644 --- a/components/test/data/autofill/heuristics/output/029_checkout_kohls.com.out +++ b/components/test/data/autofill/heuristics/output/029_checkout_kohls.com.out
@@ -15,15 +15,15 @@ UNKNOWN_TYPE | EMAIL_OPT_STATUS_ARRAY<>opt_status | Yes, sign me up for Sale Alerts. (optional) | true | BILL_TO_ADDRESS<>firstName_1-default UNKNOWN_TYPE | indShipIsBillTo | Yes | true | BILL_TO_ADDRESS<>firstName_1-default UNKNOWN_TYPE | indShipIsBillTo | No | false | BILL_TO_ADDRESS<>firstName_1-default -NAME_FIRST | SHIP_TO_ADDRESS<>firstName | First Name: | | SHIP_TO_ADDRESS<>firstName_1-default -NAME_LAST | SHIP_TO_ADDRESS<>lastName | Last Name: | | SHIP_TO_ADDRESS<>firstName_1-default -ADDRESS_HOME_LINE1 | SHIP_TO_ADDRESS<>address1 | Address: | | SHIP_TO_ADDRESS<>firstName_1-default -ADDRESS_HOME_LINE2 | SHIP_TO_ADDRESS<>address2 | Apt. or Suite #: | | SHIP_TO_ADDRESS<>firstName_1-default -ADDRESS_HOME_CITY | SHIP_TO_ADDRESS<>city | City: | | SHIP_TO_ADDRESS<>firstName_1-default -ADDRESS_HOME_STATE | SHIP_TO_ADDRESS<>state_cd | State: | | SHIP_TO_ADDRESS<>firstName_1-default -ADDRESS_HOME_ZIP | SHIP_TO_ADDRESS<>postal | ZIP Code: | | SHIP_TO_ADDRESS<>firstName_1-default -PHONE_HOME_CITY_CODE | SHIP_PHONE<>areacode | Area Code | | SHIP_TO_ADDRESS<>firstName_1-default -PHONE_HOME_NUMBER | SHIP_PHONE<>exchange | Exchange | | SHIP_TO_ADDRESS<>firstName_1-default -PHONE_HOME_EXTENSION | SHIP_PHONE<>extension | Extension | | SHIP_TO_ADDRESS<>firstName_1-default -PHONE_HOME_WHOLE_NUMBER | ship_phone | Contact Phone: | | SHIP_TO_ADDRESS<>firstName_1-default -UNKNOWN_TYPE | validShippingMethodList | Shipping Method: | 7037973929746575 | SHIP_TO_ADDRESS<>firstName_1-default +NAME_FIRST | SHIP_TO_ADDRESS<>firstName | First Name: | | SHIP_TO_ADDRESS<>firstName_2-default +NAME_LAST | SHIP_TO_ADDRESS<>lastName | Last Name: | | SHIP_TO_ADDRESS<>firstName_2-default +ADDRESS_HOME_LINE1 | SHIP_TO_ADDRESS<>address1 | Address: | | SHIP_TO_ADDRESS<>firstName_2-default +ADDRESS_HOME_LINE2 | SHIP_TO_ADDRESS<>address2 | Apt. or Suite #: | | SHIP_TO_ADDRESS<>firstName_2-default +ADDRESS_HOME_CITY | SHIP_TO_ADDRESS<>city | City: | | SHIP_TO_ADDRESS<>firstName_2-default +ADDRESS_HOME_STATE | SHIP_TO_ADDRESS<>state_cd | State: | | SHIP_TO_ADDRESS<>firstName_2-default +ADDRESS_HOME_ZIP | SHIP_TO_ADDRESS<>postal | ZIP Code: | | SHIP_TO_ADDRESS<>firstName_2-default +PHONE_HOME_CITY_CODE | SHIP_PHONE<>areacode | Area Code | | SHIP_TO_ADDRESS<>firstName_2-default +PHONE_HOME_NUMBER | SHIP_PHONE<>exchange | Exchange | | SHIP_TO_ADDRESS<>firstName_2-default +PHONE_HOME_EXTENSION | SHIP_PHONE<>extension | Extension | | SHIP_TO_ADDRESS<>firstName_2-default +PHONE_HOME_WHOLE_NUMBER | ship_phone | Contact Phone: | | SHIP_TO_ADDRESS<>firstName_2-default +UNKNOWN_TYPE | validShippingMethodList | Shipping Method: | 7037973929746575 | SHIP_TO_ADDRESS<>firstName_2-default
diff --git a/components/test/data/autofill/heuristics/output/030_checkout_lowes.com.out b/components/test/data/autofill/heuristics/output/030_checkout_lowes.com.out index 5e535de..4a4597a 100644 --- a/components/test/data/autofill/heuristics/output/030_checkout_lowes.com.out +++ b/components/test/data/autofill/heuristics/output/030_checkout_lowes.com.out
@@ -5,16 +5,16 @@ NAME_FIRST | firstName | First Name: | | country_1-default NAME_LAST | lastName | Last Name: | | country_1-default COMPANY_NAME | addressField1 | Company Name: | | country_1-default -ADDRESS_HOME_LINE1 | address1 | Address Line 1: | | address1_1-default -ADDRESS_HOME_LINE2 | address2 | Address Line 2: | | address1_1-default -ADDRESS_HOME_CITY | city | City: | | address1_1-default -ADDRESS_HOME_STATE | state | State: | | address1_1-default -ADDRESS_HOME_ZIP | zipCode | ZIP Code: | | address1_1-default -ADDRESS_HOME_CITY | taxGeoCode | Municipality: As an additional way to make sure you receive your order, we ask that you select the name of your municipality (city, town, borough, village, etc.) followed by the county, township, or parish in which you reside. | | taxGeoCode_1-default -UNKNOWN_TYPE | billingAddress | This is also my billing address. | on | taxGeoCode_1-default -EMAIL_ADDRESS | email1 | E-mail Address: | | taxGeoCode_1-default -PHONE_HOME_CITY_CODE | billphone1 | Contact Phone: | | taxGeoCode_1-default -PHONE_HOME_NUMBER | billphone2 | Contact Phone: | | taxGeoCode_1-default -PHONE_HOME_NUMBER | billphone3 | Contact Phone: | | taxGeoCode_1-default -EMAIL_ADDRESS | selfAddress | Please enter the phone number and e-mail address associated with this billing address.E-mail Address: Contact Phone: | 0 | selfAddress_1-default -UNKNOWN_TYPE | save-address | on | on | selfAddress_1-default +ADDRESS_HOME_LINE1 | address1 | Address Line 1: | | address1_2-default +ADDRESS_HOME_LINE2 | address2 | Address Line 2: | | address1_2-default +ADDRESS_HOME_CITY | city | City: | | address1_2-default +ADDRESS_HOME_STATE | state | State: | | address1_2-default +ADDRESS_HOME_ZIP | zipCode | ZIP Code: | | address1_2-default +ADDRESS_HOME_CITY | taxGeoCode | Municipality: As an additional way to make sure you receive your order, we ask that you select the name of your municipality (city, town, borough, village, etc.) followed by the county, township, or parish in which you reside. | | taxGeoCode_3-default +UNKNOWN_TYPE | billingAddress | This is also my billing address. | on | taxGeoCode_3-default +EMAIL_ADDRESS | email1 | E-mail Address: | | taxGeoCode_3-default +PHONE_HOME_CITY_CODE | billphone1 | Contact Phone: | | taxGeoCode_3-default +PHONE_HOME_NUMBER | billphone2 | Contact Phone: | | taxGeoCode_3-default +PHONE_HOME_NUMBER | billphone3 | Contact Phone: | | taxGeoCode_3-default +EMAIL_ADDRESS | selfAddress | Please enter the phone number and e-mail address associated with this billing address.E-mail Address: Contact Phone: | 0 | selfAddress_4-default +UNKNOWN_TYPE | save-address | on | on | selfAddress_4-default
diff --git a/components/test/data/autofill/heuristics/output/032_checkout_nordstrom.com.out b/components/test/data/autofill/heuristics/output/032_checkout_nordstrom.com.out index 4f29b3f..6ee1251 100644 --- a/components/test/data/autofill/heuristics/output/032_checkout_nordstrom.com.out +++ b/components/test/data/autofill/heuristics/output/032_checkout_nordstrom.com.out
@@ -12,13 +12,13 @@ ADDRESS_HOME_ZIP | ctl00$mainContentPlaceHolder$billingAddressForm$zipCode | Zip/Postal Code | | ctl00$mainContentPlaceHolder$emailAddress_1-default ADDRESS_HOME_COUNTRY | ctl00$mainContentPlaceHolder$billingAddressForm$country | Country | 249 | ctl00$mainContentPlaceHolder$emailAddress_1-default UNKNOWN_TYPE | ctl00$mainContentPlaceHolder$shippingSameAsBilling | | on | ctl00$mainContentPlaceHolder$emailAddress_1-default -NAME_FIRST | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName | First Name | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default -NAME_MIDDLE_INITIAL | ctl00$mainContentPlaceHolder$shippingAddressForm$middleInitial | M.I. | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default -NAME_LAST | ctl00$mainContentPlaceHolder$shippingAddressForm$lastName | Last Name | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default -ADDRESS_HOME_LINE1 | ctl00$mainContentPlaceHolder$shippingAddressForm$address1 | Address | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default -ADDRESS_HOME_LINE2 | ctl00$mainContentPlaceHolder$shippingAddressForm$address2 | Address | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default -ADDRESS_HOME_CITY | ctl00$mainContentPlaceHolder$shippingAddressForm$city | City | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default -ADDRESS_HOME_STATE | ctl00$mainContentPlaceHolder$shippingAddressForm$stateProvince | State/Province | -1 | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default -ADDRESS_HOME_ZIP | ctl00$mainContentPlaceHolder$shippingAddressForm$zipCode | Zip/Postal Code | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default -UNKNOWN_TYPE | ctl00$mainContentPlaceHolder$registrationPassword | Password | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default -UNKNOWN_TYPE | ctl00$mainContentPlaceHolder$registrationPasswordConfirm | Confirm Password | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default +NAME_FIRST | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName | First Name | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_2-default +NAME_MIDDLE_INITIAL | ctl00$mainContentPlaceHolder$shippingAddressForm$middleInitial | M.I. | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_2-default +NAME_LAST | ctl00$mainContentPlaceHolder$shippingAddressForm$lastName | Last Name | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_2-default +ADDRESS_HOME_LINE1 | ctl00$mainContentPlaceHolder$shippingAddressForm$address1 | Address | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_2-default +ADDRESS_HOME_LINE2 | ctl00$mainContentPlaceHolder$shippingAddressForm$address2 | Address | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_2-default +ADDRESS_HOME_CITY | ctl00$mainContentPlaceHolder$shippingAddressForm$city | City | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_2-default +ADDRESS_HOME_STATE | ctl00$mainContentPlaceHolder$shippingAddressForm$stateProvince | State/Province | -1 | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_2-default +ADDRESS_HOME_ZIP | ctl00$mainContentPlaceHolder$shippingAddressForm$zipCode | Zip/Postal Code | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_2-default +UNKNOWN_TYPE | ctl00$mainContentPlaceHolder$registrationPassword | Password | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_2-default +UNKNOWN_TYPE | ctl00$mainContentPlaceHolder$registrationPasswordConfirm | Confirm Password | | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_2-default
diff --git a/components/test/data/autofill/heuristics/output/034_checkout_overstock.com.out b/components/test/data/autofill/heuristics/output/034_checkout_overstock.com.out index 8717fa0..e62f8912 100644 --- a/components/test/data/autofill/heuristics/output/034_checkout_overstock.com.out +++ b/components/test/data/autofill/heuristics/output/034_checkout_overstock.com.out
@@ -9,41 +9,41 @@ PHONE_HOME_WHOLE_NUMBER | BillingEveningPhone | Evening Phone | | BillingFirstName_1-default UNKNOWN_TYPE | checkbox2 | This order is being sent as a gift | on | BillingFirstName_1-default UNKNOWN_TYPE | diffShip | My shipping address is the same as my billing address | on | BillingFirstName_1-default -NAME_FIRST | ShippingFirstName | First Name | | ShippingFirstName_1-default -NAME_LAST | ShippingLastName | Last Name | | ShippingFirstName_1-default -ADDRESS_HOME_LINE1 | lineone | Address Line 1 | 7540 Donegal Dr | ShippingFirstName_1-default -ADDRESS_HOME_LINE2 | linetwo | Address Line 2 | | ShippingFirstName_1-default -UNKNOWN_TYPE | ShippingAddressType | Address Type | H | ShippingFirstName_1-default -ADDRESS_HOME_CITY | city | City | Cupertino | ShippingFirstName_1-default -ADDRESS_HOME_STATE | state | State | CA | ShippingFirstName_1-default -ADDRESS_HOME_ZIP | zip | Zip | 95014 | ShippingFirstName_1-default -UNKNOWN_TYPE | product6496917 | Black-plated Tungsten Carbide Comfort Fit Band (8 mm) Options: 10 1 | GROUND6496917 | ShippingFirstName_1-default -UNKNOWN_TYPE | CC | CreditCardValue | CreditCardValue | ShippingFirstName_1-default +NAME_FIRST | ShippingFirstName | First Name | | ShippingFirstName_2-default +NAME_LAST | ShippingLastName | Last Name | | ShippingFirstName_2-default +ADDRESS_HOME_LINE1 | lineone | Address Line 1 | 7540 Donegal Dr | ShippingFirstName_2-default +ADDRESS_HOME_LINE2 | linetwo | Address Line 2 | | ShippingFirstName_2-default +UNKNOWN_TYPE | ShippingAddressType | Address Type | H | ShippingFirstName_2-default +ADDRESS_HOME_CITY | city | City | Cupertino | ShippingFirstName_2-default +ADDRESS_HOME_STATE | state | State | CA | ShippingFirstName_2-default +ADDRESS_HOME_ZIP | zip | Zip | 95014 | ShippingFirstName_2-default +UNKNOWN_TYPE | product6496917 | Black-plated Tungsten Carbide Comfort Fit Band (8 mm) Options: 10 1 | GROUND6496917 | ShippingFirstName_2-default +UNKNOWN_TYPE | CC | CreditCardValue | CreditCardValue | ShippingFirstName_2-default CREDIT_CARD_NUMBER | CC_number | Credit Card #: | | credit-card-cc CREDIT_CARD_EXP_MONTH | exp_month | Expiration Date: | 0 | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | exp_year | Expiration Date: | | credit-card-cc -UNKNOWN_TYPE | CC | PayPal | PayPal | ShippingFirstName_1-default -UNKNOWN_TYPE | CC | bml | bml | ShippingFirstName_1-default -UNKNOWN_TYPE | UsePromoCode | Use Promo Code | on | ShippingFirstName_1-default -UNKNOWN_TYPE | PromoCode | See Terms | | ShippingFirstName_1-default -UNKNOWN_TYPE | UseGiftCards | Use Gift Card | on | ShippingFirstName_1-default -UNKNOWN_TYPE | GiftCardNumber0 | Gift Card 1: | | ShippingFirstName_1-default -UNKNOWN_TYPE | PINNumber0 | PIN: | | ShippingFirstName_1-default -UNKNOWN_TYPE | GiftCardNumber1 | Gift Card 2: | | ShippingFirstName_1-default -UNKNOWN_TYPE | PINNumber1 | PIN: | | ShippingFirstName_1-default -UNKNOWN_TYPE | GiftCardNumber2 | Gift Card 3: | | ShippingFirstName_1-default -UNKNOWN_TYPE | PINNumber2 | PIN: | | ShippingFirstName_1-default -UNKNOWN_TYPE | GiftCardNumber3 | Gift Card 4: | | ShippingFirstName_1-default -UNKNOWN_TYPE | PINNumber3 | PIN: | | ShippingFirstName_1-default -UNKNOWN_TYPE | GiftCardNumber4 | Gift Card 5: | | ShippingFirstName_1-default -UNKNOWN_TYPE | PINNumber4 | PIN: | | ShippingFirstName_1-default -UNKNOWN_TYPE | GiftCardNumber5 | Gift Card 6: | | ShippingFirstName_1-default -UNKNOWN_TYPE | PINNumber5 | PIN: | | ShippingFirstName_1-default -UNKNOWN_TYPE | GiftCardNumber6 | Gift Card 7: | | ShippingFirstName_1-default -UNKNOWN_TYPE | PINNumber6 | PIN: | | ShippingFirstName_1-default -UNKNOWN_TYPE | GiftCardNumber7 | Gift Card 8: | | ShippingFirstName_1-default -UNKNOWN_TYPE | PINNumber7 | PIN: | | ShippingFirstName_1-default -UNKNOWN_TYPE | GiftCardNumber8 | Gift Card 9: | | ShippingFirstName_1-default -UNKNOWN_TYPE | PINNumber8 | PIN: | | ShippingFirstName_1-default -UNKNOWN_TYPE | GiftCardNumber9 | Gift Card 10: | | ShippingFirstName_1-default -UNKNOWN_TYPE | PINNumber9 | PIN: | | ShippingFirstName_1-default +UNKNOWN_TYPE | CC | PayPal | PayPal | ShippingFirstName_2-default +UNKNOWN_TYPE | CC | bml | bml | ShippingFirstName_2-default +UNKNOWN_TYPE | UsePromoCode | Use Promo Code | on | ShippingFirstName_2-default +UNKNOWN_TYPE | PromoCode | See Terms | | ShippingFirstName_2-default +UNKNOWN_TYPE | UseGiftCards | Use Gift Card | on | ShippingFirstName_2-default +UNKNOWN_TYPE | GiftCardNumber0 | Gift Card 1: | | ShippingFirstName_2-default +UNKNOWN_TYPE | PINNumber0 | PIN: | | ShippingFirstName_2-default +UNKNOWN_TYPE | GiftCardNumber1 | Gift Card 2: | | ShippingFirstName_2-default +UNKNOWN_TYPE | PINNumber1 | PIN: | | ShippingFirstName_2-default +UNKNOWN_TYPE | GiftCardNumber2 | Gift Card 3: | | ShippingFirstName_2-default +UNKNOWN_TYPE | PINNumber2 | PIN: | | ShippingFirstName_2-default +UNKNOWN_TYPE | GiftCardNumber3 | Gift Card 4: | | ShippingFirstName_2-default +UNKNOWN_TYPE | PINNumber3 | PIN: | | ShippingFirstName_2-default +UNKNOWN_TYPE | GiftCardNumber4 | Gift Card 5: | | ShippingFirstName_2-default +UNKNOWN_TYPE | PINNumber4 | PIN: | | ShippingFirstName_2-default +UNKNOWN_TYPE | GiftCardNumber5 | Gift Card 6: | | ShippingFirstName_2-default +UNKNOWN_TYPE | PINNumber5 | PIN: | | ShippingFirstName_2-default +UNKNOWN_TYPE | GiftCardNumber6 | Gift Card 7: | | ShippingFirstName_2-default +UNKNOWN_TYPE | PINNumber6 | PIN: | | ShippingFirstName_2-default +UNKNOWN_TYPE | GiftCardNumber7 | Gift Card 8: | | ShippingFirstName_2-default +UNKNOWN_TYPE | PINNumber7 | PIN: | | ShippingFirstName_2-default +UNKNOWN_TYPE | GiftCardNumber8 | Gift Card 9: | | ShippingFirstName_2-default +UNKNOWN_TYPE | PINNumber8 | PIN: | | ShippingFirstName_2-default +UNKNOWN_TYPE | GiftCardNumber9 | Gift Card 10: | | ShippingFirstName_2-default +UNKNOWN_TYPE | PINNumber9 | PIN: | | ShippingFirstName_2-default
diff --git a/components/test/data/autofill/heuristics/output/037_checkout_qvc.com.out b/components/test/data/autofill/heuristics/output/037_checkout_qvc.com.out index f4e9f7a..519e7d0 100644 --- a/components/test/data/autofill/heuristics/output/037_checkout_qvc.com.out +++ b/components/test/data/autofill/heuristics/output/037_checkout_qvc.com.out
@@ -19,11 +19,11 @@ PHONE_HOME_EXTENSION | BilltoWpExt | Work Phone: | | EmailAddress_1-default UNKNOWN_TYPE | SameAsBilltoCheckbox | Same as Bill-To: | 1 | EmailAddress_1-default UNKNOWN_TYPE | ShiptoFirstName | * Name: | | EmailAddress_1-default -ADDRESS_HOME_LINE1 | ShiptoAddress1 | * Address Line 1: | | ShiptoAddress1_1-default -ADDRESS_HOME_LINE2 | ShiptoAddress2 | Address Line 2: | | ShiptoAddress1_1-default -ADDRESS_HOME_CITY | ShiptoCity | City: | | ShiptoAddress1_1-default -ADDRESS_HOME_STATE | ShiptoState | State/Province: | AL | ShiptoAddress1_1-default -ADDRESS_HOME_ZIP | ShiptoZipCode | * Postal Code: | | ShiptoAddress1_1-default -ADDRESS_HOME_COUNTRY | ShiptoCountry | * Country: | US | ShiptoAddress1_1-default -UNKNOWN_TYPE | ShiptoRadiobutton | This order only | ThisOrderOnly | ShiptoAddress1_1-default -UNKNOWN_TYPE | ShiptoRadiobutton | (Permanent Ship-To)**All future orders | PermanentShipto | ShiptoAddress1_1-default +ADDRESS_HOME_LINE1 | ShiptoAddress1 | * Address Line 1: | | ShiptoAddress1_2-default +ADDRESS_HOME_LINE2 | ShiptoAddress2 | Address Line 2: | | ShiptoAddress1_2-default +ADDRESS_HOME_CITY | ShiptoCity | City: | | ShiptoAddress1_2-default +ADDRESS_HOME_STATE | ShiptoState | State/Province: | AL | ShiptoAddress1_2-default +ADDRESS_HOME_ZIP | ShiptoZipCode | * Postal Code: | | ShiptoAddress1_2-default +ADDRESS_HOME_COUNTRY | ShiptoCountry | * Country: | US | ShiptoAddress1_2-default +UNKNOWN_TYPE | ShiptoRadiobutton | This order only | ThisOrderOnly | ShiptoAddress1_2-default +UNKNOWN_TYPE | ShiptoRadiobutton | (Permanent Ship-To)**All future orders | PermanentShipto | ShiptoAddress1_2-default
diff --git a/components/test/data/autofill/heuristics/output/038_checkout_sears.com.out b/components/test/data/autofill/heuristics/output/038_checkout_sears.com.out index 6c65ecd78..b926011 100644 --- a/components/test/data/autofill/heuristics/output/038_checkout_sears.com.out +++ b/components/test/data/autofill/heuristics/output/038_checkout_sears.com.out
@@ -11,15 +11,15 @@ PHONE_HOME_EXTENSION | shipping_ext1 | Ext. | | address_email_1-default ADDRESS_HOME_STATE | shipping_county | County | UNKNOWN | address_email_1-default UNKNOWN_TYPE | billingAddressCheckBox | Same as Delivery/Shipping Address | on | address_email_1-default -NAME_FIRST | firstName | First Name* | | firstName_1-default -NAME_LAST | lastName | Last Name* | | firstName_1-default -UNKNOWN_TYPE | country | Street Address Line 1* | US | firstName_1-default -ADDRESS_HOME_LINE1 | address1 | Street Address Line 1* | | firstName_1-default -ADDRESS_HOME_LINE2 | address2 | Street Address Line 2 | | firstName_1-default -ADDRESS_HOME_CITY | city | City* | | firstName_1-default -ADDRESS_HOME_STATE | state | State* State* | AL | firstName_1-default -ADDRESS_HOME_ZIP | zipCode | ZIP Code* ZIP Code* | | firstName_1-default -PHONE_HOME_WHOLE_NUMBER | day1 | Phone Number* | | firstName_1-default -PHONE_HOME_EXTENSION | ext1 | Ext. | | firstName_1-default -ADDRESS_HOME_STATE | county | County County | UNKNOWN | firstName_1-default +NAME_FIRST | firstName | First Name* | | firstName_2-default +NAME_LAST | lastName | Last Name* | | firstName_2-default +UNKNOWN_TYPE | country | Street Address Line 1* | US | firstName_2-default +ADDRESS_HOME_LINE1 | address1 | Street Address Line 1* | | firstName_2-default +ADDRESS_HOME_LINE2 | address2 | Street Address Line 2 | | firstName_2-default +ADDRESS_HOME_CITY | city | City* | | firstName_2-default +ADDRESS_HOME_STATE | state | State* State* | AL | firstName_2-default +ADDRESS_HOME_ZIP | zipCode | ZIP Code* ZIP Code* | | firstName_2-default +PHONE_HOME_WHOLE_NUMBER | day1 | Phone Number* | | firstName_2-default +PHONE_HOME_EXTENSION | ext1 | Ext. | | firstName_2-default +ADDRESS_HOME_STATE | county | County County | UNKNOWN | firstName_2-default UNKNOWN_TYPE | KmartSpuSpecialInstr | | | KmartSpuSpecialInstr_1-default
diff --git a/components/test/data/autofill/heuristics/output/047_register_continental.com.out b/components/test/data/autofill/heuristics/output/047_register_continental.com.out index 5bc5b31c..96bb0c68 100644 --- a/components/test/data/autofill/heuristics/output/047_register_continental.com.out +++ b/components/test/data/autofill/heuristics/output/047_register_continental.com.out
@@ -22,23 +22,23 @@ ADDRESS_HOME_COUNTRY | ctl00$ContentInfo$Address$country$cboCountry | Country: | US | ctl00$CustomerHeader$ddlCountries_1-default PHONE_HOME_WHOLE_NUMBER | ctl00$ContentInfo$HomePhone$txtNumber$txtPhone | Home PhoneNumber: | | ctl00$CustomerHeader$ddlCountries_1-default PHONE_HOME_EXTENSION | ctl00$ContentInfo$HomePhone$txtExt$txtPhoneExt | Ext./PIN (optional): | | ctl00$CustomerHeader$ddlCountries_1-default -ADDRESS_HOME_COUNTRY | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry | Country: | US | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry_1-default -PHONE_HOME_WHOLE_NUMBER | ctl00$ContentInfo$BusinessPhone$txtNumber$txtPhone | Business/Other PhoneNumber: | | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry_1-default -PHONE_HOME_EXTENSION | ctl00$ContentInfo$BusinessPhone$txtExt$txtPhoneExt | Ext./PIN (optional): | | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry_1-default -ADDRESS_HOME_COUNTRY | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry | Country: | US | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$HomeAirport$txtAirport | Home Airport (optional): | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -EMAIL_ADDRESS | ctl00$ContentInfo$Email$txtEmail | E-mail Address: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$chkSubOpStatement | | on | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$chkSubopnewsoffers | | on | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$chkSubcocomspecials | | on | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$chkSubtripnotes | | on | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$NewPin$txtNewPin$txtNewPin | New PIN: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$NewPin$txtConfPin$txtConfPin | Re-type New PIN: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$UsernamePassword$username$txtUsername | Username: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$UsernamePassword$password$txtPassword | Password: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$UsernamePassword$passwordRetype$txtPassword | Re-type Password: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$PINPasswordReminder$PINReminder1$txtPINReminder | PIN Reminder: (cannot include any numbers) | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$SecurityQuestionAnswer$Question$txtSecurity | Security Question: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$SecurityQuestionAnswer$Answer$txtSecurity | Answer: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$SecurityQuestionAnswer$AnswerReType$txtSecurity | Re-type Answer: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default -UNKNOWN_TYPE | ctl00$ContentInfo$txtAgreement | Username and Password (optional)You have the option to create your own easy to remember username or password to sign in to continental.com. The username can be used in place of your OnePass account number and a password can be used in place of your PIN. PIN/Password ReminderIf you forget your PIN or password, we will provide this reminder to access your account.PIN Reminder: (cannot include any numbers)Security Question | Agreement Between User And Continental AirlinesThis Web site is offered to the user conditioned on acceptance by the user ("User") without modification of the terms, conditions, and notices contained herein. By accessing and using this Web site, the User is deemed to have agreed to all such terms, conditions, and notices (the "Agreement").OnePass Terms and ConditionsContinental Airlines and all OnePass partners reserve the right to change any aspect of the OnePass program at any time within 30 days notice to active members. This right includes, but is not limited to, changes in partner affiliation, rules for earning mileage credit and mileage redemption levels. However, rules for use of travel rewards, cities served, flight schedules, limited seating or space availability, restricted travel dates and specific features of promotional offers are subject to change with or without notice at the discretion of Continental Airlines or the OnePass partner. Continental Airlines is not responsible for unilateral action | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default +ADDRESS_HOME_COUNTRY | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry | Country: | US | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry_2-default +PHONE_HOME_WHOLE_NUMBER | ctl00$ContentInfo$BusinessPhone$txtNumber$txtPhone | Business/Other PhoneNumber: | | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry_2-default +PHONE_HOME_EXTENSION | ctl00$ContentInfo$BusinessPhone$txtExt$txtPhoneExt | Ext./PIN (optional): | | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry_2-default +ADDRESS_HOME_COUNTRY | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry | Country: | US | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$HomeAirport$txtAirport | Home Airport (optional): | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +EMAIL_ADDRESS | ctl00$ContentInfo$Email$txtEmail | E-mail Address: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$chkSubOpStatement | | on | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$chkSubopnewsoffers | | on | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$chkSubcocomspecials | | on | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$chkSubtripnotes | | on | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$NewPin$txtNewPin$txtNewPin | New PIN: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$NewPin$txtConfPin$txtConfPin | Re-type New PIN: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$UsernamePassword$username$txtUsername | Username: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$UsernamePassword$password$txtPassword | Password: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$UsernamePassword$passwordRetype$txtPassword | Re-type Password: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$PINPasswordReminder$PINReminder1$txtPINReminder | PIN Reminder: (cannot include any numbers) | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$SecurityQuestionAnswer$Question$txtSecurity | Security Question: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$SecurityQuestionAnswer$Answer$txtSecurity | Answer: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$SecurityQuestionAnswer$AnswerReType$txtSecurity | Re-type Answer: | | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default +UNKNOWN_TYPE | ctl00$ContentInfo$txtAgreement | Username and Password (optional)You have the option to create your own easy to remember username or password to sign in to continental.com. The username can be used in place of your OnePass account number and a password can be used in place of your PIN. PIN/Password ReminderIf you forget your PIN or password, we will provide this reminder to access your account.PIN Reminder: (cannot include any numbers)Security Question | Agreement Between User And Continental AirlinesThis Web site is offered to the user conditioned on acceptance by the user ("User") without modification of the terms, conditions, and notices contained herein. By accessing and using this Web site, the User is deemed to have agreed to all such terms, conditions, and notices (the "Agreement").OnePass Terms and ConditionsContinental Airlines and all OnePass partners reserve the right to change any aspect of the OnePass program at any time within 30 days notice to active members. This right includes, but is not limited to, changes in partner affiliation, rules for earning mileage credit and mileage redemption levels. However, rules for use of travel rewards, cities served, flight schedules, limited seating or space availability, restricted travel dates and specific features of promotional offers are subject to change with or without notice at the discretion of Continental Airlines or the OnePass partner. Continental Airlines is not responsible for unilateral action | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_3-default
diff --git a/components/test/data/autofill/heuristics/output/052_register_google.com.out b/components/test/data/autofill/heuristics/output/052_register_google.com.out index e012e54..d8dfbb9 100644 --- a/components/test/data/autofill/heuristics/output/052_register_google.com.out +++ b/components/test/data/autofill/heuristics/output/052_register_google.com.out
@@ -9,8 +9,8 @@ UNKNOWN_TYPE | selection | Security question: | choosequestion | FirstName_1-default UNKNOWN_TYPE | ownquestion | Security question: | | FirstName_1-default UNKNOWN_TYPE | IdentityAnswer | Answer: | | FirstName_1-default -EMAIL_ADDRESS | SecondaryEmail | Recovery email: | | SecondaryEmail_1-default -ADDRESS_HOME_COUNTRY | loc | Location: | US | SecondaryEmail_1-default -UNKNOWN_TYPE | Birthday | Birthday: | | SecondaryEmail_1-default -UNKNOWN_TYPE | newaccountcaptcha | Type the characters you see in the picture below. | | SecondaryEmail_1-default -UNKNOWN_TYPE | | Printable Version | Google Terms of ServiceWelcome to Google!1. Your relationship with Google 1.1 Your use of Google’s products, software, services and web sites (referred to collectively as the “Services†in this document and excluding any services provided to you by Google under a separate written agreement) is subject to the terms of a legal agreement between you and Google. “Google†means Google Inc., whose principal place of business is at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States. This document explains how the agreement is made up, and sets out some of the terms of that agreement. 1.2 Unless otherwise agreed in writing with Google, your agreement with Google will always include, at a minimum, the terms and conditions set out in this document. These are referred to below as the “Universal Termsâ€. 1.3 Your agreement with Google will also include the terms of any Legal Notices applicable to the Services, in addition to the Universal Terms. All of these are referred to below a | SecondaryEmail_1-default +EMAIL_ADDRESS | SecondaryEmail | Recovery email: | | SecondaryEmail_2-default +ADDRESS_HOME_COUNTRY | loc | Location: | US | SecondaryEmail_2-default +UNKNOWN_TYPE | Birthday | Birthday: | | SecondaryEmail_2-default +UNKNOWN_TYPE | newaccountcaptcha | Type the characters you see in the picture below. | | SecondaryEmail_2-default +UNKNOWN_TYPE | | Printable Version | Google Terms of ServiceWelcome to Google!1. Your relationship with Google 1.1 Your use of Google’s products, software, services and web sites (referred to collectively as the “Services†in this document and excluding any services provided to you by Google under a separate written agreement) is subject to the terms of a legal agreement between you and Google. “Google†means Google Inc., whose principal place of business is at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States. This document explains how the agreement is made up, and sets out some of the terms of that agreement. 1.2 Unless otherwise agreed in writing with Google, your agreement with Google will always include, at a minimum, the terms and conditions set out in this document. These are referred to below as the “Universal Termsâ€. 1.3 Your agreement with Google will also include the terms of any Legal Notices applicable to the Services, in addition to the Universal Terms. All of these are referred to below a | SecondaryEmail_2-default
diff --git a/components/test/data/autofill/heuristics/output/057_register_live.com.out b/components/test/data/autofill/heuristics/output/057_register_live.com.out index cb339ab..a4d419c 100644 --- a/components/test/data/autofill/heuristics/output/057_register_live.com.out +++ b/components/test/data/autofill/heuristics/output/057_register_live.com.out
@@ -6,12 +6,12 @@ EMAIL_ADDRESS | imembernameeasi | Use your email address: | Example: someone@example.com | imembernamelive_1-default UNKNOWN_TYPE | iPwd | Create a password: | | imembernamelive_1-default UNKNOWN_TYPE | iRetypePwd | Retype password: | | imembernamelive_1-default -EMAIL_ADDRESS | iAltEmail | Alternate email address: | | iAltEmail_1-default -UNKNOWN_TYPE | iSQ | Question: | 0 | iAltEmail_1-default -UNKNOWN_TYPE | iSA | Secret answer: | | iAltEmail_1-default -NAME_FIRST | iFirstName | First name: | | iAltEmail_1-default -NAME_LAST | iLastName | Last name: | | iAltEmail_1-default -UNKNOWN_TYPE | profile_gender | Male | m | iAltEmail_1-default -UNKNOWN_TYPE | profile_gender | Female | f | iAltEmail_1-default -UNKNOWN_TYPE | iBirthYear | Birth year: | Example: 1990 | iAltEmail_1-default -UNKNOWN_TYPE | iOptinEmail | Send me email with promotional offers and survey invitations from Windows Live, Bing, and MSN. (You can unsubscribe at any time.) | on | iAltEmail_1-default +EMAIL_ADDRESS | iAltEmail | Alternate email address: | | iAltEmail_2-default +UNKNOWN_TYPE | iSQ | Question: | 0 | iAltEmail_2-default +UNKNOWN_TYPE | iSA | Secret answer: | | iAltEmail_2-default +NAME_FIRST | iFirstName | First name: | | iAltEmail_2-default +NAME_LAST | iLastName | Last name: | | iAltEmail_2-default +UNKNOWN_TYPE | profile_gender | Male | m | iAltEmail_2-default +UNKNOWN_TYPE | profile_gender | Female | f | iAltEmail_2-default +UNKNOWN_TYPE | iBirthYear | Birth year: | Example: 1990 | iAltEmail_2-default +UNKNOWN_TYPE | iOptinEmail | Send me email with promotional offers and survey invitations from Windows Live, Bing, and MSN. (You can unsubscribe at any time.) | on | iAltEmail_2-default
diff --git a/components/test/data/autofill/heuristics/output/062_register_newegg.com.out b/components/test/data/autofill/heuristics/output/062_register_newegg.com.out index d28727c..32eb404 100644 --- a/components/test/data/autofill/heuristics/output/062_register_newegg.com.out +++ b/components/test/data/autofill/heuristics/output/062_register_newegg.com.out
@@ -22,19 +22,19 @@ PHONE_HOME_EXTENSION | BDayPhone_ext1 | Ext | | LoginName_1-default UNKNOWN_TYPE | same | Yes | 1 | LoginName_1-default UNKNOWN_TYPE | same | No | 0 | LoginName_1-default -NAME_FIRST | SFirstName | First Name* | | SFirstName_1-default -NAME_MIDDLE_INITIAL | SMI | MI | | SFirstName_1-default -NAME_LAST | SLastName | Last Name* | | SFirstName_1-default -COMPANY_NAME | SCompanyName | Company Name | | SFirstName_1-default -ADDRESS_HOME_LINE1 | SAddress1 | Address* | | SFirstName_1-default -ADDRESS_HOME_LINE2 | SAddress2 | Address 2 | | SFirstName_1-default -ADDRESS_HOME_CITY | SCity | City* | | SFirstName_1-default -ADDRESS_HOME_STATE | SState | State* | AK | SFirstName_1-default -ADDRESS_HOME_ZIP | SZip | Zip Code* | | SFirstName_1-default -PHONE_HOME_CITY_CODE | ShippingPhone_tel1 | Shipping Phone* | | SFirstName_1-default -PHONE_HOME_NUMBER | ShippingPhone_tel2 | | | SFirstName_1-default -PHONE_HOME_NUMBER | ShippingPhone_tel3 | | | SFirstName_1-default -PHONE_HOME_EXTENSION | ShippingPhone_ext1 | Ext | | SFirstName_1-default +NAME_FIRST | SFirstName | First Name* | | SFirstName_2-default +NAME_MIDDLE_INITIAL | SMI | MI | | SFirstName_2-default +NAME_LAST | SLastName | Last Name* | | SFirstName_2-default +COMPANY_NAME | SCompanyName | Company Name | | SFirstName_2-default +ADDRESS_HOME_LINE1 | SAddress1 | Address* | | SFirstName_2-default +ADDRESS_HOME_LINE2 | SAddress2 | Address 2 | | SFirstName_2-default +ADDRESS_HOME_CITY | SCity | City* | | SFirstName_2-default +ADDRESS_HOME_STATE | SState | State* | AK | SFirstName_2-default +ADDRESS_HOME_ZIP | SZip | Zip Code* | | SFirstName_2-default +PHONE_HOME_CITY_CODE | ShippingPhone_tel1 | Shipping Phone* | | SFirstName_2-default +PHONE_HOME_NUMBER | ShippingPhone_tel2 | | | SFirstName_2-default +PHONE_HOME_NUMBER | ShippingPhone_tel3 | | | SFirstName_2-default +PHONE_HOME_EXTENSION | ShippingPhone_ext1 | Ext | | SFirstName_2-default UNKNOWN_TYPE | custtype | Is this purchase for personal or business use? | 200 | LoginName_1-default UNKNOWN_TYPE | Age | Age | | LoginName_1-default UNKNOWN_TYPE | income | Income | 0 | LoginName_1-default
diff --git a/components/test/data/autofill/heuristics/output/063_register_officedepot.com.out b/components/test/data/autofill/heuristics/output/063_register_officedepot.com.out index f40c0b1..c6e3bbba9 100644 --- a/components/test/data/autofill/heuristics/output/063_register_officedepot.com.out +++ b/components/test/data/autofill/heuristics/output/063_register_officedepot.com.out
@@ -22,21 +22,21 @@ CREDIT_CARD_EXP_4_DIGIT_YEAR | paymentFormInfo.creditCardExpYear | / | -1 | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | paymentFormInfo.creditCardCvv | CID | | credit-card-cc UNKNOWN_TYPE | sameAsBilling | Same as Billing | on | addrsForm[0].firstName_1-default -NAME_FIRST | addrsForm[2].firstName | *First Name: | | addrsForm[2].firstName_1-default -NAME_MIDDLE_INITIAL | addrsForm[2].middleInitial | Middle Initial: | | addrsForm[2].firstName_1-default -NAME_LAST | addrsForm[2].lastName | *Last Name: | | addrsForm[2].firstName_1-default -COMPANY_NAME | addrsForm[2].shiptoName | Company Name | | addrsForm[2].firstName_1-default -ADDRESS_HOME_LINE1 | addrsForm[2].address1 | *Address | | addrsForm[2].firstName_1-default -ADDRESS_HOME_LINE2 | addrsForm[2].address2 | | | addrsForm[2].firstName_1-default -ADDRESS_HOME_CITY | addrsForm[2].city | *City | | addrsForm[2].firstName_1-default -ADDRESS_HOME_STATE | addrsForm[2].state | *State | {blank} | addrsForm[2].firstName_1-default -ADDRESS_HOME_ZIP | addrsForm[2].postalCode1 | *Zip Code | | addrsForm[2].firstName_1-default -PHONE_HOME_CITY_CODE | addrsForm[2].phoneNumber1 | *Phone Number: | | addrsForm[2].firstName_1-default -PHONE_HOME_NUMBER | addrsForm[2].phoneNumber2 | *Phone Number: | | addrsForm[2].firstName_1-default -PHONE_HOME_NUMBER | addrsForm[2].phoneNumber3 | *Phone Number: | | addrsForm[2].firstName_1-default -PHONE_HOME_EXTENSION | addrsForm[2].phoneNumber4 | ext. | | addrsForm[2].firstName_1-default -EMAIL_ADDRESS | addrsForm[2].email | *Email Address: | | addrsForm[2].firstName_1-default -UNKNOWN_TYPE | loginForm.loginName | *Login Name: | | addrsForm[2].firstName_1-default -UNKNOWN_TYPE | loginForm.password | *Password: | | addrsForm[2].firstName_1-default -UNKNOWN_TYPE | loginForm.passwordConfirm | *Password Confirm: | | addrsForm[2].firstName_1-default -UNKNOWN_TYPE | loginForm.autoLogin | Log me in automatically(Cookies must be enabled) | on | addrsForm[2].firstName_1-default +NAME_FIRST | addrsForm[2].firstName | *First Name: | | addrsForm[2].firstName_3-default +NAME_MIDDLE_INITIAL | addrsForm[2].middleInitial | Middle Initial: | | addrsForm[2].firstName_3-default +NAME_LAST | addrsForm[2].lastName | *Last Name: | | addrsForm[2].firstName_3-default +COMPANY_NAME | addrsForm[2].shiptoName | Company Name | | addrsForm[2].firstName_3-default +ADDRESS_HOME_LINE1 | addrsForm[2].address1 | *Address | | addrsForm[2].firstName_3-default +ADDRESS_HOME_LINE2 | addrsForm[2].address2 | | | addrsForm[2].firstName_3-default +ADDRESS_HOME_CITY | addrsForm[2].city | *City | | addrsForm[2].firstName_3-default +ADDRESS_HOME_STATE | addrsForm[2].state | *State | {blank} | addrsForm[2].firstName_3-default +ADDRESS_HOME_ZIP | addrsForm[2].postalCode1 | *Zip Code | | addrsForm[2].firstName_3-default +PHONE_HOME_CITY_CODE | addrsForm[2].phoneNumber1 | *Phone Number: | | addrsForm[2].firstName_3-default +PHONE_HOME_NUMBER | addrsForm[2].phoneNumber2 | *Phone Number: | | addrsForm[2].firstName_3-default +PHONE_HOME_NUMBER | addrsForm[2].phoneNumber3 | *Phone Number: | | addrsForm[2].firstName_3-default +PHONE_HOME_EXTENSION | addrsForm[2].phoneNumber4 | ext. | | addrsForm[2].firstName_3-default +EMAIL_ADDRESS | addrsForm[2].email | *Email Address: | | addrsForm[2].firstName_3-default +UNKNOWN_TYPE | loginForm.loginName | *Login Name: | | addrsForm[2].firstName_3-default +UNKNOWN_TYPE | loginForm.password | *Password: | | addrsForm[2].firstName_3-default +UNKNOWN_TYPE | loginForm.passwordConfirm | *Password Confirm: | | addrsForm[2].firstName_3-default +UNKNOWN_TYPE | loginForm.autoLogin | Log me in automatically(Cookies must be enabled) | on | addrsForm[2].firstName_3-default
diff --git a/components/test/data/autofill/heuristics/output/065_register_pyramidcollection.com.out b/components/test/data/autofill/heuristics/output/065_register_pyramidcollection.com.out index 262a4f0..d9e49a2 100644 --- a/components/test/data/autofill/heuristics/output/065_register_pyramidcollection.com.out +++ b/components/test/data/autofill/heuristics/output/065_register_pyramidcollection.com.out
@@ -11,15 +11,15 @@ PHONE_HOME_WHOLE_NUMBER | P3 | Evening Phone | | E1_1-default UNKNOWN_TYPE | P1 | Create Password * | | E1_1-default UNKNOWN_TYPE | PasswordConfirm | Confirm Password * | | E1_1-default -NAME_FIRST | SF1 | First Name * | | SF1_1-default -NAME_LAST | SL1 | Last Name * | | SF1_1-default -ADDRESS_HOME_LINE1 | SS1 | Address Line 1 * | | SF1_1-default -ADDRESS_HOME_LINE2 | SR1 | Address Line 2 | | SF1_1-default -ADDRESS_HOME_CITY | SC2 | City * | | SF1_1-default -ADDRESS_HOME_STATE | SS2 | State * | | SF1_1-default -ADDRESS_HOME_COUNTRY | SC3 | Country * | 0000 | SF1_1-default -ADDRESS_HOME_ZIP | SZ1 | Zip Code * | | SF1_1-default -PHONE_HOME_WHOLE_NUMBER | SP2 | Day Phone * | | SF1_1-default -PHONE_HOME_WHOLE_NUMBER | SP3 | Evening Phone | | SF1_1-default -UNKNOWN_TYPE | sameAsBilling | My Shipping address is same as billing address. | on | SF1_1-default +NAME_FIRST | SF1 | First Name * | | SF1_2-default +NAME_LAST | SL1 | Last Name * | | SF1_2-default +ADDRESS_HOME_LINE1 | SS1 | Address Line 1 * | | SF1_2-default +ADDRESS_HOME_LINE2 | SR1 | Address Line 2 | | SF1_2-default +ADDRESS_HOME_CITY | SC2 | City * | | SF1_2-default +ADDRESS_HOME_STATE | SS2 | State * | | SF1_2-default +ADDRESS_HOME_COUNTRY | SC3 | Country * | 0000 | SF1_2-default +ADDRESS_HOME_ZIP | SZ1 | Zip Code * | | SF1_2-default +PHONE_HOME_WHOLE_NUMBER | SP2 | Day Phone * | | SF1_2-default +PHONE_HOME_WHOLE_NUMBER | SP3 | Evening Phone | | SF1_2-default +UNKNOWN_TYPE | sameAsBilling | My Shipping address is same as billing address. | on | SF1_2-default UNKNOWN_TYPE | email | ENTER TO WIN A $100 GIFT CARD! | enter email address | email_1-default
diff --git a/components/test/data/autofill/heuristics/output/070_register_signup.live.com.out b/components/test/data/autofill/heuristics/output/070_register_signup.live.com.out index cb339ab..a4d419c 100644 --- a/components/test/data/autofill/heuristics/output/070_register_signup.live.com.out +++ b/components/test/data/autofill/heuristics/output/070_register_signup.live.com.out
@@ -6,12 +6,12 @@ EMAIL_ADDRESS | imembernameeasi | Use your email address: | Example: someone@example.com | imembernamelive_1-default UNKNOWN_TYPE | iPwd | Create a password: | | imembernamelive_1-default UNKNOWN_TYPE | iRetypePwd | Retype password: | | imembernamelive_1-default -EMAIL_ADDRESS | iAltEmail | Alternate email address: | | iAltEmail_1-default -UNKNOWN_TYPE | iSQ | Question: | 0 | iAltEmail_1-default -UNKNOWN_TYPE | iSA | Secret answer: | | iAltEmail_1-default -NAME_FIRST | iFirstName | First name: | | iAltEmail_1-default -NAME_LAST | iLastName | Last name: | | iAltEmail_1-default -UNKNOWN_TYPE | profile_gender | Male | m | iAltEmail_1-default -UNKNOWN_TYPE | profile_gender | Female | f | iAltEmail_1-default -UNKNOWN_TYPE | iBirthYear | Birth year: | Example: 1990 | iAltEmail_1-default -UNKNOWN_TYPE | iOptinEmail | Send me email with promotional offers and survey invitations from Windows Live, Bing, and MSN. (You can unsubscribe at any time.) | on | iAltEmail_1-default +EMAIL_ADDRESS | iAltEmail | Alternate email address: | | iAltEmail_2-default +UNKNOWN_TYPE | iSQ | Question: | 0 | iAltEmail_2-default +UNKNOWN_TYPE | iSA | Secret answer: | | iAltEmail_2-default +NAME_FIRST | iFirstName | First name: | | iAltEmail_2-default +NAME_LAST | iLastName | Last name: | | iAltEmail_2-default +UNKNOWN_TYPE | profile_gender | Male | m | iAltEmail_2-default +UNKNOWN_TYPE | profile_gender | Female | f | iAltEmail_2-default +UNKNOWN_TYPE | iBirthYear | Birth year: | Example: 1990 | iAltEmail_2-default +UNKNOWN_TYPE | iOptinEmail | Send me email with promotional offers and survey invitations from Windows Live, Bing, and MSN. (You can unsubscribe at any time.) | on | iAltEmail_2-default
diff --git a/components/test/data/autofill/heuristics/output/072_register_supershuttle.com.out b/components/test/data/autofill/heuristics/output/072_register_supershuttle.com.out index 8b9d7a4..a6d3ae9 100644 --- a/components/test/data/autofill/heuristics/output/072_register_supershuttle.com.out +++ b/components/test/data/autofill/heuristics/output/072_register_supershuttle.com.out
@@ -1,11 +1,11 @@ EMAIL_ADDRESS | ctl00$cphLeft$InnerLogin1$txtEmailAddress | Email Address | | ctl00$cphLeft$InnerLogin1$txtEmailAddress_1-default UNKNOWN_TYPE | ctl00$cphLeft$InnerLogin1$txtPassword | Password | | ctl00$cphLeft$InnerLogin1$txtEmailAddress_1-default -EMAIL_ADDRESS | ctl00$cphRight$Registration1$txtEmailAddress | Email Address | | ctl00$cphRight$Registration1$txtEmailAddress_1-default -NAME_FIRST | ctl00$cphRight$Registration1$txtFirstName | First Name | | ctl00$cphRight$Registration1$txtEmailAddress_1-default -NAME_LAST | ctl00$cphRight$Registration1$txtLastName | Last Name | | ctl00$cphRight$Registration1$txtEmailAddress_1-default -PHONE_HOME_WHOLE_NUMBER | ctl00$cphRight$Registration1$txtCellPhone | Contact or Cell Phone Number | | ctl00$cphRight$Registration1$txtEmailAddress_1-default -PHONE_HOME_COUNTRY_CODE | ctl00$cphRight$Registration1$txtCountryCode | If outside the US (Country Code/Phone Number) | | ctl00$cphRight$Registration1$txtEmailAddress_1-default -PHONE_HOME_CITY_AND_NUMBER | ctl00$cphRight$Registration1$txtIntPhoneNumber | Contact or Cell Phone Number | | ctl00$cphRight$Registration1$txtEmailAddress_1-default -UNKNOWN_TYPE | ctl00$cphRight$Registration1$txtPassword | Password | | ctl00$cphRight$Registration1$txtEmailAddress_1-default -UNKNOWN_TYPE | ctl00$cphRight$Registration1$txtConfirmPassword | Confirm Password | | ctl00$cphRight$Registration1$txtEmailAddress_1-default -UNKNOWN_TYPE | ctl00$cphRight$Registration1$chkAcceptSpecialOffers | Email me regarding SuperShuttle special offers and promotions | on | ctl00$cphRight$Registration1$txtEmailAddress_1-default +EMAIL_ADDRESS | ctl00$cphRight$Registration1$txtEmailAddress | Email Address | | ctl00$cphRight$Registration1$txtEmailAddress_2-default +NAME_FIRST | ctl00$cphRight$Registration1$txtFirstName | First Name | | ctl00$cphRight$Registration1$txtEmailAddress_2-default +NAME_LAST | ctl00$cphRight$Registration1$txtLastName | Last Name | | ctl00$cphRight$Registration1$txtEmailAddress_2-default +PHONE_HOME_WHOLE_NUMBER | ctl00$cphRight$Registration1$txtCellPhone | Contact or Cell Phone Number | | ctl00$cphRight$Registration1$txtEmailAddress_2-default +PHONE_HOME_COUNTRY_CODE | ctl00$cphRight$Registration1$txtCountryCode | If outside the US (Country Code/Phone Number) | | ctl00$cphRight$Registration1$txtEmailAddress_2-default +PHONE_HOME_CITY_AND_NUMBER | ctl00$cphRight$Registration1$txtIntPhoneNumber | Contact or Cell Phone Number | | ctl00$cphRight$Registration1$txtEmailAddress_2-default +UNKNOWN_TYPE | ctl00$cphRight$Registration1$txtPassword | Password | | ctl00$cphRight$Registration1$txtEmailAddress_2-default +UNKNOWN_TYPE | ctl00$cphRight$Registration1$txtConfirmPassword | Confirm Password | | ctl00$cphRight$Registration1$txtEmailAddress_2-default +UNKNOWN_TYPE | ctl00$cphRight$Registration1$chkAcceptSpecialOffers | Email me regarding SuperShuttle special offers and promotions | on | ctl00$cphRight$Registration1$txtEmailAddress_2-default
diff --git a/components/test/data/autofill/heuristics/output/077_register_yahoo.com.out b/components/test/data/autofill/heuristics/output/077_register_yahoo.com.out index 6b17176..10583486 100644 --- a/components/test/data/autofill/heuristics/output/077_register_yahoo.com.out +++ b/components/test/data/autofill/heuristics/output/077_register_yahoo.com.out
@@ -10,11 +10,11 @@ UNKNOWN_TYPE | domain | @ | yahoo.com | firstname_1-default UNKNOWN_TYPE | password | Password | | firstname_1-default UNKNOWN_TYPE | passwordconfirm | Re-type Password | | firstname_1-default -EMAIL_ADDRESS | altemail | Alternate Email (optional) | | altemail_1-default -UNKNOWN_TYPE | secquestion | Secret Question 1 | | altemail_1-default -UNKNOWN_TYPE | customsecquestion1 | Specify Your Question | | altemail_1-default -UNKNOWN_TYPE | secquestionanswer | Your Answer | | altemail_1-default -UNKNOWN_TYPE | secquestion2 | Secret Question 2 | | altemail_1-default -UNKNOWN_TYPE | customsecquestion2 | Specify Your Question | | altemail_1-default -UNKNOWN_TYPE | secquestionanswer2 | Your Answer | | altemail_1-default -UNKNOWN_TYPE | cword | Type the code shown | | altemail_1-default +EMAIL_ADDRESS | altemail | Alternate Email (optional) | | altemail_2-default +UNKNOWN_TYPE | secquestion | Secret Question 1 | | altemail_2-default +UNKNOWN_TYPE | customsecquestion1 | Specify Your Question | | altemail_2-default +UNKNOWN_TYPE | secquestionanswer | Your Answer | | altemail_2-default +UNKNOWN_TYPE | secquestion2 | Secret Question 2 | | altemail_2-default +UNKNOWN_TYPE | customsecquestion2 | Specify Your Question | | altemail_2-default +UNKNOWN_TYPE | secquestionanswer2 | Your Answer | | altemail_2-default +UNKNOWN_TYPE | cword | Type the code shown | | altemail_2-default
diff --git a/components/test/data/autofill/heuristics/output/080_crbug_53075.out b/components/test/data/autofill/heuristics/output/080_crbug_53075.out index 5369aaed..6689998 100644 --- a/components/test/data/autofill/heuristics/output/080_crbug_53075.out +++ b/components/test/data/autofill/heuristics/output/080_crbug_53075.out
@@ -15,13 +15,13 @@ ADDRESS_HOME_COUNTRY | ecomms_country | Country: | 224 | ecomms_company_name_1-default UNKNOWN_TYPE | delivery_address | specify a different delivery address | 1 | ecomms_company_name_1-default UNKNOWN_TYPE | del_title | Title: | | ecomms_company_name_1-default -NAME_FIRST | del_first_name | First Name: | | del_first_name_1-default -NAME_LAST | del_last_name | Last Name: | | del_first_name_1-default -PHONE_HOME_WHOLE_NUMBER | del_telephone | Telephone: | | del_first_name_1-default -PHONE_HOME_WHOLE_NUMBER | del_mobile | Mobile: | | del_first_name_1-default -ADDRESS_HOME_LINE1 | del_address1 | Address1: | | del_first_name_1-default -ADDRESS_HOME_LINE2 | del_address2 | Address2: | | del_first_name_1-default -ADDRESS_HOME_CITY | del_town | Town / City: | | del_first_name_1-default -ADDRESS_HOME_STATE | del_county | County: | | del_first_name_1-default -ADDRESS_HOME_ZIP | del_postcode | Postcode: | | del_first_name_1-default -ADDRESS_HOME_COUNTRY | ecomms_del_country | Country: | 224 | del_first_name_1-default +NAME_FIRST | del_first_name | First Name: | | del_first_name_2-default +NAME_LAST | del_last_name | Last Name: | | del_first_name_2-default +PHONE_HOME_WHOLE_NUMBER | del_telephone | Telephone: | | del_first_name_2-default +PHONE_HOME_WHOLE_NUMBER | del_mobile | Mobile: | | del_first_name_2-default +ADDRESS_HOME_LINE1 | del_address1 | Address1: | | del_first_name_2-default +ADDRESS_HOME_LINE2 | del_address2 | Address2: | | del_first_name_2-default +ADDRESS_HOME_CITY | del_town | Town / City: | | del_first_name_2-default +ADDRESS_HOME_STATE | del_county | County: | | del_first_name_2-default +ADDRESS_HOME_ZIP | del_postcode | Postcode: | | del_first_name_2-default +ADDRESS_HOME_COUNTRY | ecomms_del_country | Country: | 224 | del_first_name_2-default
diff --git a/components/test/data/autofill/heuristics/output/083_crbug_87517.out b/components/test/data/autofill/heuristics/output/083_crbug_87517.out index 9bf531d..bc05b2b3 100644 --- a/components/test/data/autofill/heuristics/output/083_crbug_87517.out +++ b/components/test/data/autofill/heuristics/output/083_crbug_87517.out
@@ -26,19 +26,19 @@ UNKNOWN_TYPE | Tribute_IncludeAmount | Include the amount | 1 | f1_1-default UNKNOWN_TYPE | Tribute_IncludeAmount | Do not include the amount | 0 | f1_1-default NAME_FULL | Tribute_NotifyName | Name: | | f1_1-default -EMAIL_ADDRESS | Tribute_Email | Email: | | Tribute_Email_1-default -ADDRESS_HOME_LINE1 | Tribute_NotifyAddr | Street: | | Tribute_Email_1-default -ADDRESS_HOME_CITY | Tribute_NotifyCity | City / St. / Zip: | | Tribute_Email_1-default -ADDRESS_HOME_STATE | Tribute_NotifyState | City / St. / Zip: | | Tribute_Email_1-default -ADDRESS_HOME_ZIP | Tribute_NotifyZip | City / St. / Zip: | | Tribute_Email_1-default +EMAIL_ADDRESS | Tribute_Email | Email: | | Tribute_Email_2-default +ADDRESS_HOME_LINE1 | Tribute_NotifyAddr | Street: | | Tribute_Email_2-default +ADDRESS_HOME_CITY | Tribute_NotifyCity | City / St. / Zip: | | Tribute_Email_2-default +ADDRESS_HOME_STATE | Tribute_NotifyState | City / St. / Zip: | | Tribute_Email_2-default +ADDRESS_HOME_ZIP | Tribute_NotifyZip | City / St. / Zip: | | Tribute_Email_2-default CREDIT_CARD_TYPE | cctype | Credit Card Type * | Visa | credit-card-cc CREDIT_CARD_NUMBER | ccard | Credit Card Number * | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | csc | CSC Number * What Is This? | | credit-card-cc CREDIT_CARD_EXP_MONTH | ExpMon | Month | 1 | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | ExpYear | Year | 11 | credit-card-cc UNKNOWN_TYPE | SameAddress | Same As Contact Address | checkbox | f1_1-default -ADDRESS_HOME_LINE1 | CC_Addr | Address 1 * | | CC_Addr_1-default -ADDRESS_HOME_LINE2 | CC_Addr2 | Address 2 | | CC_Addr_1-default -ADDRESS_HOME_CITY | CC_City | City / State / Zip * | | CC_Addr_1-default -ADDRESS_HOME_STATE | CC_State | Credit Card Information | | CC_Addr_1-default -ADDRESS_HOME_ZIP | CC_Zip | Credit Card Information | | CC_Addr_1-default +ADDRESS_HOME_LINE1 | CC_Addr | Address 1 * | | CC_Addr_4-default +ADDRESS_HOME_LINE2 | CC_Addr2 | Address 2 | | CC_Addr_4-default +ADDRESS_HOME_CITY | CC_City | City / State / Zip * | | CC_Addr_4-default +ADDRESS_HOME_STATE | CC_State | Credit Card Information | | CC_Addr_4-default +ADDRESS_HOME_ZIP | CC_Zip | Credit Card Information | | CC_Addr_4-default
diff --git a/components/test/data/autofill/heuristics/output/084_crbug_93595.out b/components/test/data/autofill/heuristics/output/084_crbug_93595.out index a058c76..e251826 100644 --- a/components/test/data/autofill/heuristics/output/084_crbug_93595.out +++ b/components/test/data/autofill/heuristics/output/084_crbug_93595.out
@@ -3,6 +3,6 @@ CREDIT_CARD_NAME_FULL | cc_name | | | credit-card-cc CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR | cc_exp | Expiration date (MM/YY) | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | cc_cvv2 | CVV2 / Security Code: | | credit-card-cc -UNKNOWN_TYPE | field_17 | | Select an option... | payment_method_1-default -UNKNOWN_TYPE | age | | | payment_method_1-default -UNKNOWN_TYPE | comments | | | payment_method_1-default +UNKNOWN_TYPE | field_17 | | Select an option... | payment_method_2-default +UNKNOWN_TYPE | age | | | payment_method_2-default +UNKNOWN_TYPE | comments | | | payment_method_2-default
diff --git a/components/test/data/autofill/heuristics/output/085_crbug_98152.out b/components/test/data/autofill/heuristics/output/085_crbug_98152.out index ab0b852..c9d2959 100644 --- a/components/test/data/autofill/heuristics/output/085_crbug_98152.out +++ b/components/test/data/autofill/heuristics/output/085_crbug_98152.out
@@ -4,11 +4,11 @@ CREDIT_CARD_EXP_4_DIGIT_YEAR | CCForm.expirationYear | Expiration date | 2011 | credit-card-cc CREDIT_CARD_NAME_FULL | CCForm.name | Name as it appears on card | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | CCForm.cid | | | credit-card-cc -UNKNOWN_TYPE | isBillingAddress | Same as Shipping address | on | CCForm.cardType_1-default -COMPANY_NAME | CCForm.companyName | Company Name | | CCForm.cardType_1-default -ADDRESS_HOME_LINE1 | addressForm.street1 | Address Line 1 | | CCForm.cardType_1-default -ADDRESS_HOME_LINE2 | addressForm.street2 | Address Line 2 | | CCForm.cardType_1-default -ADDRESS_HOME_CITY | addressForm.city | City | | CCForm.cardType_1-default -ADDRESS_HOME_STATE | addressForm.state | State | | CCForm.cardType_1-default -ADDRESS_HOME_ZIP | addressForm.zip | Zip Code | | CCForm.cardType_1-default -PHONE_HOME_WHOLE_NUMBER | addressForm.phone | Phone Number | | CCForm.cardType_1-default +UNKNOWN_TYPE | isBillingAddress | Same as Shipping address | on | CCForm.cardType_2-default +COMPANY_NAME | CCForm.companyName | Company Name | | CCForm.cardType_2-default +ADDRESS_HOME_LINE1 | addressForm.street1 | Address Line 1 | | CCForm.cardType_2-default +ADDRESS_HOME_LINE2 | addressForm.street2 | Address Line 2 | | CCForm.cardType_2-default +ADDRESS_HOME_CITY | addressForm.city | City | | CCForm.cardType_2-default +ADDRESS_HOME_STATE | addressForm.state | State | | CCForm.cardType_2-default +ADDRESS_HOME_ZIP | addressForm.zip | Zip Code | | CCForm.cardType_2-default +PHONE_HOME_WHOLE_NUMBER | addressForm.phone | Phone Number | | CCForm.cardType_2-default
diff --git a/components/test/data/autofill/heuristics/output/087_crbug_98286.out b/components/test/data/autofill/heuristics/output/087_crbug_98286.out index 17632bb..efd73c4 100644 --- a/components/test/data/autofill/heuristics/output/087_crbug_98286.out +++ b/components/test/data/autofill/heuristics/output/087_crbug_98286.out
@@ -4,4 +4,4 @@ CREDIT_CARD_EXP_MONTH | drpdwnExpirationMonth | *Expiration date: | 00 | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | drpdwnExpirationYear | *Expiration date: | 2011 | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | txtVisaVerificationNumber | VISA Card Verification # | | credit-card-cc -UNKNOWN_TYPE | chkUnreadable | I can't read the numbers | on | drpdwnCardTypes_1-default +UNKNOWN_TYPE | chkUnreadable | I can't read the numbers | on | drpdwnCardTypes_2-default
diff --git a/components/test/data/autofill/heuristics/output/092_checkout_alaskaair.com.out b/components/test/data/autofill/heuristics/output/092_checkout_alaskaair.com.out index 9fe174d..27f382b 100644 --- a/components/test/data/autofill/heuristics/output/092_checkout_alaskaair.com.out +++ b/components/test/data/autofill/heuristics/output/092_checkout_alaskaair.com.out
@@ -19,22 +19,22 @@ ADDRESS_HOME_STATE | CreditCardInformation.BillingAddressEntry.MXStates_Selected | State/Province | | MyWalletInformation.UseMyWalletFunds_1-default UNKNOWN_TYPE | CreditCardInformation.BillingAddressEntry.OtherStates_Selected | State/Province | | MyWalletInformation.UseMyWalletFunds_1-default ADDRESS_HOME_ZIP | CreditCardInformation.BillingAddressEntry.PostalCode | Zip/Postal Code | | MyWalletInformation.UseMyWalletFunds_1-default -ADDRESS_HOME_COUNTRY | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected | Country Code | 1 | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -PHONE_HOME_WHOLE_NUMBER | CreditCardInformation.BillingPhoneNumberEntry.Number | Phone (with area code) | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -UNKNOWN_TYPE | TripInsurance.QuoteID | Yes, add trip protection for a total of $21.00. | 657566350481481886 | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -UNKNOWN_TYPE | TripInsurance.QuoteID | No, I choose not to protect my purchase. | 657566350481481887 | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default +ADDRESS_HOME_COUNTRY | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected | Country Code | 1 | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default +PHONE_HOME_WHOLE_NUMBER | CreditCardInformation.BillingPhoneNumberEntry.Number | Phone (with area code) | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default +UNKNOWN_TYPE | TripInsurance.QuoteID | Yes, add trip protection for a total of $21.00. | 657566350481481886 | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default +UNKNOWN_TYPE | TripInsurance.QuoteID | No, I choose not to protect my purchase. | 657566350481481887 | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default CREDIT_CARD_NUMBER | AncillaryCreditCardInformation.BillingCreditCardEntry.CardNumber | Card Number | | credit-card-cc CREDIT_CARD_EXP_MONTH | AncillaryCreditCardInformation.BillingCreditCardEntry.ExpirationMonths_Selected | Expiration* | | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | AncillaryCreditCardInformation.BillingCreditCardEntry.ExpirationYears_Selected | Expiration* | | credit-card-cc CREDIT_CARD_NAME_FULL | AncillaryCreditCardInformation.BillingCreditCardEntry.CardPersonName | Name on Card | | credit-card-cc -ADDRESS_HOME_COUNTRY | AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected | Country | US | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -ADDRESS_HOME_LINE1 | AncillaryCreditCardInformation.BillingAddressEntry.Address1 | Address | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -ADDRESS_HOME_LINE2 | AncillaryCreditCardInformation.BillingAddressEntry.Address2 | Address Line 2 | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -ADDRESS_HOME_CITY | AncillaryCreditCardInformation.BillingAddressEntry.City | City | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -ADDRESS_HOME_STATE | AncillaryCreditCardInformation.BillingAddressEntry.USStates_Selected | State/Province | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -ADDRESS_HOME_STATE | AncillaryCreditCardInformation.BillingAddressEntry.CAStates_Selected | State/Province | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -ADDRESS_HOME_STATE | AncillaryCreditCardInformation.BillingAddressEntry.MXStates_Selected | State/Province | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -UNKNOWN_TYPE | AncillaryCreditCardInformation.BillingAddressEntry.OtherStates_Selected | State/Province | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -ADDRESS_HOME_ZIP | AncillaryCreditCardInformation.BillingAddressEntry.PostalCode | Zip/Postal Code | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -ADDRESS_HOME_COUNTRY | AncillaryCreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected | Country Code | 1 | AncillaryCreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default -PHONE_HOME_WHOLE_NUMBER | AncillaryCreditCardInformation.BillingPhoneNumberEntry.Number | Phone (with area code) | | AncillaryCreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default +ADDRESS_HOME_COUNTRY | AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected | Country | US | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default +ADDRESS_HOME_LINE1 | AncillaryCreditCardInformation.BillingAddressEntry.Address1 | Address | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default +ADDRESS_HOME_LINE2 | AncillaryCreditCardInformation.BillingAddressEntry.Address2 | Address Line 2 | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default +ADDRESS_HOME_CITY | AncillaryCreditCardInformation.BillingAddressEntry.City | City | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default +ADDRESS_HOME_STATE | AncillaryCreditCardInformation.BillingAddressEntry.USStates_Selected | State/Province | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default +ADDRESS_HOME_STATE | AncillaryCreditCardInformation.BillingAddressEntry.CAStates_Selected | State/Province | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default +ADDRESS_HOME_STATE | AncillaryCreditCardInformation.BillingAddressEntry.MXStates_Selected | State/Province | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default +UNKNOWN_TYPE | AncillaryCreditCardInformation.BillingAddressEntry.OtherStates_Selected | State/Province | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default +ADDRESS_HOME_ZIP | AncillaryCreditCardInformation.BillingAddressEntry.PostalCode | Zip/Postal Code | | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_3-default +ADDRESS_HOME_COUNTRY | AncillaryCreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected | Country Code | 1 | AncillaryCreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_4-default +PHONE_HOME_WHOLE_NUMBER | AncillaryCreditCardInformation.BillingPhoneNumberEntry.Number | Phone (with area code) | | AncillaryCreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_4-default
diff --git a/components/test/data/autofill/heuristics/output/096_llbean.out b/components/test/data/autofill/heuristics/output/096_llbean.out index 78a58185..e1faed0 100644 --- a/components/test/data/autofill/heuristics/output/096_llbean.out +++ b/components/test/data/autofill/heuristics/output/096_llbean.out
@@ -18,12 +18,12 @@ ADDRESS_HOME_ZIP | zipCode | Zip Code | | personTitle_1-default ADDRESS_HOME_CITY | city | City | | personTitle_1-default ADDRESS_HOME_STATE | state | State | | personTitle_1-default -ADDRESS_HOME_ZIP | CAPostal | Postal Code | | CAPostal_1-default -ADDRESS_HOME_CITY | CACity | City | | CAPostal_1-default -ADDRESS_HOME_STATE | CAProvince | Province | | CAPostal_1-default -ADDRESS_HOME_CITY | INTLCity | City | | CAPostal_1-default -ADDRESS_HOME_STATE | INTLCounty | County | | CAPostal_1-default -ADDRESS_HOME_ZIP | INTLPostal | Postal Code | | CAPostal_1-default +ADDRESS_HOME_ZIP | CAPostal | Postal Code | | CAPostal_2-default +ADDRESS_HOME_CITY | CACity | City | | CAPostal_2-default +ADDRESS_HOME_STATE | CAProvince | Province | | CAPostal_2-default +ADDRESS_HOME_CITY | INTLCity | City | | CAPostal_2-default +ADDRESS_HOME_STATE | INTLCounty | County | | CAPostal_2-default +ADDRESS_HOME_ZIP | INTLPostal | Postal Code | | CAPostal_2-default PHONE_HOME_WHOLE_NUMBER | phone1 | Daytime Phone Number (optional) | | personTitle_1-default PHONE_HOME_WHOLE_NUMBER | intlPhone1Prefix | International Country Code | | personTitle_1-default PHONE_HOME_WHOLE_NUMBER | intlPhone1 | Daytime Phone Number | | personTitle_1-default
diff --git a/components/test/data/autofill/heuristics/output/097_register_alaskaair.com.out b/components/test/data/autofill/heuristics/output/097_register_alaskaair.com.out index bde99aa..94ca9d3 100644 --- a/components/test/data/autofill/heuristics/output/097_register_alaskaair.com.out +++ b/components/test/data/autofill/heuristics/output/097_register_alaskaair.com.out
@@ -10,30 +10,30 @@ UNKNOWN_TYPE | FormUserControl$_personalIdentification$_birthDate$_birthDate$_day | Day | | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default UNKNOWN_TYPE | FormUserControl$_personalIdentification$_birthDate$_birthDate$_yearTextBox | Year | Year | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default UNKNOWN_TYPE | FormUserControl$_personalIdentification$_gender$_gender | Gender* | | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default -NAME_FIRST | FormUserControl$_guardianInformation$_firstName$_name | First Name* | | FormUserControl$_guardianInformation$_firstName$_name_1-default -NAME_LAST | FormUserControl$_guardianInformation$_lastName$_name | Last Name* | | FormUserControl$_guardianInformation$_lastName$_name_1-default -EMAIL_ADDRESS | FormUserControl$_guardianInformation$_email$_emailAddressTextBox | Email Address* | | FormUserControl$_guardianInformation$_lastName$_name_1-default -ADDRESS_HOME_COUNTRY | FormUserControl$_mailingAddress$_country | Country* | US | FormUserControl$_guardianInformation$_lastName$_name_1-default -COMPANY_NAME | FormUserControl$_mailingAddress$_company | Company | | FormUserControl$_guardianInformation$_lastName$_name_1-default -ADDRESS_HOME_LINE1 | FormUserControl$_mailingAddress$_addr1 | Address* | | FormUserControl$_guardianInformation$_lastName$_name_1-default -ADDRESS_HOME_LINE2 | FormUserControl$_mailingAddress$_addr2 | Second Address Line | | FormUserControl$_guardianInformation$_lastName$_name_1-default -ADDRESS_HOME_CITY | FormUserControl$_mailingAddress$_city | Zip/Postal Code | | FormUserControl$_guardianInformation$_lastName$_name_1-default -ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateUS | State/Province* | | FormUserControl$_guardianInformation$_lastName$_name_1-default -ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateCA | Canadian Provinces | | FormUserControl$_guardianInformation$_lastName$_name_1-default -ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateMX | Mexican States | | FormUserControl$_guardianInformation$_lastName$_name_1-default -ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateXX | State/Province Other | | FormUserControl$_guardianInformation$_lastName$_name_1-default -ADDRESS_HOME_ZIP | FormUserControl$_mailingAddress$_zip | Zip/Postal Code* | | FormUserControl$_guardianInformation$_lastName$_name_1-default -ADDRESS_HOME_COUNTRY | FormUserControl$_contactInformation$_phoneNumber$_countryCode | Country Code | 1 | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -PHONE_HOME_WHOLE_NUMBER | FormUserControl$_contactInformation$_phoneNumber$_phoneNumberTextBox | Country Code | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -PHONE_HOME_EXTENSION | FormUserControl$_contactInformation$_phoneNumber$_extensionTextBox | Ext. | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -EMAIL_ADDRESS | FormUserControl$_contactInformation$_emailAddress$_emailAddressTextBox | Email Address* | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -UNKNOWN_TYPE | FormUserControl$_userIdPassword$_userId$_userId | Create a User ID* | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -UNKNOWN_TYPE | FormUserControl$_userIdPassword$_password$_password | Create a Password | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -UNKNOWN_TYPE | FormUserControl$_userIdPassword$_reEnterPassword$_password | Re-enter Password | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -UNKNOWN_TYPE | FormUserControl$_secretQuestion$_question | Secret Question* | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -UNKNOWN_TYPE | FormUserControl$_secretQuestion$_answer | Please choose a secret question and provide the answer. You will need to answer the question again in case you forget your password. Make sure you choose a question and answer that are easy for you to remember, but difficult for other people to know.Secret Question* Answer* | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -UNKNOWN_TYPE | FormUserControl$_subscriptionsOffers$_insiderNewsletter$_subscriptionCheckBox | Insider NewsletterA weekly email personalized to provide you with an insider glimpse of the best deals we have to offer - across the board. | on | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -ADDRESS_HOME_CITY | FormUserControl$_subscriptionsOffers$_primaryDepartureCity$_primaryDepartureCity$_city | Primary Departure City | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -UNKNOWN_TYPE | FormUserControl$_subscriptionsOffers$_eStatements$_subscriptionCheckBox | Mileage Plan E-Statements and Partner OffersA monthly recap of your Mileage Plan activity along with program news, exclusive partner offers, and countless ways to earn free travel faster. | on | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -UNKNOWN_TYPE | FormUserControl$_subscriptionsOffers$_asQXAnnouncements$_subscriptionCheckBox | Alaska AnnouncementsOccasional email that puts you "in the know" about sales, promotions, and other important travel information. | on | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default -UNKNOWN_TYPE | FormUserControl$_mpTermsAndConditions$_iAgree | Mileage Plan™ Terms & Conditions* I acknowledge that I have reviewed these Mileage Plan Terms and Conditions | on | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default +NAME_FIRST | FormUserControl$_guardianInformation$_firstName$_name | First Name* | | FormUserControl$_guardianInformation$_firstName$_name_2-default +NAME_LAST | FormUserControl$_guardianInformation$_lastName$_name | Last Name* | | FormUserControl$_guardianInformation$_lastName$_name_3-default +EMAIL_ADDRESS | FormUserControl$_guardianInformation$_email$_emailAddressTextBox | Email Address* | | FormUserControl$_guardianInformation$_lastName$_name_3-default +ADDRESS_HOME_COUNTRY | FormUserControl$_mailingAddress$_country | Country* | US | FormUserControl$_guardianInformation$_lastName$_name_3-default +COMPANY_NAME | FormUserControl$_mailingAddress$_company | Company | | FormUserControl$_guardianInformation$_lastName$_name_3-default +ADDRESS_HOME_LINE1 | FormUserControl$_mailingAddress$_addr1 | Address* | | FormUserControl$_guardianInformation$_lastName$_name_3-default +ADDRESS_HOME_LINE2 | FormUserControl$_mailingAddress$_addr2 | Second Address Line | | FormUserControl$_guardianInformation$_lastName$_name_3-default +ADDRESS_HOME_CITY | FormUserControl$_mailingAddress$_city | Zip/Postal Code | | FormUserControl$_guardianInformation$_lastName$_name_3-default +ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateUS | State/Province* | | FormUserControl$_guardianInformation$_lastName$_name_3-default +ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateCA | Canadian Provinces | | FormUserControl$_guardianInformation$_lastName$_name_3-default +ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateMX | Mexican States | | FormUserControl$_guardianInformation$_lastName$_name_3-default +ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateXX | State/Province Other | | FormUserControl$_guardianInformation$_lastName$_name_3-default +ADDRESS_HOME_ZIP | FormUserControl$_mailingAddress$_zip | Zip/Postal Code* | | FormUserControl$_guardianInformation$_lastName$_name_3-default +ADDRESS_HOME_COUNTRY | FormUserControl$_contactInformation$_phoneNumber$_countryCode | Country Code | 1 | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +PHONE_HOME_WHOLE_NUMBER | FormUserControl$_contactInformation$_phoneNumber$_phoneNumberTextBox | Country Code | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +PHONE_HOME_EXTENSION | FormUserControl$_contactInformation$_phoneNumber$_extensionTextBox | Ext. | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +EMAIL_ADDRESS | FormUserControl$_contactInformation$_emailAddress$_emailAddressTextBox | Email Address* | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +UNKNOWN_TYPE | FormUserControl$_userIdPassword$_userId$_userId | Create a User ID* | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +UNKNOWN_TYPE | FormUserControl$_userIdPassword$_password$_password | Create a Password | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +UNKNOWN_TYPE | FormUserControl$_userIdPassword$_reEnterPassword$_password | Re-enter Password | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +UNKNOWN_TYPE | FormUserControl$_secretQuestion$_question | Secret Question* | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +UNKNOWN_TYPE | FormUserControl$_secretQuestion$_answer | Please choose a secret question and provide the answer. You will need to answer the question again in case you forget your password. Make sure you choose a question and answer that are easy for you to remember, but difficult for other people to know.Secret Question* Answer* | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +UNKNOWN_TYPE | FormUserControl$_subscriptionsOffers$_insiderNewsletter$_subscriptionCheckBox | Insider NewsletterA weekly email personalized to provide you with an insider glimpse of the best deals we have to offer - across the board. | on | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +ADDRESS_HOME_CITY | FormUserControl$_subscriptionsOffers$_primaryDepartureCity$_primaryDepartureCity$_city | Primary Departure City | | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +UNKNOWN_TYPE | FormUserControl$_subscriptionsOffers$_eStatements$_subscriptionCheckBox | Mileage Plan E-Statements and Partner OffersA monthly recap of your Mileage Plan activity along with program news, exclusive partner offers, and countless ways to earn free travel faster. | on | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +UNKNOWN_TYPE | FormUserControl$_subscriptionsOffers$_asQXAnnouncements$_subscriptionCheckBox | Alaska AnnouncementsOccasional email that puts you "in the know" about sales, promotions, and other important travel information. | on | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default +UNKNOWN_TYPE | FormUserControl$_mpTermsAndConditions$_iAgree | Mileage Plan™ Terms & Conditions* I acknowledge that I have reviewed these Mileage Plan Terms and Conditions | on | FormUserControl$_contactInformation$_phoneNumber$_countryCode_4-default
diff --git a/components/test/data/autofill/heuristics/output/098_register_epson.com.mx.out b/components/test/data/autofill/heuristics/output/098_register_epson.com.mx.out index 5d56a1b5..f7b3b50 100644 --- a/components/test/data/autofill/heuristics/output/098_register_epson.com.mx.out +++ b/components/test/data/autofill/heuristics/output/098_register_epson.com.mx.out
@@ -7,6 +7,6 @@ UNKNOWN_TYPE | passLogin | a * | | doAction_1-default NAME_FIRST | nombre | Nombre * | | doAction_1-default NAME_LAST | apellido | Apellido * | | doAction_1-default -EMAIL_ADDRESS | emailRegistro | Email * | | emailRegistro_1-default -UNKNOWN_TYPE | passRegistro | a * | | emailRegistro_1-default -UNKNOWN_TYPE | rePassRegistro | a * | | emailRegistro_1-default +EMAIL_ADDRESS | emailRegistro | Email * | | emailRegistro_2-default +UNKNOWN_TYPE | passRegistro | a * | | emailRegistro_2-default +UNKNOWN_TYPE | rePassRegistro | a * | | emailRegistro_2-default
diff --git a/components/test/data/autofill/heuristics/output/101_checkout_m_bestbuy.com.out b/components/test/data/autofill/heuristics/output/101_checkout_m_bestbuy.com.out index afd8be3..698c74f 100644 --- a/components/test/data/autofill/heuristics/output/101_checkout_m_bestbuy.com.out +++ b/components/test/data/autofill/heuristics/output/101_checkout_m_bestbuy.com.out
@@ -3,31 +3,31 @@ CREDIT_CARD_EXP_MONTH | expirery-month | Credit CardCard Type | | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | expirery-year | Credit CardCard Type | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | securityCode | Security Code | | credit-card-cc -UNKNOWN_TYPE | TxtRzMembershipId | Member IDDon't Know it? | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.rwzCertMemberNumbers | Member ID | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.rwzCertNumbers | Certificate Number Last 10 digits | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.digitalDiscountsIds | Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.digitalDiscountsIds | Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.digitalDiscountsIds | Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.digitalDiscountsIds | Code | | selCreditCardType_1-default -UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.digitalDiscountsIds | Code | | selCreditCardType_1-default +UNKNOWN_TYPE | TxtRzMembershipId | Member IDDon't Know it? | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCNumber | Card Number or Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.SVCCID | Security Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.rwzCertMemberNumbers | Member ID | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.rwzCertNumbers | Certificate Number Last 10 digits | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.digitalDiscountsIds | Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.digitalDiscountsIds | Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.digitalDiscountsIds | Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.digitalDiscountsIds | Code | | selCreditCardType_2-default +UNKNOWN_TYPE | /bestbuy/digiterra/commerce/order/formhandler/CheckoutPaymentFormHandler.digitalDiscountsIds | Code | | selCreditCardType_2-default
diff --git a/components/test/data/autofill/heuristics/output/102_checkout_m_macys.com.out b/components/test/data/autofill/heuristics/output/102_checkout_m_macys.com.out index ff9c12e7..16a6ad7 100644 --- a/components/test/data/autofill/heuristics/output/102_checkout_m_macys.com.out +++ b/components/test/data/autofill/heuristics/output/102_checkout_m_macys.com.out
@@ -3,25 +3,25 @@ CREDIT_CARD_EXP_MONTH | creditCard.expMonth | expiration: | -1 | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | creditCard.expYear | expiration: | -1 | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | creditCard.securityCode | please enter security code: | | credit-card-cc -UNKNOWN_TYPE | creditCard.billingContact.shippingAddressAsBillingAddress | Use my Shipping Address | true | creditCard.cardType.code_1-default -NAME_FIRST | creditCard.billingContact.firstName | first name: | | creditCard.cardType.code_1-default -NAME_LAST | creditCard.billingContact.lastName | last name: | | creditCard.cardType.code_1-default -ADDRESS_HOME_LINE1 | creditCard.billingContact.address.addressLine1 | Address line 1: | | creditCard.cardType.code_1-default -ADDRESS_HOME_LINE2 | creditCard.billingContact.address.addressLine2 | Address line 2: (optional) | | creditCard.cardType.code_1-default -ADDRESS_HOME_CITY | creditCard.billingContact.address.city | City: | | creditCard.cardType.code_1-default -ADDRESS_HOME_STATE | creditCard.billingContact.address.state | State: | -1 | creditCard.cardType.code_1-default -ADDRESS_HOME_ZIP | creditCard.billingContact.address.postalCode | Zip code: | | creditCard.cardType.code_1-default -EMAIL_ADDRESS | user.email | email address: | | creditCard.cardType.code_1-default -PHONE_HOME_CITY_CODE | user.phone.areaCode | phone: | | creditCard.cardType.code_1-default -PHONE_HOME_NUMBER | user.phone.exchangeNumber | phone:Please enter your phone number | | creditCard.cardType.code_1-default -PHONE_HOME_WHOLE_NUMBER | user.phone.subscriberNumber | phone:Please enter your phone number | | creditCard.cardType.code_1-default -UNKNOWN_TYPE | user.profile.createAccount | Yes! Create an account for me at macys.com | true | creditCard.cardType.code_1-default -EMAIL_ADDRESS | user.profile.email | email address: | | user.profile.email_1-default -EMAIL_ADDRESS | user.profile.confirmEmail | Confirm email address: | | user.profile.email_1-default -UNKNOWN_TYPE | user.profile.password | Password: | | user.profile.email_1-default -UNKNOWN_TYPE | user.profile.confirmPassword | Confirm password: | | user.profile.email_1-default -UNKNOWN_TYPE | user.profile.month | Birthdate: | -1 | user.profile.email_1-default -UNKNOWN_TYPE | user.profile.date | Birthdate: | -1 | user.profile.email_1-default -UNKNOWN_TYPE | user.profile.year | Birthdate: | -1 | user.profile.email_1-default -UNKNOWN_TYPE | user.profile.subscriptionInfo.emailSalesEvents | Yes, send me email updates from Macy’s.com about the latest trends, products and promotions online and in-store. | true | user.profile.email_1-default -UNKNOWN_TYPE | user.savePaymentDetails | Yes, save payment information to my Macy's profile. | true | user.profile.email_1-default +UNKNOWN_TYPE | creditCard.billingContact.shippingAddressAsBillingAddress | Use my Shipping Address | true | creditCard.cardType.code_2-default +NAME_FIRST | creditCard.billingContact.firstName | first name: | | creditCard.cardType.code_2-default +NAME_LAST | creditCard.billingContact.lastName | last name: | | creditCard.cardType.code_2-default +ADDRESS_HOME_LINE1 | creditCard.billingContact.address.addressLine1 | Address line 1: | | creditCard.cardType.code_2-default +ADDRESS_HOME_LINE2 | creditCard.billingContact.address.addressLine2 | Address line 2: (optional) | | creditCard.cardType.code_2-default +ADDRESS_HOME_CITY | creditCard.billingContact.address.city | City: | | creditCard.cardType.code_2-default +ADDRESS_HOME_STATE | creditCard.billingContact.address.state | State: | -1 | creditCard.cardType.code_2-default +ADDRESS_HOME_ZIP | creditCard.billingContact.address.postalCode | Zip code: | | creditCard.cardType.code_2-default +EMAIL_ADDRESS | user.email | email address: | | creditCard.cardType.code_2-default +PHONE_HOME_CITY_CODE | user.phone.areaCode | phone: | | creditCard.cardType.code_2-default +PHONE_HOME_NUMBER | user.phone.exchangeNumber | phone:Please enter your phone number | | creditCard.cardType.code_2-default +PHONE_HOME_WHOLE_NUMBER | user.phone.subscriberNumber | phone:Please enter your phone number | | creditCard.cardType.code_2-default +UNKNOWN_TYPE | user.profile.createAccount | Yes! Create an account for me at macys.com | true | creditCard.cardType.code_2-default +EMAIL_ADDRESS | user.profile.email | email address: | | user.profile.email_3-default +EMAIL_ADDRESS | user.profile.confirmEmail | Confirm email address: | | user.profile.email_3-default +UNKNOWN_TYPE | user.profile.password | Password: | | user.profile.email_3-default +UNKNOWN_TYPE | user.profile.confirmPassword | Confirm password: | | user.profile.email_3-default +UNKNOWN_TYPE | user.profile.month | Birthdate: | -1 | user.profile.email_3-default +UNKNOWN_TYPE | user.profile.date | Birthdate: | -1 | user.profile.email_3-default +UNKNOWN_TYPE | user.profile.year | Birthdate: | -1 | user.profile.email_3-default +UNKNOWN_TYPE | user.profile.subscriptionInfo.emailSalesEvents | Yes, send me email updates from Macy’s.com about the latest trends, products and promotions online and in-store. | true | user.profile.email_3-default +UNKNOWN_TYPE | user.savePaymentDetails | Yes, save payment information to my Macy's profile. | true | user.profile.email_3-default
diff --git a/components/test/data/autofill/heuristics/output/104_checkout_m_kohls.com.out b/components/test/data/autofill/heuristics/output/104_checkout_m_kohls.com.out index 1c586df..78b22c4 100644 --- a/components/test/data/autofill/heuristics/output/104_checkout_m_kohls.com.out +++ b/components/test/data/autofill/heuristics/output/104_checkout_m_kohls.com.out
@@ -15,4 +15,4 @@ CREDIT_CARD_NUMBER | cardNumber | Card Number | | credit-card-cc CREDIT_CARD_EXP_MONTH | expMonth | Expiration Month: | | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | expYear | Expiration Year: | | credit-card-cc -UNKNOWN_TYPE | creditCardID | Credit Card ID | | paymentType_1-default +UNKNOWN_TYPE | creditCardID | Credit Card ID | | paymentType_2-default
diff --git a/components/test/data/autofill/heuristics/output/108_checkout_m_gap.com.out b/components/test/data/autofill/heuristics/output/108_checkout_m_gap.com.out index e19b954c..1b2b225 100644 --- a/components/test/data/autofill/heuristics/output/108_checkout_m_gap.com.out +++ b/components/test/data/autofill/heuristics/output/108_checkout_m_gap.com.out
@@ -5,38 +5,38 @@ ADDRESS_HOME_CITY | shippingAddressFieldGroup1-shippingCity | *Town/City | | shippingAddressFieldGroup1-shippingFirstName_1-default ADDRESS_HOME_ZIP | shippingAddressFieldGroup1-shippingPostalCode | *Zip code | | shippingAddressFieldGroup1-shippingFirstName_1-default ADDRESS_HOME_STATE | shippingAddressFieldGroup1-shippingState | *First name *Last Name *House Number and Street | | shippingAddressFieldGroup1-shippingFirstName_1-default -NAME_FIRST | shippingAddressFieldGroup2-shippingFirstName | *First name | | shippingAddressFieldGroup2-shippingFirstName_1-default -NAME_LAST | shippingAddressFieldGroup2-shippingLastName | *Last Name | | shippingAddressFieldGroup2-shippingFirstName_1-default -ADDRESS_HOME_LINE1 | shippingAddressFieldGroup2-shippingAddressLine1 | *House Number and Street | | shippingAddressFieldGroup2-shippingFirstName_1-default -ADDRESS_HOME_LINE2 | shippingAddressFieldGroup2-shippingAddressLine2 | Address line 2 | | shippingAddressFieldGroup2-shippingFirstName_1-default -ADDRESS_HOME_CITY | shippingAddressFieldGroup2-shippingCity | *Town/City | | shippingAddressFieldGroup2-shippingFirstName_1-default -ADDRESS_HOME_STATE | shippingAddressFieldGroup2-shippingState | *County | | shippingAddressFieldGroup2-shippingFirstName_1-default -ADDRESS_HOME_ZIP | shippingAddressFieldGroup2-shippingPostalCode | *Zip code | | shippingAddressFieldGroup2-shippingFirstName_1-default -NAME_FIRST | shippingAddressFieldGroup3-shippingFirstName | *First name | | shippingAddressFieldGroup3-shippingFirstName_1-default -NAME_LAST | shippingAddressFieldGroup3-shippingLastName | *Last Name | | shippingAddressFieldGroup3-shippingFirstName_1-default -ADDRESS_HOME_LINE1 | shippingAddressFieldGroup3-shippingAddressLine1 | *House Number and Street | | shippingAddressFieldGroup3-shippingFirstName_1-default -ADDRESS_HOME_LINE2 | shippingAddressFieldGroup3-shippingAddressLine2 | Address line 2 | | shippingAddressFieldGroup3-shippingFirstName_1-default -ADDRESS_HOME_CITY | shippingAddressFieldGroup3-shippingCity | *Town/City | | shippingAddressFieldGroup3-shippingFirstName_1-default -ADDRESS_HOME_STATE | shippingAddressFieldGroup3-shippingState | *State | | shippingAddressFieldGroup3-shippingFirstName_1-default -ADDRESS_HOME_STATE | shippingAddressFieldGroup3-shippingCounty | *County | | shippingAddressFieldGroup3-shippingFirstName_1-default -ADDRESS_HOME_ZIP | shippingAddressFieldGroup3-shippingPostalCode | *Zip code | | shippingAddressFieldGroup3-shippingFirstName_1-default -NAME_FIRST | shippingAddressFieldGroup4-shippingFirstName | *First name | | shippingAddressFieldGroup4-shippingFirstName_1-default -NAME_LAST | shippingAddressFieldGroup4-shippingLastName | *Last Name | | shippingAddressFieldGroup4-shippingFirstName_1-default -ADDRESS_HOME_LINE1 | shippingAddressFieldGroup4-shippingAddressLine1 | *House Number and Street | | shippingAddressFieldGroup4-shippingFirstName_1-default -ADDRESS_HOME_LINE2 | shippingAddressFieldGroup4-shippingAddressLine2 | Address line 2 | | shippingAddressFieldGroup4-shippingFirstName_1-default -ADDRESS_HOME_CITY | shippingAddressFieldGroup4-shippingCity | *Town/City | | shippingAddressFieldGroup4-shippingFirstName_1-default -ADDRESS_HOME_STATE | shippingAddressFieldGroup4-shippingState | *State | | shippingAddressFieldGroup4-shippingFirstName_1-default -ADDRESS_HOME_ZIP | shippingAddressFieldGroup4-shippingPostalCode | *Zip code | | shippingAddressFieldGroup4-shippingFirstName_1-default -NAME_LAST | shippingAddressFieldGroup5-shippingLastName | *Last Name | | shippingAddressFieldGroup5-shippingLastName_1-default -NAME_FIRST | shippingAddressFieldGroup5-shippingFirstName | *First name | | shippingAddressFieldGroup5-shippingLastName_1-default -ADDRESS_HOME_ZIP | shippingAddressFieldGroup5-shippingPostalCode | *Zip code | | shippingAddressFieldGroup5-shippingLastName_1-default -ADDRESS_HOME_STATE | shippingAddressFieldGroup5-shippingState | *State | | shippingAddressFieldGroup5-shippingLastName_1-default -ADDRESS_HOME_CITY | shippingAddressFieldGroup5-shippingCity | *Town/City | | shippingAddressFieldGroup5-shippingLastName_1-default -ADDRESS_HOME_LINE1 | shippingAddressFieldGroup5-shippingAddressLine1 | *House Number and Street | | shippingAddressFieldGroup5-shippingLastName_1-default -ADDRESS_HOME_LINE2 | shippingAddressFieldGroup5-shippingAddressLine2 | Address line 2 | | shippingAddressFieldGroup5-shippingLastName_1-default -PHONE_HOME_WHOLE_NUMBER | shippingDayPhone | * Day phone (incl. area code) | | shippingAddressFieldGroup5-shippingLastName_1-default -UNKNOWN_TYPE | shippingBillingSameAsShipping | Use this address for my Billing information. | on | shippingAddressFieldGroup5-shippingLastName_1-default -UNKNOWN_TYPE | shippingOptions | 7-9 business days - $0.00 | 7 | shippingAddressFieldGroup5-shippingLastName_1-default -UNKNOWN_TYPE | shippingOptions | 3-5 business days - $7.00 | 1 | shippingAddressFieldGroup5-shippingLastName_1-default -UNKNOWN_TYPE | shippingOptions | 2 business days - $17.00 | 3 | shippingAddressFieldGroup5-shippingLastName_1-default -UNKNOWN_TYPE | shippingOptions | 1 business day - $22.00 | 5 | shippingAddressFieldGroup5-shippingLastName_1-default +NAME_FIRST | shippingAddressFieldGroup2-shippingFirstName | *First name | | shippingAddressFieldGroup2-shippingFirstName_2-default +NAME_LAST | shippingAddressFieldGroup2-shippingLastName | *Last Name | | shippingAddressFieldGroup2-shippingFirstName_2-default +ADDRESS_HOME_LINE1 | shippingAddressFieldGroup2-shippingAddressLine1 | *House Number and Street | | shippingAddressFieldGroup2-shippingFirstName_2-default +ADDRESS_HOME_LINE2 | shippingAddressFieldGroup2-shippingAddressLine2 | Address line 2 | | shippingAddressFieldGroup2-shippingFirstName_2-default +ADDRESS_HOME_CITY | shippingAddressFieldGroup2-shippingCity | *Town/City | | shippingAddressFieldGroup2-shippingFirstName_2-default +ADDRESS_HOME_STATE | shippingAddressFieldGroup2-shippingState | *County | | shippingAddressFieldGroup2-shippingFirstName_2-default +ADDRESS_HOME_ZIP | shippingAddressFieldGroup2-shippingPostalCode | *Zip code | | shippingAddressFieldGroup2-shippingFirstName_2-default +NAME_FIRST | shippingAddressFieldGroup3-shippingFirstName | *First name | | shippingAddressFieldGroup3-shippingFirstName_3-default +NAME_LAST | shippingAddressFieldGroup3-shippingLastName | *Last Name | | shippingAddressFieldGroup3-shippingFirstName_3-default +ADDRESS_HOME_LINE1 | shippingAddressFieldGroup3-shippingAddressLine1 | *House Number and Street | | shippingAddressFieldGroup3-shippingFirstName_3-default +ADDRESS_HOME_LINE2 | shippingAddressFieldGroup3-shippingAddressLine2 | Address line 2 | | shippingAddressFieldGroup3-shippingFirstName_3-default +ADDRESS_HOME_CITY | shippingAddressFieldGroup3-shippingCity | *Town/City | | shippingAddressFieldGroup3-shippingFirstName_3-default +ADDRESS_HOME_STATE | shippingAddressFieldGroup3-shippingState | *State | | shippingAddressFieldGroup3-shippingFirstName_3-default +ADDRESS_HOME_STATE | shippingAddressFieldGroup3-shippingCounty | *County | | shippingAddressFieldGroup3-shippingFirstName_3-default +ADDRESS_HOME_ZIP | shippingAddressFieldGroup3-shippingPostalCode | *Zip code | | shippingAddressFieldGroup3-shippingFirstName_3-default +NAME_FIRST | shippingAddressFieldGroup4-shippingFirstName | *First name | | shippingAddressFieldGroup4-shippingFirstName_4-default +NAME_LAST | shippingAddressFieldGroup4-shippingLastName | *Last Name | | shippingAddressFieldGroup4-shippingFirstName_4-default +ADDRESS_HOME_LINE1 | shippingAddressFieldGroup4-shippingAddressLine1 | *House Number and Street | | shippingAddressFieldGroup4-shippingFirstName_4-default +ADDRESS_HOME_LINE2 | shippingAddressFieldGroup4-shippingAddressLine2 | Address line 2 | | shippingAddressFieldGroup4-shippingFirstName_4-default +ADDRESS_HOME_CITY | shippingAddressFieldGroup4-shippingCity | *Town/City | | shippingAddressFieldGroup4-shippingFirstName_4-default +ADDRESS_HOME_STATE | shippingAddressFieldGroup4-shippingState | *State | | shippingAddressFieldGroup4-shippingFirstName_4-default +ADDRESS_HOME_ZIP | shippingAddressFieldGroup4-shippingPostalCode | *Zip code | | shippingAddressFieldGroup4-shippingFirstName_4-default +NAME_LAST | shippingAddressFieldGroup5-shippingLastName | *Last Name | | shippingAddressFieldGroup5-shippingLastName_5-default +NAME_FIRST | shippingAddressFieldGroup5-shippingFirstName | *First name | | shippingAddressFieldGroup5-shippingLastName_5-default +ADDRESS_HOME_ZIP | shippingAddressFieldGroup5-shippingPostalCode | *Zip code | | shippingAddressFieldGroup5-shippingLastName_5-default +ADDRESS_HOME_STATE | shippingAddressFieldGroup5-shippingState | *State | | shippingAddressFieldGroup5-shippingLastName_5-default +ADDRESS_HOME_CITY | shippingAddressFieldGroup5-shippingCity | *Town/City | | shippingAddressFieldGroup5-shippingLastName_5-default +ADDRESS_HOME_LINE1 | shippingAddressFieldGroup5-shippingAddressLine1 | *House Number and Street | | shippingAddressFieldGroup5-shippingLastName_5-default +ADDRESS_HOME_LINE2 | shippingAddressFieldGroup5-shippingAddressLine2 | Address line 2 | | shippingAddressFieldGroup5-shippingLastName_5-default +PHONE_HOME_WHOLE_NUMBER | shippingDayPhone | * Day phone (incl. area code) | | shippingAddressFieldGroup5-shippingLastName_5-default +UNKNOWN_TYPE | shippingBillingSameAsShipping | Use this address for my Billing information. | on | shippingAddressFieldGroup5-shippingLastName_5-default +UNKNOWN_TYPE | shippingOptions | 7-9 business days - $0.00 | 7 | shippingAddressFieldGroup5-shippingLastName_5-default +UNKNOWN_TYPE | shippingOptions | 3-5 business days - $7.00 | 1 | shippingAddressFieldGroup5-shippingLastName_5-default +UNKNOWN_TYPE | shippingOptions | 2 business days - $17.00 | 3 | shippingAddressFieldGroup5-shippingLastName_5-default +UNKNOWN_TYPE | shippingOptions | 1 business day - $22.00 | 5 | shippingAddressFieldGroup5-shippingLastName_5-default
diff --git a/components/test/data/autofill/heuristics/output/112_checkout_m_llbean.com.out b/components/test/data/autofill/heuristics/output/112_checkout_m_llbean.com.out index a3e2103c..d6280c3 100644 --- a/components/test/data/autofill/heuristics/output/112_checkout_m_llbean.com.out +++ b/components/test/data/autofill/heuristics/output/112_checkout_m_llbean.com.out
@@ -4,30 +4,30 @@ NAME_LAST | _1_lastName | Last Name | | _1_personTitle_1-default UNKNOWN_TYPE | _1_gender | Male | M | _1_personTitle_1-default UNKNOWN_TYPE | _1_gender | Female | F | _1_personTitle_1-default -ADDRESS_HOME_COUNTRY | _1_country | Country USA & Territories | USA | _1_country_1-default -ADDRESS_HOME_ZIP | _1_JPNPostal | Postal Code | | _1_country_1-default -UNKNOWN_TYPE | _1_JPNPrefecture | Prefecture | | _1_country_1-default -ADDRESS_HOME_CITY | _1_JPNCity | City | | _1_country_1-default -ADDRESS_HOME_LINE1 | _1_address1 | Address | | _1_country_1-default -ADDRESS_HOME_LINE2 | _1_address2 | Address Line 2 (optional) | | _1_country_1-default -ADDRESS_HOME_LINE3 | _1_address3 | Address Line 3 (optional) | | _1_country_1-default -ADDRESS_HOME_ZIP | _1_zipCode | Enter Zip for City and State | | _1_zipCode_1-default -ADDRESS_HOME_CITY | _1_city | City | | _1_zipCode_1-default -ADDRESS_HOME_STATE | _1_state | | | _1_zipCode_1-default -ADDRESS_HOME_ZIP | _1_CAPostal | Postal Code | | _1_CAPostal_1-default -ADDRESS_HOME_CITY | _1_CACity | City | | _1_CAPostal_1-default -ADDRESS_HOME_STATE | _1_CAProvince | Province | | _1_CAPostal_1-default -ADDRESS_HOME_CITY | _1_INTLCity | City | | _1_CAPostal_1-default -ADDRESS_HOME_STATE | _1_INTLCounty | County | | _1_CAPostal_1-default -ADDRESS_HOME_ZIP | _1_INTLPostal | Postal Code | | _1_CAPostal_1-default -UNKNOWN_TYPE | _1_addressSelect | Home | homeAddress | _1_zipCode_1-default -UNKNOWN_TYPE | _1_addressSelect | Business | bizAddress | _1_zipCode_1-default -COMPANY_NAME | _1_otherAddress | Company Name (optional) | | _1_zipCode_1-default -PHONE_HOME_WHOLE_NUMBER | _1_phone1 | Daytime Phone Number | | _1_zipCode_1-default -PHONE_HOME_WHOLE_NUMBER | _1_intlPhone1Prefix | Daytime Phone Number | | _1_zipCode_1-default -PHONE_HOME_WHOLE_NUMBER | _1_intlPhone1 | Daytime Phone Number | | _1_zipCode_1-default -UNKNOWN_TYPE | _1_phone1_Loc | Home | H | _1_zipCode_1-default -UNKNOWN_TYPE | _1_phone1_Loc | Work | B | _1_zipCode_1-default -UNKNOWN_TYPE | _1_phone1_Loc | Mobile | M | _1_zipCode_1-default -UNKNOWN_TYPE | _1_ckoutShippingCheck | Include my phone number on shipping forms | ckoutShippingCheck | _1_zipCode_1-default -UNKNOWN_TYPE | _1_shipLiability | I accept liability for shipping these items uninsured | on | _1_zipCode_1-default +ADDRESS_HOME_COUNTRY | _1_country | Country USA & Territories | USA | _1_country_2-default +ADDRESS_HOME_ZIP | _1_JPNPostal | Postal Code | | _1_country_2-default +UNKNOWN_TYPE | _1_JPNPrefecture | Prefecture | | _1_country_2-default +ADDRESS_HOME_CITY | _1_JPNCity | City | | _1_country_2-default +ADDRESS_HOME_LINE1 | _1_address1 | Address | | _1_country_2-default +ADDRESS_HOME_LINE2 | _1_address2 | Address Line 2 (optional) | | _1_country_2-default +ADDRESS_HOME_LINE3 | _1_address3 | Address Line 3 (optional) | | _1_country_2-default +ADDRESS_HOME_ZIP | _1_zipCode | Enter Zip for City and State | | _1_zipCode_3-default +ADDRESS_HOME_CITY | _1_city | City | | _1_zipCode_3-default +ADDRESS_HOME_STATE | _1_state | | | _1_zipCode_3-default +ADDRESS_HOME_ZIP | _1_CAPostal | Postal Code | | _1_CAPostal_4-default +ADDRESS_HOME_CITY | _1_CACity | City | | _1_CAPostal_4-default +ADDRESS_HOME_STATE | _1_CAProvince | Province | | _1_CAPostal_4-default +ADDRESS_HOME_CITY | _1_INTLCity | City | | _1_CAPostal_4-default +ADDRESS_HOME_STATE | _1_INTLCounty | County | | _1_CAPostal_4-default +ADDRESS_HOME_ZIP | _1_INTLPostal | Postal Code | | _1_CAPostal_4-default +UNKNOWN_TYPE | _1_addressSelect | Home | homeAddress | _1_zipCode_3-default +UNKNOWN_TYPE | _1_addressSelect | Business | bizAddress | _1_zipCode_3-default +COMPANY_NAME | _1_otherAddress | Company Name (optional) | | _1_zipCode_3-default +PHONE_HOME_WHOLE_NUMBER | _1_phone1 | Daytime Phone Number | | _1_zipCode_3-default +PHONE_HOME_WHOLE_NUMBER | _1_intlPhone1Prefix | Daytime Phone Number | | _1_zipCode_3-default +PHONE_HOME_WHOLE_NUMBER | _1_intlPhone1 | Daytime Phone Number | | _1_zipCode_3-default +UNKNOWN_TYPE | _1_phone1_Loc | Home | H | _1_zipCode_3-default +UNKNOWN_TYPE | _1_phone1_Loc | Work | B | _1_zipCode_3-default +UNKNOWN_TYPE | _1_phone1_Loc | Mobile | M | _1_zipCode_3-default +UNKNOWN_TYPE | _1_ckoutShippingCheck | Include my phone number on shipping forms | ckoutShippingCheck | _1_zipCode_3-default +UNKNOWN_TYPE | _1_shipLiability | I accept liability for shipping these items uninsured | on | _1_zipCode_3-default
diff --git a/components/test/data/autofill/heuristics/output/118_checkout_cvs.com.out b/components/test/data/autofill/heuristics/output/118_checkout_cvs.com.out index 27073b7..9945787 100644 --- a/components/test/data/autofill/heuristics/output/118_checkout_cvs.com.out +++ b/components/test/data/autofill/heuristics/output/118_checkout_cvs.com.out
@@ -9,32 +9,32 @@ UNKNOWN_TYPE | orderConfirmation | Send order information to somebody@example.com. | on | fname_1-default EMAIL_ADDRESS | cemail | Specify a different email address: | | fname_1-default UNKNOWN_TYPE | bopusPerson | ... will pick up order. | on | fname_1-default -NAME_FIRST | bdfname | First Name | | bdfname_1-default -NAME_LAST | bdlname | Last Name | | bdfname_1-default -PHONE_HOME_WHOLE_NUMBER | bdphone | Phone Number | | bdfname_1-default -UNKNOWN_TYPE | bopusSMSagree | Text me information from CVS/pharmacy, including information about my order. I Agree to the Mobile Terms of Use. | on | bdfname_1-default -UNKNOWN_TYPE | orderConfirmation1 | Send order information to . | on | bdfname_1-default -EMAIL_ADDRESS | bdemail | Specify a different email address | | bdfname_1-default -UNKNOWN_TYPE | bopusSMSagree1 | Text me information from CVS/pharmacy�, including information about my order. | on | bdfname_1-default -UNKNOWN_TYPE | fsaValue | I would like to apply $0.00 of eligible items in this order to my FSA Debit Card. | on | bdfname_1-default -UNKNOWN_TYPE | fsaValue1 | I would like to apply $0.00 of eligible items in this order to my FSA Debit Card. | on | bdfname_1-default +NAME_FIRST | bdfname | First Name | | bdfname_2-default +NAME_LAST | bdlname | Last Name | | bdfname_2-default +PHONE_HOME_WHOLE_NUMBER | bdphone | Phone Number | | bdfname_2-default +UNKNOWN_TYPE | bopusSMSagree | Text me information from CVS/pharmacy, including information about my order. I Agree to the Mobile Terms of Use. | on | bdfname_2-default +UNKNOWN_TYPE | orderConfirmation1 | Send order information to . | on | bdfname_2-default +EMAIL_ADDRESS | bdemail | Specify a different email address | | bdfname_2-default +UNKNOWN_TYPE | bopusSMSagree1 | Text me information from CVS/pharmacy�, including information about my order. | on | bdfname_2-default +UNKNOWN_TYPE | fsaValue | I would like to apply $0.00 of eligible items in this order to my FSA Debit Card. | on | bdfname_2-default +UNKNOWN_TYPE | fsaValue1 | I would like to apply $0.00 of eligible items in this order to my FSA Debit Card. | on | bdfname_2-default CREDIT_CARD_NUMBER | ccfield | FSA Card | | credit-card-cc -PHONE_HOME_WHOLE_NUMBER | expfield | First Name Last Name Street Address Apartment, Building, Floor, Etc City State ZIP Code Phone Number FSA Card Exp FSA Card Exp First Name Last Name Street Address Apartment, Building, Floor, Etc City State ZIP Code Phone Number Credit Card Exp Credit Card Exp First Name Last Name Street Address Apartment, Building, Floor, Etc City State ZIP Code Phone Number | | bdfname_1-default +PHONE_HOME_WHOLE_NUMBER | expfield | First Name Last Name Street Address Apartment, Building, Floor, Etc City State ZIP Code Phone Number FSA Card Exp FSA Card Exp First Name Last Name Street Address Apartment, Building, Floor, Etc City State ZIP Code Phone Number Credit Card Exp Credit Card Exp First Name Last Name Street Address Apartment, Building, Floor, Etc City State ZIP Code Phone Number | | bdfname_2-default CREDIT_CARD_VERIFICATION_CODE | cvvfield | Specify a different email address: First Name Last Name Phone Number Specify a different email address CVV CVV CVV CVV | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | cvvfield | | CVV | | credit-card-cc CREDIT_CARD_NUMBER | ccfield | FSA Card | | credit-card-cc CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR | expfield | Exp | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | cvvfield | CVV | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | cvvfield | |CVV | | credit-card-cc -UNKNOWN_TYPE | chk1 | Use ... as Billing Address. | on | bdfname_1-default -NAME_FIRST | ffname | First Name | | bdfname_1-default -NAME_LAST | flname | Last Name | | bdfname_1-default -ADDRESS_HOME_LINE1 | fstreetAddr | Street Address | | bdfname_1-default -ADDRESS_HOME_LINE2 | fstreetAddr1 | Apartment, Building, Floor, Etc | | bdfname_1-default -ADDRESS_HOME_CITY | fcity | City | | bdfname_1-default -ADDRESS_HOME_STATE | sstateName | State | 0 | bdfname_1-default -ADDRESS_HOME_ZIP | fzip | ZIP Code | | bdfname_1-default -PHONE_HOME_WHOLE_NUMBER | fphone | Phone Number | | bdfname_1-default +UNKNOWN_TYPE | chk1 | Use ... as Billing Address. | on | bdfname_2-default +NAME_FIRST | ffname | First Name | | bdfname_2-default +NAME_LAST | flname | Last Name | | bdfname_2-default +ADDRESS_HOME_LINE1 | fstreetAddr | Street Address | | bdfname_2-default +ADDRESS_HOME_LINE2 | fstreetAddr1 | Apartment, Building, Floor, Etc | | bdfname_2-default +ADDRESS_HOME_CITY | fcity | City | | bdfname_2-default +ADDRESS_HOME_STATE | sstateName | State | 0 | bdfname_2-default +ADDRESS_HOME_ZIP | fzip | ZIP Code | | bdfname_2-default +PHONE_HOME_WHOLE_NUMBER | fphone | Phone Number | | bdfname_2-default CREDIT_CARD_NUMBER | ccfield | Credit Card | | credit-card-cc CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR | expfield | Exp | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | cvvfield | CVV | | credit-card-cc @@ -45,11 +45,11 @@ CREDIT_CARD_VERIFICATION_CODE | cvvfield | |CVV | | credit-card-cc UNKNOWN_TYPE | billing | Use ... | on | fname_1-default UNKNOWN_TYPE | newaddress | Specify a Different Billing Address Specify a Billing Address: | | fname_1-default -NAME_FIRST | ufname | First Name | | ufname_1-default -NAME_LAST | ulname | Last Name | | ufname_1-default -ADDRESS_HOME_LINE1 | ustreetAddr | Street Address | | ufname_1-default -ADDRESS_HOME_LINE2 | ustreetAddr1 | Apartment, Building, Floor, Etc | | ufname_1-default -ADDRESS_HOME_CITY | ucity | City | | ufname_1-default -ADDRESS_HOME_STATE | ustateName | State | 0 | ufname_1-default -ADDRESS_HOME_ZIP | uzip | ZIP Code | | ufname_1-default -PHONE_HOME_WHOLE_NUMBER | uphone | Phone Number | | ufname_1-default +NAME_FIRST | ufname | First Name | | ufname_4-default +NAME_LAST | ulname | Last Name | | ufname_4-default +ADDRESS_HOME_LINE1 | ustreetAddr | Street Address | | ufname_4-default +ADDRESS_HOME_LINE2 | ustreetAddr1 | Apartment, Building, Floor, Etc | | ufname_4-default +ADDRESS_HOME_CITY | ucity | City | | ufname_4-default +ADDRESS_HOME_STATE | ustateName | State | 0 | ufname_4-default +ADDRESS_HOME_ZIP | uzip | ZIP Code | | ufname_4-default +PHONE_HOME_WHOLE_NUMBER | uphone | Phone Number | | ufname_4-default
diff --git a/components/test/data/autofill/heuristics/output/127_bug_463986.out b/components/test/data/autofill/heuristics/output/127_bug_463986.out index 88c35e9..fe10365 100644 --- a/components/test/data/autofill/heuristics/output/127_bug_463986.out +++ b/components/test/data/autofill/heuristics/output/127_bug_463986.out
@@ -30,28 +30,28 @@ CREDIT_CARD_EXP_MONTH | accountExpiryMonth | Expiration Date | - | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | accountExpiryYear | Expiration Date | - | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | accountVerification | Verification Number * | | credit-card-cc -ADDRESS_HOME_COUNTRY | accountCountry | Country | | accountCountry_1-default -UNKNOWN_TYPE | bankAccHolder | Account holder | | accountCountry_1-default -UNKNOWN_TYPE | accountNo | Account Number | | accountCountry_1-default -UNKNOWN_TYPE | accountClearing | Bank Clearing | | accountCountry_1-default -UNKNOWN_TYPE | accountBank | Bank Code | | accountCountry_1-default -UNKNOWN_TYPE | checkingAccountNumber | Bank Name | | accountCountry_1-default -UNKNOWN_TYPE | codeCIN | Code CIN | | accountCountry_1-default -UNKNOWN_TYPE | codeABI | Code ABI | | accountCountry_1-default -UNKNOWN_TYPE | codeCAB | Code CAB | | accountCountry_1-default -ADDRESS_HOME_ZIP | codigoEntidad | Codigo de Entidad | | accountCountry_1-default -ADDRESS_HOME_ZIP | codigoOficina | Codigo de Oficina | | accountCountry_1-default -UNKNOWN_TYPE | controlDigits | Digitos de Control | | accountCountry_1-default -UNKNOWN_TYPE | identificationPaper | Digitos de Control | IDCARD | accountCountry_1-default -UNKNOWN_TYPE | identificationValue | Digitos de Control | | accountCountry_1-default -UNKNOWN_TYPE | virtualAccountBrand | Provider | | accountCountry_1-default -UNKNOWN_TYPE | virtualAccountId | Username / Id | | accountCountry_1-default -UNKNOWN_TYPE | userAccountBrand | Provider | | accountCountry_1-default -UNKNOWN_TYPE | userAccountId | Username / Id | | accountCountry_1-default -UNKNOWN_TYPE | userAccountPassword | Password | | accountCountry_1-default -UNKNOWN_TYPE | userAccountPasswordReType | Re-type password | | accountCountry_1-default -ADDRESS_HOME_COUNTRY | onlineTransferCountry | Country | US | accountCountry_1-default -UNKNOWN_TYPE | onlineTransferInstitute | Bank | ACHSECUR | accountCountry_1-default -UNKNOWN_TYPE | otAccountNumber | Account No. | | accountCountry_1-default -UNKNOWN_TYPE | otBankCode | Bank Code | | accountCountry_1-default +ADDRESS_HOME_COUNTRY | accountCountry | Country | | accountCountry_3-default +UNKNOWN_TYPE | bankAccHolder | Account holder | | accountCountry_3-default +UNKNOWN_TYPE | accountNo | Account Number | | accountCountry_3-default +UNKNOWN_TYPE | accountClearing | Bank Clearing | | accountCountry_3-default +UNKNOWN_TYPE | accountBank | Bank Code | | accountCountry_3-default +UNKNOWN_TYPE | checkingAccountNumber | Bank Name | | accountCountry_3-default +UNKNOWN_TYPE | codeCIN | Code CIN | | accountCountry_3-default +UNKNOWN_TYPE | codeABI | Code ABI | | accountCountry_3-default +UNKNOWN_TYPE | codeCAB | Code CAB | | accountCountry_3-default +ADDRESS_HOME_ZIP | codigoEntidad | Codigo de Entidad | | accountCountry_3-default +ADDRESS_HOME_ZIP | codigoOficina | Codigo de Oficina | | accountCountry_3-default +UNKNOWN_TYPE | controlDigits | Digitos de Control | | accountCountry_3-default +UNKNOWN_TYPE | identificationPaper | Digitos de Control | IDCARD | accountCountry_3-default +UNKNOWN_TYPE | identificationValue | Digitos de Control | | accountCountry_3-default +UNKNOWN_TYPE | virtualAccountBrand | Provider | | accountCountry_3-default +UNKNOWN_TYPE | virtualAccountId | Username / Id | | accountCountry_3-default +UNKNOWN_TYPE | userAccountBrand | Provider | | accountCountry_3-default +UNKNOWN_TYPE | userAccountId | Username / Id | | accountCountry_3-default +UNKNOWN_TYPE | userAccountPassword | Password | | accountCountry_3-default +UNKNOWN_TYPE | userAccountPasswordReType | Re-type password | | accountCountry_3-default +ADDRESS_HOME_COUNTRY | onlineTransferCountry | Country | US | accountCountry_3-default +UNKNOWN_TYPE | onlineTransferInstitute | Bank | ACHSECUR | accountCountry_3-default +UNKNOWN_TYPE | otAccountNumber | Account No. | | accountCountry_3-default +UNKNOWN_TYPE | otBankCode | Bank Code | | accountCountry_3-default UNKNOWN_TYPE | accept | I read and understood and I accept the terms in force in IKEA | on | salutation_1-default
diff --git a/components/test/data/autofill/heuristics/output/128_bug_464002.out b/components/test/data/autofill/heuristics/output/128_bug_464002.out index 8607779..56e53de3 100644 --- a/components/test/data/autofill/heuristics/output/128_bug_464002.out +++ b/components/test/data/autofill/heuristics/output/128_bug_464002.out
@@ -3,5 +3,5 @@ CREDIT_CARD_VERIFICATION_CODE | paymentMethodForm.cardVerificationNumber | Security code* | | credit-card-cc CREDIT_CARD_EXP_MONTH | paymentMethodForm.expirationMonth | 04 | | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | paymentMethodForm.expirationYear | 2018 | | credit-card-cc -ADDRESS_HOME_ZIP | paymentMethodForm.zip | Card billing ZIP Code* | | paymentMethodForm.newCreditCardCustomerName_1-default -UNKNOWN_TYPE | paymentMethodForm.custCode | Customer code | | paymentMethodForm.newCreditCardCustomerName_1-default +ADDRESS_HOME_ZIP | paymentMethodForm.zip | Card billing ZIP Code* | | paymentMethodForm.newCreditCardCustomerName_2-default +UNKNOWN_TYPE | paymentMethodForm.custCode | Customer code | | paymentMethodForm.newCreditCardCustomerName_2-default
diff --git a/components/test/data/autofill/heuristics/output/129_bug_465053.out b/components/test/data/autofill/heuristics/output/129_bug_465053.out index 9778b200..61c619f9 100644 --- a/components/test/data/autofill/heuristics/output/129_bug_465053.out +++ b/components/test/data/autofill/heuristics/output/129_bug_465053.out
@@ -3,10 +3,10 @@ CREDIT_CARD_EXP_2_DIGIT_YEAR | | YY | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | | CVC | | credit-card-cc CREDIT_CARD_NAME_FULL | | Cardholder name | | credit-card-cc -COMPANY_NAME | ORGANIZATION | Business name | | _1-default -NAME_FULL | RECIPIENT | Name | | _1-default -ADDRESS_HOME_LINE1 | ADDRESS_LINE_1 | Street address | | _1-default -ADDRESS_HOME_LINE2 | ADDRESS_LINE_2 | Apt./Suite | | _1-default -ADDRESS_HOME_CITY | LOCALITY | City | | _1-default -ADDRESS_HOME_ZIP | POSTAL_CODE | ZIP code | | _1-default -ADDRESS_HOME_COUNTRY | COUNTRY | Country | US | _1-default +COMPANY_NAME | ORGANIZATION | Business name | | _2-default +NAME_FULL | RECIPIENT | Name | | _2-default +ADDRESS_HOME_LINE1 | ADDRESS_LINE_1 | Street address | | _2-default +ADDRESS_HOME_LINE2 | ADDRESS_LINE_2 | Apt./Suite | | _2-default +ADDRESS_HOME_CITY | LOCALITY | City | | _2-default +ADDRESS_HOME_ZIP | POSTAL_CODE | ZIP code | | _2-default +ADDRESS_HOME_COUNTRY | COUNTRY | Country | US | _2-default
diff --git a/components/test/data/autofill/heuristics/output/130_bug_465576.out b/components/test/data/autofill/heuristics/output/130_bug_465576.out index ec56d061..913df522e 100644 --- a/components/test/data/autofill/heuristics/output/130_bug_465576.out +++ b/components/test/data/autofill/heuristics/output/130_bug_465576.out
@@ -3,4 +3,4 @@ CREDIT_CARD_EXP_MONTH | expirationMonth | Expiry Date * | | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | expirationYear | Expiry Date * | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | cvNumber | security code * | | credit-card-cc -PHONE_HOME_WHOLE_NUMBER | phoneNumber | Billing Phone Your registered number with your payment issuer is required to process your order. * | | cardTypeSelect_1-default +PHONE_HOME_WHOLE_NUMBER | phoneNumber | Billing Phone Your registered number with your payment issuer is required to process your order. * | | cardTypeSelect_2-default
diff --git a/components/test/data/autofill/heuristics/output/132_bug_469012.out b/components/test/data/autofill/heuristics/output/132_bug_469012.out index 3f71c3f..a9dccda 100644 --- a/components/test/data/autofill/heuristics/output/132_bug_469012.out +++ b/components/test/data/autofill/heuristics/output/132_bug_469012.out
@@ -2,13 +2,13 @@ CREDIT_CARD_NUMBER | cardnumber | Your cardnumber | | credit-card-cc CREDIT_CARD_EXP_MONTH | expire_month | Expiration Date | | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | expire_year | | | credit-card-cc -NAME_FIRST | firstname | First Name * | | cardissuer_1-default -NAME_LAST | lastname | Last Name * | | cardissuer_1-default -ADDRESS_HOME_LINE1 | address1 | Address * | | cardissuer_1-default -ADDRESS_HOME_LINE2 | unit | Unit # | | cardissuer_1-default -ADDRESS_HOME_LINE3 | address2 | Address Line 2 | | cardissuer_1-default -ADDRESS_HOME_CITY | city | City * | | cardissuer_1-default -ADDRESS_HOME_STATE | state | State * | | cardissuer_1-default -ADDRESS_HOME_ZIP | zip | State * | | cardissuer_1-default -ADDRESS_HOME_COUNTRY | country | Country * | us | cardissuer_1-default -PHONE_HOME_WHOLE_NUMBER | phonenumber | Mobile Phone* | | cardissuer_1-default +NAME_FIRST | firstname | First Name * | | cardissuer_2-default +NAME_LAST | lastname | Last Name * | | cardissuer_2-default +ADDRESS_HOME_LINE1 | address1 | Address * | | cardissuer_2-default +ADDRESS_HOME_LINE2 | unit | Unit # | | cardissuer_2-default +ADDRESS_HOME_LINE3 | address2 | Address Line 2 | | cardissuer_2-default +ADDRESS_HOME_CITY | city | City * | | cardissuer_2-default +ADDRESS_HOME_STATE | state | State * | | cardissuer_2-default +ADDRESS_HOME_ZIP | zip | State * | | cardissuer_2-default +ADDRESS_HOME_COUNTRY | country | Country * | us | cardissuer_2-default +PHONE_HOME_WHOLE_NUMBER | phonenumber | Mobile Phone* | | cardissuer_2-default
diff --git a/components/test/data/autofill/heuristics/output/133_bug_469472.out b/components/test/data/autofill/heuristics/output/133_bug_469472.out index 5943cdd6..8bf613a 100644 --- a/components/test/data/autofill/heuristics/output/133_bug_469472.out +++ b/components/test/data/autofill/heuristics/output/133_bug_469472.out
@@ -1,8 +1,8 @@ CREDIT_CARD_NUMBER | cc_number | Debit or Prepaid gift card number | | credit-card-cc -UNKNOWN_TYPE | credit_card_type | Visa | V | cc_number_1-default -UNKNOWN_TYPE | credit_card_type | MasterCard | M | cc_number_1-default -UNKNOWN_TYPE | credit_card_type | Discover | D | cc_number_1-default -UNKNOWN_TYPE | credit_card_type | American Express | A | cc_number_1-default +UNKNOWN_TYPE | credit_card_type | Visa | V | cc_number_2-default +UNKNOWN_TYPE | credit_card_type | MasterCard | M | cc_number_2-default +UNKNOWN_TYPE | credit_card_type | Discover | D | cc_number_2-default +UNKNOWN_TYPE | credit_card_type | American Express | A | cc_number_2-default CREDIT_CARD_EXP_MONTH | expdate_month | Month | | credit-card-cc CREDIT_CARD_EXP_2_DIGIT_YEAR | expdate_year | Year | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | cvv2_number | CSC What is this? For American Express, it's the four digits on the front of the card.For MasterCard, Visa or Discover, it's the last three digits in the signature area on the back of your card. | | credit-card-cc
diff --git a/components/test/data/autofill/heuristics/output/137_bug_555010.out b/components/test/data/autofill/heuristics/output/137_bug_555010.out index 69283c92..02366ec 100644 --- a/components/test/data/autofill/heuristics/output/137_bug_555010.out +++ b/components/test/data/autofill/heuristics/output/137_bug_555010.out
@@ -1,24 +1,24 @@ UNKNOWN_TYPE | userName | Username or Email address | | userName_1-default UNKNOWN_TYPE | password | Password | | userName_1-default CREDIT_CARD_NAME_FULL | cardName | Full Name (First Name Last Name) | | credit-card-cc -ADDRESS_HOME_LINE1 | id_skCOShipAddress | Shipping Address | | cardName_1-default -UNKNOWN_TYPE | id_skCOShipAptBldg | Apt/Bldg (optional) | | cardName_1-default -PHONE_HOME_WHOLE_NUMBER | id_skCOPhoneno | Phone | | cardName_1-default -EMAIL_ADDRESS | id_skCOEmail | Email | | cardName_1-default +ADDRESS_HOME_LINE1 | id_skCOShipAddress | Shipping Address | | cardName_2-default +UNKNOWN_TYPE | id_skCOShipAptBldg | Apt/Bldg (optional) | | cardName_2-default +PHONE_HOME_WHOLE_NUMBER | id_skCOPhoneno | Phone | | cardName_2-default +EMAIL_ADDRESS | id_skCOEmail | Email | | cardName_2-default CREDIT_CARD_NUMBER | cardNumber | 1234 5647 8901 2345 | | credit-card-cc CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR | expirationMonth | EXP | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | cvv | CVV | | credit-card-cc CREDIT_CARD_NAME_FULL | id_skCOName | Card Holder Name | | credit-card-cc -ADDRESS_HOME_LINE1 | id_skCOShipAddress | Billing Address | | id_skCOShipAddress_2-default -UNKNOWN_TYPE | id_skCOShipAptBldg | Apt/Bldg (optional) | | id_skCOShipAddress_2-default -PHONE_HOME_WHOLE_NUMBER | id_skCOPhoneno | Phone | | id_skCOShipAddress_2-default -NAME_FULL | id_skCOName | Name | | id_skCOShipAddress_2-default -ADDRESS_HOME_LINE1 | id_skCOShipAddress | Address | | id_skCOShipAddress_3-default +ADDRESS_HOME_LINE1 | id_skCOShipAddress | Billing Address | | id_skCOShipAddress_3-default UNKNOWN_TYPE | id_skCOShipAptBldg | Apt/Bldg (optional) | | id_skCOShipAddress_3-default PHONE_HOME_WHOLE_NUMBER | id_skCOPhoneno | Phone | | id_skCOShipAddress_3-default +NAME_FULL | id_skCOName | Name | | id_skCOShipAddress_3-default +ADDRESS_HOME_LINE1 | id_skCOShipAddress | Address | | id_skCOShipAddress_4-default +UNKNOWN_TYPE | id_skCOShipAptBldg | Apt/Bldg (optional) | | id_skCOShipAddress_4-default +PHONE_HOME_WHOLE_NUMBER | id_skCOPhoneno | Phone | | id_skCOShipAddress_4-default CREDIT_CARD_NUMBER | cardNumber | 1234 5647 8901 2345 | | credit-card-cc CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR | expirationMonth | EXP | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | cvv | CVV | | credit-card-cc CREDIT_CARD_NAME_FULL | id_skAltPUName | Name | | credit-card-cc -PHONE_HOME_WHOLE_NUMBER | id_skAltPUPhoneno | Phone | | id_skCOShipAddress_3-default -EMAIL_ADDRESS | id_skAltPUEmail | Email | | id_skCOShipAddress_3-default +PHONE_HOME_WHOLE_NUMBER | id_skAltPUPhoneno | Phone | | id_skCOShipAddress_4-default +EMAIL_ADDRESS | id_skAltPUEmail | Email | | id_skCOShipAddress_4-default
diff --git a/components/test/data/autofill/heuristics/output/138_cc_checkout_united.com.out b/components/test/data/autofill/heuristics/output/138_cc_checkout_united.com.out index 774f300..713e795 100644 --- a/components/test/data/autofill/heuristics/output/138_cc_checkout_united.com.out +++ b/components/test/data/autofill/heuristics/output/138_cc_checkout_united.com.out
@@ -6,49 +6,49 @@ CREDIT_CARD_EXP_4_DIGIT_YEAR | CreditCardViewModels[0].ExpYear | Year* | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | CreditCardViewModels[0].SecurityCode | Security code* | | credit-card-cc CREDIT_CARD_NAME_FULL | CreditCardViewModels[0].CardHolderName | Full name as it appears on your card* | | credit-card-cc -ADDRESS_HOME_LINE1 | CreditCardViewModels[0].AddressLine1 | Billing address line 1* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_LINE2 | CreditCardViewModels[0].AddressLine2 | Billing address line 2 (Optional) | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_LINE3 | CreditCardViewModels[0].AddressLine3 | Billing address line 3 (Optional) | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_CITY | CreditCardViewModels[0].City | City/town/department* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_STATE | CreditCardViewModels[0].StateCode | State/province/region/county* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_ZIP | CreditCardViewModels[0].PostalCode | ZIP/Postal code* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_COUNTRY | CreditCardViewModels[0].CountryCode | Country* | US | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | FOPOption | Other forms of payment | OtherFop | CreditCardViewModels[0].CardTypeCode_1-default +ADDRESS_HOME_LINE1 | CreditCardViewModels[0].AddressLine1 | Billing address line 1* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_LINE2 | CreditCardViewModels[0].AddressLine2 | Billing address line 2 (Optional) | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_LINE3 | CreditCardViewModels[0].AddressLine3 | Billing address line 3 (Optional) | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_CITY | CreditCardViewModels[0].City | City/town/department* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_STATE | CreditCardViewModels[0].StateCode | State/province/region/county* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_ZIP | CreditCardViewModels[0].PostalCode | ZIP/Postal code* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_COUNTRY | CreditCardViewModels[0].CountryCode | Country* | US | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | FOPOption | Other forms of payment | OtherFop | CreditCardViewModels[0].CardTypeCode_2-default CREDIT_CARD_TYPE | OtherFOPType | Form of payment | | credit-card-cc CREDIT_CARD_NAME_FULL | AlipayCardHolderName | Full name as it appears on your card* | | credit-card-cc -ADDRESS_HOME_LINE1 | AlipayBillingAddressLine1 | Billing address line 1* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_LINE2 | AlipayBillingAddressLine2 | Billing address line 2 (Optional) | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_LINE3 | AlipayBillingAddressLine3 | Billing address line 3 (Optional) | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_CITY | AlipayCity | City/town/department* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_ZIP | AlipayZipCode | ZIP/Postal code* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_COUNTRY | AlipayCountryCode | United States | US | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_LINE1 | PayPalBillingAddress | Billing address* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_CITY | PayPalCity | City/town/department* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_STATE | PayPalState | State/province/region/county* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_ZIP | PayPalZipCode | ZIP/Postal code* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_COUNTRY | PayPalCountryCode | United States | US | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | WalletCCSecurityCode | Security code | | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | CashType | Western Union ($11.95 service charge per transaction) | WU | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | CashType | Airport Ticket Office (service charge per transaction may apply) | ATO | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | CashType | United Ticket Office (service charge per transaction may apply) | CTO | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | BmlModel.IfForSixMonthsNoPayment | Yes, I would like to make no payments for six months on orders greater than $250. | true | CreditCardViewModels[0].CardTypeCode_1-default -NAME_FIRST | BmlModel.FirstName | First name* | | CreditCardViewModels[0].CardTypeCode_1-default -NAME_LAST | BmlModel.LastName | Last name* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_LINE1 | BmlModel.BMLAddressLine1 | Billing address* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_CITY | BmlModel.BMLCity | City* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_STATE | BmlModel.BMLStateCode | State/territory/province* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_ZIP | BmlModel.BMLPostalCode | Zip/Postal code* | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_COUNTRY | BmlModel.BMLPhoneCountryAccessCode | Phone Country | US | CreditCardViewModels[0].CardTypeCode_1-default -PHONE_HOME_WHOLE_NUMBER | BmlModel.BMLPhoneNumber | Phone number* | | CreditCardViewModels[0].CardTypeCode_1-default -PHONE_HOME_EXTENSION | BmlModel.BMLPhoneExtension | Extension (Optional) | | CreditCardViewModels[0].CardTypeCode_1-default -EMAIL_ADDRESS | BmlModel.BMLEmail | Email address* | | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | BmlModel.DobMonth | Date Of Birth Month | | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | BmlModel.DobDay | DD* | | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | BmlModel.DobYear | YYYY* | | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | BmlModel.SocialSN | Last 4 digits* | | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | BmlModel.IfBMLTermsElectronicAccepted | I agree to have the PayPal Credit terms and conditions presented electronically | true | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | BmlModel.IfBMLTermsAccepted | I agree to the PayPal Credit terms and conditions | true | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | EmailAddressList | Your email address will be used to contact you about this reservation only. | | CreditCardViewModels[0].CardTypeCode_1-default -EMAIL_ADDRESS | PurchaserEmailAddress | Email address* | homer.simpson.duffman@gmail.com | CreditCardViewModels[0].CardTypeCode_1-default -UNKNOWN_TYPE | PhoneList | | | CreditCardViewModels[0].CardTypeCode_1-default -ADDRESS_HOME_COUNTRY | PhoneCountryCode | Country | US | CreditCardViewModels[0].CardTypeCode_1-default +ADDRESS_HOME_LINE1 | AlipayBillingAddressLine1 | Billing address line 1* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_LINE2 | AlipayBillingAddressLine2 | Billing address line 2 (Optional) | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_LINE3 | AlipayBillingAddressLine3 | Billing address line 3 (Optional) | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_CITY | AlipayCity | City/town/department* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_ZIP | AlipayZipCode | ZIP/Postal code* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_COUNTRY | AlipayCountryCode | United States | US | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_LINE1 | PayPalBillingAddress | Billing address* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_CITY | PayPalCity | City/town/department* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_STATE | PayPalState | State/province/region/county* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_ZIP | PayPalZipCode | ZIP/Postal code* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_COUNTRY | PayPalCountryCode | United States | US | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | WalletCCSecurityCode | Security code | | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | CashType | Western Union ($11.95 service charge per transaction) | WU | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | CashType | Airport Ticket Office (service charge per transaction may apply) | ATO | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | CashType | United Ticket Office (service charge per transaction may apply) | CTO | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | BmlModel.IfForSixMonthsNoPayment | Yes, I would like to make no payments for six months on orders greater than $250. | true | CreditCardViewModels[0].CardTypeCode_2-default +NAME_FIRST | BmlModel.FirstName | First name* | | CreditCardViewModels[0].CardTypeCode_2-default +NAME_LAST | BmlModel.LastName | Last name* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_LINE1 | BmlModel.BMLAddressLine1 | Billing address* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_CITY | BmlModel.BMLCity | City* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_STATE | BmlModel.BMLStateCode | State/territory/province* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_ZIP | BmlModel.BMLPostalCode | Zip/Postal code* | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_COUNTRY | BmlModel.BMLPhoneCountryAccessCode | Phone Country | US | CreditCardViewModels[0].CardTypeCode_2-default +PHONE_HOME_WHOLE_NUMBER | BmlModel.BMLPhoneNumber | Phone number* | | CreditCardViewModels[0].CardTypeCode_2-default +PHONE_HOME_EXTENSION | BmlModel.BMLPhoneExtension | Extension (Optional) | | CreditCardViewModels[0].CardTypeCode_2-default +EMAIL_ADDRESS | BmlModel.BMLEmail | Email address* | | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | BmlModel.DobMonth | Date Of Birth Month | | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | BmlModel.DobDay | DD* | | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | BmlModel.DobYear | YYYY* | | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | BmlModel.SocialSN | Last 4 digits* | | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | BmlModel.IfBMLTermsElectronicAccepted | I agree to have the PayPal Credit terms and conditions presented electronically | true | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | BmlModel.IfBMLTermsAccepted | I agree to the PayPal Credit terms and conditions | true | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | EmailAddressList | Your email address will be used to contact you about this reservation only. | | CreditCardViewModels[0].CardTypeCode_2-default +EMAIL_ADDRESS | PurchaserEmailAddress | Email address* | homer.simpson.duffman@gmail.com | CreditCardViewModels[0].CardTypeCode_2-default +UNKNOWN_TYPE | PhoneList | | | CreditCardViewModels[0].CardTypeCode_2-default +ADDRESS_HOME_COUNTRY | PhoneCountryCode | Country | US | CreditCardViewModels[0].CardTypeCode_2-default
diff --git a/components/test/data/autofill/heuristics/output/141_checkout_cc_keurig.com.out b/components/test/data/autofill/heuristics/output/141_checkout_cc_keurig.com.out index feea886..ba25e94 100644 --- a/components/test/data/autofill/heuristics/output/141_checkout_cc_keurig.com.out +++ b/components/test/data/autofill/heuristics/output/141_checkout_cc_keurig.com.out
@@ -2,9 +2,9 @@ CREDIT_CARD_NAME_LAST | card_lastNameOnCard | Last Name* | | credit-card-cc CREDIT_CARD_NUMBER | card_accountNumber | Card Number* | | credit-card-cc CREDIT_CARD_TYPE | card_cardType | Card Type | | credit-card-cc -UNKNOWN_TYPE | | Please select a card type | | card_firstNameOnCard_1-default +UNKNOWN_TYPE | | Please select a card type | | card_firstNameOnCard_2-default CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR | card_expirationMonth | Expiration Date* | | credit-card-cc -UNKNOWN_TYPE | | Month | | card_firstNameOnCard_1-default -UNKNOWN_TYPE | card_expirationYear | Expiration Date* | | card_firstNameOnCard_1-default -UNKNOWN_TYPE | | Year | | card_firstNameOnCard_1-default +UNKNOWN_TYPE | | Month | | card_firstNameOnCard_2-default +UNKNOWN_TYPE | card_expirationYear | Expiration Date* | | card_firstNameOnCard_2-default +UNKNOWN_TYPE | | Year | | card_firstNameOnCard_2-default CREDIT_CARD_VERIFICATION_CODE | card_cvNumber | Security Code* | | credit-card-cc
diff --git a/components/test/data/autofill/heuristics/output/144_cc_checkout_m_jcp.com.out b/components/test/data/autofill/heuristics/output/144_cc_checkout_m_jcp.com.out index 9169c2b8..6c84f4e 100644 --- a/components/test/data/autofill/heuristics/output/144_cc_checkout_m_jcp.com.out +++ b/components/test/data/autofill/heuristics/output/144_cc_checkout_m_jcp.com.out
@@ -2,17 +2,17 @@ CREDIT_CARD_EXP_MONTH | month-guest | Month | | credit-card-cc CREDIT_CARD_EXP_4_DIGIT_YEAR | year-guest | Expiration Date | | credit-card-cc CREDIT_CARD_VERIFICATION_CODE | c-v-v-guest | C V V | | credit-card-cc -UNKNOWN_TYPE | billingAsShipping | Same as shipping address | on | card-number-guest_1-default -NAME_FIRST | first-name-guest | First name | | card-number-guest_1-default -NAME_LAST | last-name-guest | Last name | | card-number-guest_1-default -ADDRESS_HOME_COUNTRY | country-guest | + Company (optional) | 1 | card-number-guest_1-default -COMPANY_NAME | company-guest | Company (Optional) | | card-number-guest_1-default -ADDRESS_HOME_LINE1 | address-1-guest | Street address | | card-number-guest_1-default -ADDRESS_HOME_LINE2 | address-2-guest | Street address 2 (optional) | | card-number-guest_1-default -UNKNOWN_TYPE | military-address-type | | | card-number-guest_1-default -ADDRESS_HOME_ZIP | zip-guest | Zip | | card-number-guest_1-default -ADDRESS_HOME_STATE | state-guest | | | card-number-guest_1-default -UNKNOWN_TYPE | military-state | | | card-number-guest_1-default -ADDRESS_HOME_CITY | city-guest | City | | card-number-guest_1-default -EMAIL_ADDRESS | email | Email address | | card-number-guest_1-default -PHONE_HOME_WHOLE_NUMBER | phone-guest | Phone number | | card-number-guest_1-default +UNKNOWN_TYPE | billingAsShipping | Same as shipping address | on | card-number-guest_2-default +NAME_FIRST | first-name-guest | First name | | card-number-guest_2-default +NAME_LAST | last-name-guest | Last name | | card-number-guest_2-default +ADDRESS_HOME_COUNTRY | country-guest | + Company (optional) | 1 | card-number-guest_2-default +COMPANY_NAME | company-guest | Company (Optional) | | card-number-guest_2-default +ADDRESS_HOME_LINE1 | address-1-guest | Street address | | card-number-guest_2-default +ADDRESS_HOME_LINE2 | address-2-guest | Street address 2 (optional) | | card-number-guest_2-default +UNKNOWN_TYPE | military-address-type | | | card-number-guest_2-default +ADDRESS_HOME_ZIP | zip-guest | Zip | | card-number-guest_2-default +ADDRESS_HOME_STATE | state-guest | | | card-number-guest_2-default +UNKNOWN_TYPE | military-state | | | card-number-guest_2-default +ADDRESS_HOME_CITY | city-guest | City | | card-number-guest_2-default +EMAIL_ADDRESS | email | Email address | | card-number-guest_2-default +PHONE_HOME_WHOLE_NUMBER | phone-guest | Phone number | | card-number-guest_2-default
diff --git a/components/test/data/autofill/heuristics/output/149_checkout_qvc.com_non_hidden.out b/components/test/data/autofill/heuristics/output/149_checkout_qvc.com_non_hidden.out index fded2eb7..ac5a6cd5 100644 --- a/components/test/data/autofill/heuristics/output/149_checkout_qvc.com_non_hidden.out +++ b/components/test/data/autofill/heuristics/output/149_checkout_qvc.com_non_hidden.out
@@ -19,11 +19,11 @@ PHONE_HOME_EXTENSION | BilltoWpExt | Work Phone: | | EmailAddress_1-default UNKNOWN_TYPE | SameAsBilltoCheckbox | Same as Bill-To: | 1 | EmailAddress_1-default UNKNOWN_TYPE | ShiptoFirstName | * Name: | | EmailAddress_1-default -ADDRESS_HOME_LINE1 | ShiptoAddress1 | * Address Line 1: | | ShiptoAddress1_1-default -ADDRESS_HOME_LINE2 | ShiptoAddress2 | Address Line 2: | | ShiptoAddress1_1-default -ADDRESS_HOME_CITY | ShiptoCity | City: | | ShiptoAddress1_1-default -ADDRESS_HOME_STATE | ShiptoState | State/Province: | AL | ShiptoAddress1_1-default -ADDRESS_HOME_ZIP | ShiptoZipCode | * Postal Code: | | ShiptoAddress1_1-default -ADDRESS_HOME_COUNTRY | ShiptoCountry | * Country: | US | ShiptoAddress1_1-default -UNKNOWN_TYPE | ShiptoRadiobutton | This order only | ThisOrderOnly | ShiptoAddress1_1-default -UNKNOWN_TYPE | ShiptoRadiobutton | (Permanent Ship-To)** All future orders | PermanentShipto | ShiptoAddress1_1-default +ADDRESS_HOME_LINE1 | ShiptoAddress1 | * Address Line 1: | | ShiptoAddress1_2-default +ADDRESS_HOME_LINE2 | ShiptoAddress2 | Address Line 2: | | ShiptoAddress1_2-default +ADDRESS_HOME_CITY | ShiptoCity | City: | | ShiptoAddress1_2-default +ADDRESS_HOME_STATE | ShiptoState | State/Province: | AL | ShiptoAddress1_2-default +ADDRESS_HOME_ZIP | ShiptoZipCode | * Postal Code: | | ShiptoAddress1_2-default +ADDRESS_HOME_COUNTRY | ShiptoCountry | * Country: | US | ShiptoAddress1_2-default +UNKNOWN_TYPE | ShiptoRadiobutton | This order only | ThisOrderOnly | ShiptoAddress1_2-default +UNKNOWN_TYPE | ShiptoRadiobutton | (Permanent Ship-To)** All future orders | PermanentShipto | ShiptoAddress1_2-default
diff --git a/components/test/data/autofill/heuristics/output/153_fmm-en_inm.gob.mx.out b/components/test/data/autofill/heuristics/output/153_fmm-en_inm.gob.mx.out index eb7dd63..59fd1a0 100644 --- a/components/test/data/autofill/heuristics/output/153_fmm-en_inm.gob.mx.out +++ b/components/test/data/autofill/heuristics/output/153_fmm-en_inm.gob.mx.out
@@ -13,26 +13,26 @@ UNKNOWN_TYPE | tipoDocumento | Type of document | 0 | internacion_1-default UNKNOWN_TYPE | numeroDocumento | Document number | | internacion_1-default UNKNOWN_TYPE | confirmarNumeroDocumento | Document number (Confirmation) | | internacion_1-default -ADDRESS_HOME_COUNTRY | paisExpedicion | Country of issue | 0 | paisExpedicion_1-default -UNKNOWN_TYPE | fechaExpedicion | Date of issue | | paisExpedicion_1-default -UNKNOWN_TYPE | confirmarFechaExpedicion | Date of issue (Confirmation) | | paisExpedicion_1-default -UNKNOWN_TYPE | fechaExpiracion | Expiration date | | paisExpedicion_1-default -UNKNOWN_TYPE | confirmarFechaExpiracion | Expiration date (Confirmation) | | paisExpedicion_1-default -ADDRESS_HOME_COUNTRY | paisResidencia | Country of residence | 0 | paisResidencia_1-default -ADDRESS_HOME_LINE1 | direccionResidencia | Address of residence | | paisResidencia_1-default -UNKNOWN_TYPE | motivoViaje | Reason of trip | 0 | paisResidencia_1-default -UNKNOWN_TYPE | especifiqueMotivo | Specify | 0 | paisResidencia_1-default -ADDRESS_HOME_STATE | estadoDestino | State | 0 | paisResidencia_1-default -ADDRESS_HOME_LINE1 | domicilioMexico | Address in Mexico | | domicilioMexico_1-default -NAME_FIRST | nombreTutor | Name(s) | | domicilioMexico_1-default -NAME_LAST | apellidosTutor | Surname(s) | | domicilioMexico_1-default -UNKNOWN_TYPE | sexoTutor | Gender | 0 | domicilioMexico_1-default -UNKNOWN_TYPE | fechaNacimientoTutor | Date of birth | | domicilioMexico_1-default -ADDRESS_HOME_COUNTRY | nacionalidadTutor | Nationality (Country) | 0 | domicilioMexico_1-default -ADDRESS_HOME_COUNTRY | paisNacimientoTutor | Country of birth | 0 | domicilioMexico_1-default -EMAIL_ADDRESS | correoElectronico | Email | | domicilioMexico_1-default -EMAIL_ADDRESS | confirmacionCorreoElectronico | Email (Confirmation) | | domicilioMexico_1-default -UNKNOWN_TYPE | captcha | Verification code: | | domicilioMexico_1-default +ADDRESS_HOME_COUNTRY | paisExpedicion | Country of issue | 0 | paisExpedicion_2-default +UNKNOWN_TYPE | fechaExpedicion | Date of issue | | paisExpedicion_2-default +UNKNOWN_TYPE | confirmarFechaExpedicion | Date of issue (Confirmation) | | paisExpedicion_2-default +UNKNOWN_TYPE | fechaExpiracion | Expiration date | | paisExpedicion_2-default +UNKNOWN_TYPE | confirmarFechaExpiracion | Expiration date (Confirmation) | | paisExpedicion_2-default +ADDRESS_HOME_COUNTRY | paisResidencia | Country of residence | 0 | paisResidencia_3-default +ADDRESS_HOME_LINE1 | direccionResidencia | Address of residence | | paisResidencia_3-default +UNKNOWN_TYPE | motivoViaje | Reason of trip | 0 | paisResidencia_3-default +UNKNOWN_TYPE | especifiqueMotivo | Specify | 0 | paisResidencia_3-default +ADDRESS_HOME_STATE | estadoDestino | State | 0 | paisResidencia_3-default +ADDRESS_HOME_LINE1 | domicilioMexico | Address in Mexico | | domicilioMexico_4-default +NAME_FIRST | nombreTutor | Name(s) | | domicilioMexico_4-default +NAME_LAST | apellidosTutor | Surname(s) | | domicilioMexico_4-default +UNKNOWN_TYPE | sexoTutor | Gender | 0 | domicilioMexico_4-default +UNKNOWN_TYPE | fechaNacimientoTutor | Date of birth | | domicilioMexico_4-default +ADDRESS_HOME_COUNTRY | nacionalidadTutor | Nationality (Country) | 0 | domicilioMexico_4-default +ADDRESS_HOME_COUNTRY | paisNacimientoTutor | Country of birth | 0 | domicilioMexico_4-default +EMAIL_ADDRESS | correoElectronico | Email | | domicilioMexico_4-default +EMAIL_ADDRESS | confirmacionCorreoElectronico | Email (Confirmation) | | domicilioMexico_4-default +UNKNOWN_TYPE | captcha | Verification code: | | domicilioMexico_4-default UNKNOWN_TYPE | idioma | Idioma: | es | idioma_1-default UNKNOWN_TYPE | noConsecutivoInterno | Consecutivo: | | idioma_1-default UNKNOWN_TYPE | numero_pasaporte | Número de pasaporte: | | idioma_1-default
diff --git a/components/test/data/autofill/heuristics/output/154_fmm-es_inm.gob.mx.out b/components/test/data/autofill/heuristics/output/154_fmm-es_inm.gob.mx.out index 1d18dd8..4bf2b9be 100644 --- a/components/test/data/autofill/heuristics/output/154_fmm-es_inm.gob.mx.out +++ b/components/test/data/autofill/heuristics/output/154_fmm-es_inm.gob.mx.out
@@ -13,26 +13,26 @@ UNKNOWN_TYPE | tipoDocumento | Tipo de documento | 0 | internacion_1-default UNKNOWN_TYPE | numeroDocumento | Número de documento | | internacion_1-default UNKNOWN_TYPE | confirmarNumeroDocumento | Número de documento (Confirmación) | | internacion_1-default -ADDRESS_HOME_COUNTRY | paisExpedicion | País de expedición | 0 | paisExpedicion_1-default -UNKNOWN_TYPE | fechaExpedicion | Fecha de expedición | | paisExpedicion_1-default -UNKNOWN_TYPE | confirmarFechaExpedicion | Fecha de expedición (Confirmación) | | paisExpedicion_1-default -UNKNOWN_TYPE | fechaExpiracion | Fecha de expiración | | paisExpedicion_1-default -UNKNOWN_TYPE | confirmarFechaExpiracion | Fecha de expiración (Confirmación) | | paisExpedicion_1-default -ADDRESS_HOME_COUNTRY | paisResidencia | País de residencia | 0 | paisResidencia_1-default -ADDRESS_HOME_LINE1 | direccionResidencia | Dirección de residencia | | paisResidencia_1-default -UNKNOWN_TYPE | motivoViaje | Motivo de viaje | 0 | paisResidencia_1-default -UNKNOWN_TYPE | especifiqueMotivo | Especifique motivo | 0 | paisResidencia_1-default -ADDRESS_HOME_STATE | estadoDestino | Estado | 0 | paisResidencia_1-default -UNKNOWN_TYPE | domicilioMexico | Domicilio en México | | paisResidencia_1-default -NAME_FIRST | nombreTutor | Nombre(s) | | paisResidencia_1-default -NAME_LAST | apellidosTutor | Apellido(s) | | paisResidencia_1-default -UNKNOWN_TYPE | sexoTutor | Sexo | 0 | paisResidencia_1-default -UNKNOWN_TYPE | fechaNacimientoTutor | Fecha de nacimiento | | paisResidencia_1-default -ADDRESS_HOME_COUNTRY | nacionalidadTutor | Nacionalidad (País) | 0 | nacionalidadTutor_1-default -ADDRESS_HOME_COUNTRY | paisNacimientoTutor | País de nacimiento | 0 | nacionalidadTutor_1-default -EMAIL_ADDRESS | correoElectronico | Correo electrónico | | paisResidencia_1-default -EMAIL_ADDRESS | confirmacionCorreoElectronico | Correo electrónico (Confirmación) | | paisResidencia_1-default -UNKNOWN_TYPE | captcha | Código de verificación: | | paisResidencia_1-default +ADDRESS_HOME_COUNTRY | paisExpedicion | País de expedición | 0 | paisExpedicion_2-default +UNKNOWN_TYPE | fechaExpedicion | Fecha de expedición | | paisExpedicion_2-default +UNKNOWN_TYPE | confirmarFechaExpedicion | Fecha de expedición (Confirmación) | | paisExpedicion_2-default +UNKNOWN_TYPE | fechaExpiracion | Fecha de expiración | | paisExpedicion_2-default +UNKNOWN_TYPE | confirmarFechaExpiracion | Fecha de expiración (Confirmación) | | paisExpedicion_2-default +ADDRESS_HOME_COUNTRY | paisResidencia | País de residencia | 0 | paisResidencia_3-default +ADDRESS_HOME_LINE1 | direccionResidencia | Dirección de residencia | | paisResidencia_3-default +UNKNOWN_TYPE | motivoViaje | Motivo de viaje | 0 | paisResidencia_3-default +UNKNOWN_TYPE | especifiqueMotivo | Especifique motivo | 0 | paisResidencia_3-default +ADDRESS_HOME_STATE | estadoDestino | Estado | 0 | paisResidencia_3-default +UNKNOWN_TYPE | domicilioMexico | Domicilio en México | | paisResidencia_3-default +NAME_FIRST | nombreTutor | Nombre(s) | | paisResidencia_3-default +NAME_LAST | apellidosTutor | Apellido(s) | | paisResidencia_3-default +UNKNOWN_TYPE | sexoTutor | Sexo | 0 | paisResidencia_3-default +UNKNOWN_TYPE | fechaNacimientoTutor | Fecha de nacimiento | | paisResidencia_3-default +ADDRESS_HOME_COUNTRY | nacionalidadTutor | Nacionalidad (País) | 0 | nacionalidadTutor_4-default +ADDRESS_HOME_COUNTRY | paisNacimientoTutor | País de nacimiento | 0 | nacionalidadTutor_4-default +EMAIL_ADDRESS | correoElectronico | Correo electrónico | | paisResidencia_3-default +EMAIL_ADDRESS | confirmacionCorreoElectronico | Correo electrónico (Confirmación) | | paisResidencia_3-default +UNKNOWN_TYPE | captcha | Código de verificación: | | paisResidencia_3-default UNKNOWN_TYPE | idioma | Idioma: | es | idioma_1-default UNKNOWN_TYPE | noConsecutivoInterno | Consecutivo: | | idioma_1-default UNKNOWN_TYPE | numero_pasaporte | Número de pasaporte: | | idioma_1-default
diff --git a/components/test/data/autofill/heuristics/output/155_fmm-ja_inm.gob.mx.out b/components/test/data/autofill/heuristics/output/155_fmm-ja_inm.gob.mx.out index 2f7c19e9..3c9fa29 100644 --- a/components/test/data/autofill/heuristics/output/155_fmm-ja_inm.gob.mx.out +++ b/components/test/data/autofill/heuristics/output/155_fmm-ja_inm.gob.mx.out
@@ -13,26 +13,26 @@ UNKNOWN_TYPE | tipoDocumento | 書類の種類 | 0 | internacion_1-default UNKNOWN_TYPE | numeroDocumento | 書類番号 | | internacion_1-default UNKNOWN_TYPE | confirmarNumeroDocumento | 書類番号(再入力) | | internacion_1-default -ADDRESS_HOME_COUNTRY | paisExpedicion | 書類の発行国 | 0 | paisExpedicion_1-default -UNKNOWN_TYPE | fechaExpedicion | 発行日 | | paisExpedicion_1-default -UNKNOWN_TYPE | confirmarFechaExpedicion | 発行日(再入力) | | paisExpedicion_1-default -UNKNOWN_TYPE | fechaExpiracion | 有効期限日 | | paisExpedicion_1-default -UNKNOWN_TYPE | confirmarFechaExpiracion | 有効期限日(再入力) | | paisExpedicion_1-default -ADDRESS_HOME_COUNTRY | paisResidencia | 居住国 | 0 | paisResidencia_1-default -ADDRESS_HOME_LINE1 | direccionResidencia | 現住所 | | paisResidencia_1-default -UNKNOWN_TYPE | motivoViaje | 旅行目的 | 0 | paisResidencia_1-default -UNKNOWN_TYPE | especifiqueMotivo | 具体的な目的 | 0 | paisResidencia_1-default -ADDRESS_HOME_STATE | estadoDestino | 州名 | 0 | paisResidencia_1-default -ADDRESS_HOME_LINE1 | domicilioMexico | メキシコ国内の住所 | | domicilioMexico_1-default -NAME_FIRST | nombreTutor | 名 | | domicilioMexico_1-default -NAME_LAST | apellidosTutor | 姓 | | domicilioMexico_1-default -UNKNOWN_TYPE | sexoTutor | 性別 | 0 | domicilioMexico_1-default -UNKNOWN_TYPE | fechaNacimientoTutor | 生年月日 | | domicilioMexico_1-default -ADDRESS_HOME_COUNTRY | nacionalidadTutor | 国籍(国名) | 0 | domicilioMexico_1-default -ADDRESS_HOME_COUNTRY | paisNacimientoTutor | 出生国 | 0 | domicilioMexico_1-default -EMAIL_ADDRESS | correoElectronico | メールアドレス | | domicilioMexico_1-default -EMAIL_ADDRESS | confirmacionCorreoElectronico | メールアドレス(再入力) | | domicilioMexico_1-default -UNKNOWN_TYPE | captcha | 認証コード | | domicilioMexico_1-default +ADDRESS_HOME_COUNTRY | paisExpedicion | 書類の発行国 | 0 | paisExpedicion_2-default +UNKNOWN_TYPE | fechaExpedicion | 発行日 | | paisExpedicion_2-default +UNKNOWN_TYPE | confirmarFechaExpedicion | 発行日(再入力) | | paisExpedicion_2-default +UNKNOWN_TYPE | fechaExpiracion | 有効期限日 | | paisExpedicion_2-default +UNKNOWN_TYPE | confirmarFechaExpiracion | 有効期限日(再入力) | | paisExpedicion_2-default +ADDRESS_HOME_COUNTRY | paisResidencia | 居住国 | 0 | paisResidencia_3-default +ADDRESS_HOME_LINE1 | direccionResidencia | 現住所 | | paisResidencia_3-default +UNKNOWN_TYPE | motivoViaje | 旅行目的 | 0 | paisResidencia_3-default +UNKNOWN_TYPE | especifiqueMotivo | 具体的な目的 | 0 | paisResidencia_3-default +ADDRESS_HOME_STATE | estadoDestino | 州名 | 0 | paisResidencia_3-default +ADDRESS_HOME_LINE1 | domicilioMexico | メキシコ国内の住所 | | domicilioMexico_4-default +NAME_FIRST | nombreTutor | 名 | | domicilioMexico_4-default +NAME_LAST | apellidosTutor | 姓 | | domicilioMexico_4-default +UNKNOWN_TYPE | sexoTutor | 性別 | 0 | domicilioMexico_4-default +UNKNOWN_TYPE | fechaNacimientoTutor | 生年月日 | | domicilioMexico_4-default +ADDRESS_HOME_COUNTRY | nacionalidadTutor | 国籍(国名) | 0 | domicilioMexico_4-default +ADDRESS_HOME_COUNTRY | paisNacimientoTutor | 出生国 | 0 | domicilioMexico_4-default +EMAIL_ADDRESS | correoElectronico | メールアドレス | | domicilioMexico_4-default +EMAIL_ADDRESS | confirmacionCorreoElectronico | メールアドレス(再入力) | | domicilioMexico_4-default +UNKNOWN_TYPE | captcha | 認証コード | | domicilioMexico_4-default UNKNOWN_TYPE | idioma | Idioma: | es | idioma_1-default UNKNOWN_TYPE | noConsecutivoInterno | Consecutivo: | | idioma_1-default UNKNOWN_TYPE | numero_pasaporte | Número de pasaporte: | | idioma_1-default
diff --git a/components/test/data/autofill_assistant/html/autofill_assistant_target_website.html b/components/test/data/autofill_assistant/html/autofill_assistant_target_website.html index d37a2fd9..a4bdc9b6 100644 --- a/components/test/data/autofill_assistant/html/autofill_assistant_target_website.html +++ b/components/test/data/autofill_assistant/html/autofill_assistant_target_website.html
@@ -215,6 +215,10 @@ <br> </div> + <div id="emptydiv" style="width: 100%; height: 0px; padding: 0px; margin: 0px;"> + This text is hidden, but might be revealed if the div's height is increased. + </div> + <div> <select id="select"> <option value="one">One</option> @@ -387,5 +391,9 @@ </ul> <strong class="nth_match_child"></strong> </div> + + <div class="label">Label 1</div> + <div class="label">Label 2</div> + <div class="label">Label 3</div> </body> </html>
diff --git a/components/user_manager/fake_user_manager.cc b/components/user_manager/fake_user_manager.cc index ccb28f6..64177bc8 100644 --- a/components/user_manager/fake_user_manager.cc +++ b/components/user_manager/fake_user_manager.cc
@@ -259,7 +259,8 @@ } bool FakeUserManager::IsLoggedInAsPublicAccount() const { - return false; + const User* active_user = GetActiveUser(); + return active_user && active_user->GetType() == USER_TYPE_PUBLIC_ACCOUNT; } bool FakeUserManager::IsLoggedInAsGuest() const {
diff --git a/content/browser/OWNERS b/content/browser/OWNERS index e2241f21..2ffd7c49 100644 --- a/content/browser/OWNERS +++ b/content/browser/OWNERS
@@ -55,3 +55,7 @@ # Cross origin opener policy. per-file cross_origin_opener_policy*=ahemery@chromium.org per-file cross_origin_opener_policy*=pmeuleman@chromium.org + +# Network Service. +per-file network_service_*=file://services/network/OWNERS +per-file network_context_*=file://services/network/OWNERS
diff --git a/content/browser/accessibility/accessibility_tree_formatter_android.cc b/content/browser/accessibility/accessibility_tree_formatter_android.cc index 0e2c99a..366d019 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_android.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_android.cc
@@ -96,12 +96,6 @@ std::vector<AXPropertyFilter>* property_filters) override; private: - const std::string GetAllowEmptyString() override; - const std::string GetAllowString() override; - const std::string GetDenyString() override; - const std::string GetDenyNodeString() override; - const std::string GetRunUntilEventString() override; - void RecursiveBuildAccessibilityTree(const BrowserAccessibility& node, base::DictionaryValue* dict) const; @@ -309,24 +303,4 @@ return line; } -const std::string AccessibilityTreeFormatterAndroid::GetAllowEmptyString() { - return "@ANDROID-ALLOW-EMPTY:"; -} - -const std::string AccessibilityTreeFormatterAndroid::GetAllowString() { - return "@ANDROID-ALLOW:"; -} - -const std::string AccessibilityTreeFormatterAndroid::GetDenyString() { - return "@ANDROID-DENY:"; -} - -const std::string AccessibilityTreeFormatterAndroid::GetDenyNodeString() { - return "@ANDROID-DENY-NODE:"; -} - -const std::string AccessibilityTreeFormatterAndroid::GetRunUntilEventString() { - return "@ANDROID-RUN-UNTIL-EVENT:"; -} - } // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc b/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc index 77d25e4..d18dd5a2 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
@@ -38,12 +38,6 @@ ~AccessibilityTreeFormatterAuraLinux() override; private: - const std::string GetAllowEmptyString() override; - const std::string GetAllowString() override; - const std::string GetDenyString() override; - const std::string GetDenyNodeString() override; - const std::string GetRunUntilEventString() override; - std::string ProcessTreeForOutput( const base::DictionaryValue& node, base::DictionaryValue* filtered_dict_result = nullptr) override; @@ -737,25 +731,4 @@ return line; } -const std::string AccessibilityTreeFormatterAuraLinux::GetAllowEmptyString() { - return "@AURALINUX-ALLOW-EMPTY:"; -} - -const std::string AccessibilityTreeFormatterAuraLinux::GetAllowString() { - return "@AURALINUX-ALLOW:"; -} - -const std::string AccessibilityTreeFormatterAuraLinux::GetDenyString() { - return "@AURALINUX-DENY:"; -} - -const std::string AccessibilityTreeFormatterAuraLinux::GetDenyNodeString() { - return "@AURALINUX-DENY-NODE:"; -} - -const std::string -AccessibilityTreeFormatterAuraLinux::GetRunUntilEventString() { - return "@AURALINUX-RUN-UNTIL-EVENT:"; -} - } // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/content/browser/accessibility/accessibility_tree_formatter_blink.cc index d8cf4b1..183bf17 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_blink.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -604,24 +604,4 @@ return line; } -const std::string AccessibilityTreeFormatterBlink::GetAllowEmptyString() { - return "@BLINK-ALLOW-EMPTY:"; -} - -const std::string AccessibilityTreeFormatterBlink::GetAllowString() { - return "@BLINK-ALLOW:"; -} - -const std::string AccessibilityTreeFormatterBlink::GetDenyString() { - return "@BLINK-DENY:"; -} - -const std::string AccessibilityTreeFormatterBlink::GetDenyNodeString() { - return "@BLINK-DENY-NODE:"; -} - -const std::string AccessibilityTreeFormatterBlink::GetRunUntilEventString() { - return "@BLINK-RUN-UNTIL-EVENT:"; -} - } // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter_blink.h b/content/browser/accessibility/accessibility_tree_formatter_blink.h index 30ec804d..3280d8b 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_blink.h +++ b/content/browser/accessibility/accessibility_tree_formatter_blink.h
@@ -34,12 +34,6 @@ static std::unique_ptr<ui::AXTreeFormatter> CreateBlink(); private: - const std::string GetAllowEmptyString() override; - const std::string GetAllowString() override; - const std::string GetDenyString() override; - const std::string GetDenyNodeString() override; - const std::string GetRunUntilEventString() override; - void RecursiveBuildAccessibilityTree(const BrowserAccessibility& node, base::DictionaryValue* dict) const;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac.mm b/content/browser/accessibility/accessibility_tree_formatter_mac.mm index 4cb9e840..ea03a4e 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_mac.mm +++ b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -77,12 +77,6 @@ const LineIndexer* line_indexer, base::DictionaryValue* dict) const; - const std::string GetAllowEmptyString() override; - const std::string GetAllowString() override; - const std::string GetDenyString() override; - const std::string GetDenyNodeString() override; - const std::string GetRunUntilEventString() override; - void AddProperties(const id node, const LineIndexer* line_indexer, base::Value* dict) const; @@ -586,26 +580,6 @@ return ""; } -const string AccessibilityTreeFormatterMac::GetAllowEmptyString() { - return "@MAC-ALLOW-EMPTY:"; -} - -const string AccessibilityTreeFormatterMac::GetAllowString() { - return "@MAC-ALLOW:"; -} - -const string AccessibilityTreeFormatterMac::GetDenyString() { - return "@MAC-DENY:"; -} - -const string AccessibilityTreeFormatterMac::GetDenyNodeString() { - return "@MAC-DENY-NODE:"; -} - -const std::string AccessibilityTreeFormatterMac::GetRunUntilEventString() { - return "@MAC-RUN-UNTIL-EVENT:"; -} - } // namespace content #pragma clang diagnostic pop
diff --git a/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc b/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc index d6434d2..d7086b9 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc
@@ -1151,24 +1151,4 @@ } } -const std::string AccessibilityTreeFormatterUia::GetAllowEmptyString() { - return "@UIA-WIN-ALLOW-EMPTY:"; -} - -const std::string AccessibilityTreeFormatterUia::GetAllowString() { - return "@UIA-WIN-ALLOW:"; -} - -const std::string AccessibilityTreeFormatterUia::GetDenyString() { - return "@UIA-WIN-DENY:"; -} - -const std::string AccessibilityTreeFormatterUia::GetDenyNodeString() { - return "@UIA-WIN-DENY-NODE:"; -} - -const std::string AccessibilityTreeFormatterUia::GetRunUntilEventString() { - return "@UIA-WIN-RUN-UNTIL-EVENT:"; -} - } // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter_uia_win.h b/content/browser/accessibility/accessibility_tree_formatter_uia_win.h index 8c3bb6f..7f966882 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_uia_win.h +++ b/content/browser/accessibility/accessibility_tree_formatter_uia_win.h
@@ -92,11 +92,6 @@ IUIAutomationElementArray* array, base::DictionaryValue* dict); base::string16 GetNodeName(IUIAutomationElement* node); - const std::string GetAllowEmptyString() override; - const std::string GetAllowString() override; - const std::string GetDenyString() override; - const std::string GetDenyNodeString() override; - const std::string GetRunUntilEventString() override; std::string ProcessTreeForOutput( const base::DictionaryValue& node, base::DictionaryValue* filtered_result = nullptr) override;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_win.cc b/content/browser/accessibility/accessibility_tree_formatter_win.cc index eda6519..5d40201c 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_win.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_win.cc
@@ -64,11 +64,6 @@ LONG root_x, LONG root_y); - const std::string GetAllowEmptyString() override; - const std::string GetAllowString() override; - const std::string GetDenyString() override; - const std::string GetDenyNodeString() override; - const std::string GetRunUntilEventString() override; void AddProperties(const Microsoft::WRL::ComPtr<IAccessible>, base::DictionaryValue* dict, LONG root_x, @@ -1004,24 +999,4 @@ return line; } -const std::string AccessibilityTreeFormatterWin::GetAllowEmptyString() { - return "@WIN-ALLOW-EMPTY:"; -} - -const std::string AccessibilityTreeFormatterWin::GetAllowString() { - return "@WIN-ALLOW:"; -} - -const std::string AccessibilityTreeFormatterWin::GetDenyString() { - return "@WIN-DENY:"; -} - -const std::string AccessibilityTreeFormatterWin::GetDenyNodeString() { - return "@WIN-DENY-NODE:"; -} - -const std::string AccessibilityTreeFormatterWin::GetRunUntilEventString() { - return "@WIN-RUN-UNTIL-EVENT:"; -} - } // namespace content
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/content/browser/accessibility/dump_accessibility_browsertest_base.cc index c70f00c5..1346e17 100644 --- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc +++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -77,6 +77,7 @@ } // namespace +using Directive = DumpAccessibilityTestHelper::Directive; using ui::AXPropertyFilter; using ui::AXTreeFormatter; @@ -159,6 +160,7 @@ } void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives( + const DumpAccessibilityTestHelper& test_helper, const std::string& test_html, std::vector<std::string>* no_load_expected, std::vector<std::string>* wait_for, @@ -167,48 +169,30 @@ std::vector<std::string>* default_action_on) { for (const std::string& line : base::SplitString( test_html, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { - const std::string& allow_empty_str = formatter_->GetAllowEmptyString(); - const std::string& allow_str = formatter_->GetAllowString(); - const std::string& deny_str = formatter_->GetDenyString(); - const std::string& deny_node_str = formatter_->GetDenyNodeString(); - const std::string& no_load_expected_str = "@NO-LOAD-EXPECTED:"; - const std::string& wait_str = "@WAIT-FOR:"; - const std::string& execute_str = "@EXECUTE-AND-WAIT-FOR:"; - const std::string& until_str = formatter_->GetRunUntilEventString(); - const std::string& default_action_on_str = "@DEFAULT-ACTION-ON:"; - if (base::StartsWith(line, allow_empty_str, base::CompareCase::SENSITIVE)) { - property_filters_.emplace_back(line.substr(allow_empty_str.size()), - AXPropertyFilter::ALLOW_EMPTY); - } else if (base::StartsWith(line, allow_str, - base::CompareCase::SENSITIVE)) { - property_filters_.emplace_back(line.substr(allow_str.size()), - AXPropertyFilter::ALLOW); - } else if (base::StartsWith(line, deny_str, base::CompareCase::SENSITIVE)) { - property_filters_.emplace_back(line.substr(deny_str.size()), - AXPropertyFilter::DENY); - } else if (base::StartsWith(line, deny_node_str, - base::CompareCase::SENSITIVE)) { - const auto& node_filter = line.substr(deny_node_str.size()); - const auto& parts = base::SplitString( - node_filter, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - // Silently skip over parsing errors like the rest of the enclosing code. - if (parts.size() == 2) { - node_filters_.emplace_back(parts[0], parts[1]); - } - } else if (base::StartsWith(line, no_load_expected_str, - base::CompareCase::SENSITIVE)) { - no_load_expected->push_back(line.substr(no_load_expected_str.size())); - } else if (base::StartsWith(line, wait_str, base::CompareCase::SENSITIVE)) { - wait_for->push_back(line.substr(wait_str.size())); - } else if (base::StartsWith(line, execute_str, - base::CompareCase::SENSITIVE)) { - execute->push_back(line.substr(execute_str.size())); - } else if (base::StartsWith(line, until_str, - base::CompareCase::SENSITIVE)) { - run_until->push_back(line.substr(until_str.size())); - } else if (base::StartsWith(line, default_action_on_str, - base::CompareCase::SENSITIVE)) { - default_action_on->push_back(line.substr(default_action_on_str.size())); + if (test_helper.ParsePropertyFilter(line, &property_filters_) || + test_helper.ParseNodeFilter(line, &node_filters_)) { + continue; + } + + Directive directive = test_helper.ParseDirective(line); + switch (directive.type) { + case Directive::kNoLoadExpected: + no_load_expected->push_back(directive.value); + break; + case Directive::kWaitFor: + wait_for->push_back(directive.value); + break; + case Directive::kExecuteAndWaitFor: + execute->push_back(directive.value); + break; + case Directive::kRunUntil: + run_until->push_back(directive.value); + break; + case Directive::kDefaultActionOn: + default_action_on->push_back(directive.value); + break; + default: // Directive::kNone + break; } } } @@ -298,8 +282,9 @@ node_filters_.clear(); formatter_->AddDefaultFilters(&property_filters_); AddDefaultFilters(&property_filters_); - ParseHtmlForExtraDirectives(html_contents, &no_load_expected, &wait_for, - &execute, &run_until, &default_action_on); + ParseHtmlForExtraDirectives(test_helper, html_contents, &no_load_expected, + &wait_for, &execute, &run_until, + &default_action_on); // Get the test URL. GURL url(embedded_test_server()->GetURL("/" + std::string(file_dir) + "/" +
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.h b/content/browser/accessibility/dump_accessibility_browsertest_base.h index 4e089bf..32af53c 100644 --- a/content/browser/accessibility/dump_accessibility_browsertest_base.h +++ b/content/browser/accessibility/dump_accessibility_browsertest_base.h
@@ -19,6 +19,7 @@ namespace content { class BrowserAccessibility; +class DumpAccessibilityTestHelper; // Base class for an accessibility browsertest that takes an HTML file as // input, loads it into a tab, dumps some accessibility data in text format, @@ -95,12 +96,14 @@ // indicating that the test is done, and this framework will wait for that // string to appear before comparing the results. There can be multiple // @WAIT-FOR: directives. - void ParseHtmlForExtraDirectives(const std::string& test_html, - std::vector<std::string>* no_load_expected, - std::vector<std::string>* wait_for, - std::vector<std::string>* execute, - std::vector<std::string>* run_until, - std::vector<std::string>* default_action_on); + void ParseHtmlForExtraDirectives( + const DumpAccessibilityTestHelper& test_helper, + const std::string& test_html, + std::vector<std::string>* no_load_expected, + std::vector<std::string>* wait_for, + std::vector<std::string>* execute, + std::vector<std::string>* run_until, + std::vector<std::string>* default_action_on); void RunTestForPlatform(const base::FilePath file_path, const char* file_dir);
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index 2c81fb0..a0b64890 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -3859,6 +3859,59 @@ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); delete_observer_rfh_a.WaitUntilDeleted(); } +class BackForwardCacheBrowserTestWithUnfreezableLoading + : public BackForwardCacheBrowserTest { + public: + BackForwardCacheBrowserTestWithUnfreezableLoading() = default; + ~BackForwardCacheBrowserTestWithUnfreezableLoading() override = default; + + protected: + void SetUpCommandLine(base::CommandLine* command_line) override { + EnableFeatureAndSetParams(blink::features::kLoadingTasksUnfreezable, "", + ""); + BackForwardCacheBrowserTest::SetUpCommandLine(command_line); + } +}; + +// When loading task is unfreezable with the feature flag +// kLoadingTaskUnfreezable, a page will keep processing the in-flight network +// requests while the page is frozen in BackForwardCache. +IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestWithUnfreezableLoading, + FetchWhileStoring) { + net::test_server::ControllableHttpResponse fetch_response( + embedded_test_server(), "/fetch"); + ASSERT_TRUE(embedded_test_server()->Start()); + + GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html")); + GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html")); + + // 1) Navigate to A. + EXPECT_TRUE(NavigateToURL(shell(), url_a)); + RenderFrameHostImpl* rfh_a = current_frame_host(); + RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a); + + // Use "fetch" immediately before being frozen. + EXPECT_TRUE(ExecJs(rfh_a, R"( + document.addEventListener('freeze', event => { + my_fetch = fetch('/fetch', { keepalive: true}); + }); + )")); + + // 2) Navigate to B. + EXPECT_TRUE(NavigateToURL(shell(), url_b)); + + fetch_response.WaitForRequest(); + fetch_response.Send(net::HTTP_OK, "text/html", "TheResponse"); + fetch_response.Done(); + EXPECT_TRUE(rfh_a->IsInBackForwardCache()); + EXPECT_FALSE(delete_observer_rfh_a.deleted()); + + // 3) Go back to A. + web_contents()->GetController().GoBack(); + EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + ExpectOutcome(BackForwardCacheMetrics::HistoryNavigationOutcome::kRestored, + FROM_HERE); +} // Disabled on Android, since we have problems starting up the websocket test // server in the host
diff --git a/content/browser/network_service_browsertest.cc b/content/browser/network_service_browsertest.cc index 5c138eb..f855b256 100644 --- a/content/browser/network_service_browsertest.cc +++ b/content/browser/network_service_browsertest.cc
@@ -461,11 +461,7 @@ EXPECT_EQ(GetPreloadedFirstPartySetCountFromNetworkService(), 2); - mojo::Remote<network::mojom::NetworkServiceTest> network_service_test; - GetNetworkService()->BindTestInterface( - network_service_test.BindNewPipeAndPassReceiver()); - network_service_test->SimulateCrash(); - network_service_test.FlushForTesting(); + SimulateNetworkServiceCrash(); EXPECT_EQ(GetPreloadedFirstPartySetCountFromNetworkService(), 2); }
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index de99bb4..20caf620 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -3885,21 +3885,6 @@ feature, GetLastCommittedOrigin()); } -bool RenderFrameHostImpl::IsFeatureEnabled( - blink::mojom::DocumentPolicyFeature feature) { - blink::mojom::PolicyValueType feature_type = - blink::GetDocumentPolicyFeatureInfoMap().at(feature).default_value.Type(); - return IsFeatureEnabled( - feature, blink::PolicyValue::CreateMaxPolicyValue(feature_type)); -} - -bool RenderFrameHostImpl::IsFeatureEnabled( - blink::mojom::DocumentPolicyFeature feature, - blink::PolicyValue threshold_value) { - return document_policy_ && - document_policy_->IsFeatureEnabled(feature, threshold_value); -} - void RenderFrameHostImpl::ViewSource() { delegate_->ViewSource(this); } @@ -7047,16 +7032,6 @@ GetAssociatedLocalFrame()->ClearFocusedElement(); } -void RenderFrameHostImpl::BlockRequestsForFrame() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - ForEachFrame(this, - base::BindRepeating([](RenderFrameHostImpl* render_frame_host) { - if (render_frame_host->frame_) - render_frame_host->frame_->BlockRequests(); - })); -} - void RenderFrameHostImpl::ResumeBlockedRequestsForFrame() { ForEachFrame(this, base::BindRepeating([](RenderFrameHostImpl* render_frame_host) { @@ -7065,15 +7040,6 @@ })); } -void RenderFrameHostImpl::CancelBlockedRequestsForFrame() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - ForEachFrame(this, - base::BindRepeating([](RenderFrameHostImpl* render_frame_host) { - if (render_frame_host->frame_) - render_frame_host->frame_->CancelBlockedRequests(); - })); -} - void RenderFrameHostImpl::BindDevToolsAgent( mojo::PendingAssociatedRemote<blink::mojom::DevToolsAgentHost> host, mojo::PendingAssociatedReceiver<blink::mojom::DevToolsAgent> receiver) { @@ -8205,29 +8171,6 @@ is_same_document, std::move(web_bundle_navigation_info)); } -bool RenderFrameHostImpl::NavigationRequestWasIntendedForPendingEntry( - NavigationRequest* request, - const FrameHostMsg_DidCommitProvisionalLoad_Params& params, - bool same_document) { - NavigationEntryImpl* pending_entry = NavigationEntryImpl::FromNavigationEntry( - frame_tree()->controller()->GetPendingEntry()); - if (!pending_entry) - return false; - if (request->nav_entry_id() != pending_entry->GetUniqueID()) - return false; - if (!same_document) { - // Make sure that the pending entry was really loaded via - // LoadDataWithBaseURL and that it matches this handle. - // TODO(csharrison): The pending entry's base url should equal - // |params.base_url|. This is not the case for loads with invalid base urls. - if (request->common_params().url != params.base_url || - pending_entry->GetBaseURLForDataURL().is_empty()) { - return false; - } - } - return true; -} - void RenderFrameHostImpl::BeforeUnloadTimeout() { if (render_view_host_->GetDelegate()->ShouldIgnoreUnresponsiveRenderer()) return; @@ -9355,12 +9298,6 @@ document->parent_->RemoveChild(document->frame_tree_node()); } -void RenderFrameHostImpl::AddUniqueMessageToConsole( - blink::mojom::ConsoleMessageLevel level, - const std::string& message) { - AddMessageToConsoleImpl(level, message, true /* discard_duplicates */); -} - void RenderFrameHostImpl::AddMessageToConsoleImpl( blink::mojom::ConsoleMessageLevel level, const std::string& message,
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index 06cc1159..f1fe8e3 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -357,9 +357,6 @@ bool GetSuddenTerminationDisablerState( blink::mojom::SuddenTerminationDisablerType disabler_type) override; bool IsFeatureEnabled(blink::mojom::FeaturePolicyFeature feature) override; - bool IsFeatureEnabled(blink::mojom::DocumentPolicyFeature feature) override; - bool IsFeatureEnabled(blink::mojom::DocumentPolicyFeature feature, - blink::PolicyValue threshold_value) override; void ViewSource() override; void ExecuteMediaPlayerActionAtLocation( const gfx::Point&, @@ -1036,22 +1033,10 @@ return has_focused_editable_element_; } - // Note: The methods for blocking / resuming / cancelling requests per - // RenderFrameHost are deprecated and will not work in the network service, - // please avoid using them. - // - // Causes all new requests for the root RenderFrameHost and its children to - // be blocked (not being started) until ResumeBlockedRequestsForFrame is - // called. - void BlockRequestsForFrame(); - // Resumes any blocked request for the specified root RenderFrameHost and // child frame hosts. void ResumeBlockedRequestsForFrame(); - // Cancels any blocked request for the frame and its subframes. - void CancelBlockedRequestsForFrame(); - // Binds a DevToolsAgent interface for debugging. void BindDevToolsAgent( mojo::PendingAssociatedRemote<blink::mojom::DevToolsAgentHost> host, @@ -1317,12 +1302,6 @@ // |this| or the parent frame or the opener frame. std::unique_ptr<WebBundleHandleTracker> MaybeCreateWebBundleHandleTracker(); - // Adds |message| to the DevTools console only if it is unique (i.e. has not - // been added to the console previously from this frame). - virtual void AddUniqueMessageToConsole( - blink::mojom::ConsoleMessageLevel level, - const std::string& message); - // Notify the scheduler that this frame used a feature which impacts the // scheduling policy (e.g. whether the frame can be frozen or put into the // back-forward cache). @@ -2307,18 +2286,6 @@ const FrameHostMsg_DidCommitProvisionalLoad_Params& params, bool is_same_document); - // Whether the |request| corresponds to a navigation to the pending - // NavigationEntry. This is used at commit time, when the NavigationRequest - // does not match the data sent by the renderer to re-create a - // NavigationRequest and associate it with the pending NavigationEntry if - // needed. - // TODO(clamy): We should handle the mismatches gracefully without deleting - // the NavigationRequest and having to re-create one. - bool NavigationRequestWasIntendedForPendingEntry( - NavigationRequest* request, - const FrameHostMsg_DidCommitProvisionalLoad_Params& params, - bool same_document); - // Helper to process the beforeunload completion callback. |proceed| indicates // whether the navigation or tab close should be allowed to proceed. If // |treat_as_final_completion_callback| is true, the frame should stop waiting
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc index 1db848d..3a4f60c 100644 --- a/content/browser/service_worker/service_worker_browsertest.cc +++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -18,7 +18,7 @@ #include "base/memory/ref_counted.h" #include "base/metrics/statistics_recorder.h" #include "base/run_loop.h" -#include "base/scoped_observer.h" +#include "base/scoped_observation.h" #include "base/stl_util.h" #include "base/strings/string16.h" #include "base/strings/string_number_conversions.h" @@ -470,9 +470,8 @@ // An observer that waits for the service worker to be running. class WorkerRunningStatusObserver : public ServiceWorkerContextObserver { public: - explicit WorkerRunningStatusObserver(ServiceWorkerContext* context) - : scoped_context_observer_(this) { - scoped_context_observer_.Add(context); + explicit WorkerRunningStatusObserver(ServiceWorkerContext* context) { + scoped_context_observation_.Observe(context); } ~WorkerRunningStatusObserver() override = default; @@ -495,8 +494,8 @@ private: base::RunLoop run_loop_; - ScopedObserver<ServiceWorkerContext, ServiceWorkerContextObserver> - scoped_context_observer_; + base::ScopedObservation<ServiceWorkerContext, ServiceWorkerContextObserver> + scoped_context_observation_{this}; int64_t version_id_ = blink::mojom::kInvalidServiceWorkerVersionId; DISALLOW_COPY_AND_ASSIGN(WorkerRunningStatusObserver);
diff --git a/content/browser/service_worker/service_worker_container_host.cc b/content/browser/service_worker/service_worker_container_host.cc index 0ad470b1..97acf57 100644 --- a/content/browser/service_worker/service_worker_container_host.cc +++ b/content/browser/service_worker/service_worker_container_host.cc
@@ -132,7 +132,7 @@ ServiceWorkerContainerHost::~ServiceWorkerContainerHost() { DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); - if (IsBackForwardCacheEnabled() && IsContainerForClient()) { + if (IsContainerForClient()) { auto* rfh = RenderFrameHostImpl::FromID(process_id(), frame_id()); if (rfh) rfh->RemoveServiceWorkerContainerHost(client_uuid()); @@ -446,8 +446,9 @@ void ServiceWorkerContainerHost::AddMatchingRegistration( ServiceWorkerRegistration* registration) { DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); - DCHECK(blink::ServiceWorkerScopeMatches(registration->scope(), url_)); - if (!IsContextSecureForServiceWorker()) + DCHECK(blink::ServiceWorkerScopeMatches(registration->scope(), + GetUrlForScopeMatch())); + if (!IsEligibleForServiceWorkerController()) return; size_t key = registration->scope().spec().size(); if (base::Contains(matching_registrations_, key)) @@ -778,12 +779,10 @@ std::move(coep_reporter_to_be_passed)); } - if (IsBackForwardCacheEnabled()) { - auto* rfh = RenderFrameHostImpl::FromID(container_process_id, frame_id()); - // |rfh| may be null in tests (but it should not happen in production). - if (rfh) - rfh->AddServiceWorkerContainerHost(client_uuid(), GetWeakPtr()); - } + auto* rfh = RenderFrameHostImpl::FromID(container_process_id, frame_id()); + // |rfh| may be null in tests (but it should not happen in production). + if (rfh) + rfh->AddServiceWorkerContainerHost(client_uuid(), GetWeakPtr()); DCHECK_EQ(ukm_source_id_, ukm::kInvalidSourceId); ukm_source_id_ = document_ukm_source_id; @@ -888,7 +887,7 @@ DCHECK(IsContainerForClient()); if (controller_registration) { - CHECK(IsContextSecureForServiceWorker()); + CHECK(IsEligibleForServiceWorkerController()); DCHECK(controller_registration->active_version()); #if DCHECK_IS_ON() DCHECK(IsMatchingRegistration(controller_registration.get())); @@ -968,13 +967,19 @@ return allowed; } -bool ServiceWorkerContainerHost::IsContextSecureForServiceWorker() const { +bool ServiceWorkerContainerHost::IsEligibleForServiceWorkerController() const { DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); DCHECK(IsContainerForClient()); if (!url_.is_valid()) return false; - if (!OriginCanAccessServiceWorkers(url_)) + // Pass GetUrlForScopeMatch() instead of `url_` because we cannot take the + // origin of `url_` when it's a blob URL (see https://crbug.com/1144717). It's + // guaranteed that the URL returned by GetURLForScopeMatch() has the same + // logical origin as `url_`. + // TODO(asamidoi): Add url::Origin member for ServiceWorkerContainerHost and + // use it as the argument of OriginCanAccessServiceWorkers(). + if (!OriginCanAccessServiceWorkers(GetUrlForScopeMatch())) return false; if (is_parent_frame_secure_) @@ -1126,7 +1131,8 @@ for (const auto& key_registration : registrations) { ServiceWorkerRegistration* registration = key_registration.second; if (!registration->is_uninstalled() && - blink::ServiceWorkerScopeMatches(registration->scope(), url_)) { + blink::ServiceWorkerScopeMatches(registration->scope(), + GetUrlForScopeMatch())) { AddMatchingRegistration(registration); } } @@ -1224,7 +1230,7 @@ ServiceWorkerVersion* version = controller_registration_ ? controller_registration_->active_version() : nullptr; - CHECK(!version || IsContextSecureForServiceWorker()); + CHECK(!version || IsEligibleForServiceWorkerController()); if (version == controller_.get()) return; @@ -1580,4 +1586,35 @@ return true; } +const GURL& ServiceWorkerContainerHost::GetUrlForScopeMatch() const { + DCHECK(IsContainerForClient()); + if (!scope_match_url_for_blob_client_.is_empty()) + return scope_match_url_for_blob_client_; + return url_; +} + +void ServiceWorkerContainerHost::InheritControllerFrom( + ServiceWorkerContainerHost& creator_host, + const GURL& blob_url) { + DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); + DCHECK(IsContainerForClient()); + DCHECK_EQ(blink::mojom::ServiceWorkerClientType::kDedicatedWorker, + GetClientType()); + DCHECK(blob_url.SchemeIsBlob()); + + UpdateUrls(blob_url, net::SiteForCookies::FromUrl(blob_url), + creator_host.top_frame_origin()); + + // Let `scope_match_url_for_blob_client_` be the creator's url for scope match + // because a client should be handled by the service worker of its creator. + scope_match_url_for_blob_client_ = creator_host.GetUrlForScopeMatch(); + + // Inherit the controller of the creator. + if (creator_host.controller_registration()) { + AddMatchingRegistration(creator_host.controller_registration()); + SetControllerRegistration(creator_host.controller_registration(), + false /* notify_controllerchange */); + } +} + } // namespace content
diff --git a/content/browser/service_worker/service_worker_container_host.h b/content/browser/service_worker/service_worker_container_host.h index 2f99755..c5f9a0a 100644 --- a/content/browser/service_worker/service_worker_container_host.h +++ b/content/browser/service_worker/service_worker_container_host.h
@@ -230,8 +230,8 @@ blink::mojom::ServiceWorkerObjectInfoPtr CreateServiceWorkerObjectInfoToSend( scoped_refptr<ServiceWorkerVersion> version); - // Returns a ServiceWorkerObjectHost instance for |version| for this provider - // host. A new instance is created if one does not already exist. + // Returns a ServiceWorkerObjectHost instance for |version| for this + // container host. A new instance is created if one does not already exist. // ServiceWorkerObjectHost will have an ownership of the |version|. base::WeakPtr<ServiceWorkerObjectHost> GetOrCreateServiceWorkerObjectHost( scoped_refptr<ServiceWorkerVersion> version); @@ -379,7 +379,7 @@ // If non-empty, |script_url| is the script the service worker will run. bool AllowServiceWorker(const GURL& scope, const GURL& script_url); - // Returns whether this provider host is secure enough to have a service + // Returns whether this container host is secure enough to have a service // worker controller. // Analogous to Blink's Document::IsSecureContext. Because of how service // worker intercepts main resource requests, this check must be done @@ -387,7 +387,7 @@ // ServiceWorkerNetworkProviderForFrame::Create). This function uses // |url_| and |is_parent_frame_secure_| to determine context security, so they // must be set properly before calling this function. - bool IsContextSecureForServiceWorker() const; + bool IsEligibleForServiceWorkerController() const; // For service worker clients. True if the response for the main resource load // was committed to the renderer. When this is false, the client's URL may @@ -448,6 +448,19 @@ void EnterBackForwardCacheForTesting() { is_in_back_forward_cache_ = true; } void LeaveBackForwardCacheForTesting() { is_in_back_forward_cache_ = false; } + // For service worker clients. Returns the URL that is used for scope matching + // algorithm. This can be different from url() in the case of blob URL + // workers. In that case, url() may be like "blob://https://a.test" and the + // scope matching URL is "https://a.test", inherited from the parent container + // host. + const GURL& GetUrlForScopeMatch() const; + + // For service worker clients that are dedicated workers. Inherits the + // controller of the creator document or worker. Used when the client was + // created with a blob URL. + void InheritControllerFrom(ServiceWorkerContainerHost& creator_host, + const GURL& blob_url); + base::WeakPtr<ServiceWorkerContainerHost> GetWeakPtr(); ukm::SourceId ukm_source_id() const { return ukm_source_id_; } @@ -623,7 +636,7 @@ std::map<size_t, scoped_refptr<ServiceWorkerRegistration>>; // Contains all living registrations whose scope this client's URL starts // with, used for .ready and claim(). It is empty if - // IsContextSecureForServiceWorker() is false. See also + // IsEligibleForServiceWorkerController() is false. See also // AddMatchingRegistration(). ServiceWorkerRegistrationMap matching_registrations_; @@ -657,6 +670,10 @@ // The source id of the client's ExecutionContext, set on response commit. ukm::SourceId ukm_source_id_ = ukm::kInvalidSourceId; + // The URL used for service worker scope matching. It is empty except in the + // case of a service worker client with a blob URL. + GURL scope_match_url_for_blob_client_; + // For window clients only --------------------------------------------------- // A token used internally to identify this context in requests. Corresponds
diff --git a/content/browser/service_worker/service_worker_container_host_unittest.cc b/content/browser/service_worker/service_worker_container_host_unittest.cc index 72de4e0..349acb8 100644 --- a/content/browser/service_worker/service_worker_container_host_unittest.cc +++ b/content/browser/service_worker/service_worker_container_host_unittest.cc
@@ -14,7 +14,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/run_loop.h" -#include "base/scoped_observer.h" +#include "base/scoped_observation.h" #include "base/test/scoped_feature_list.h" #include "base/threading/thread_task_runner_handle.h" #include "content/browser/renderer_host/frame_tree_node.h" @@ -401,20 +401,22 @@ container_host_secure_parent->UpdateUrls( GURL("http://host"), net::SiteForCookies::FromUrl(GURL("http://host")), url::Origin::Create(GURL("http://host"))); - EXPECT_FALSE(container_host_secure_parent->IsContextSecureForServiceWorker()); + EXPECT_FALSE( + container_host_secure_parent->IsEligibleForServiceWorkerController()); // Insecure parent frame. container_host_insecure_parent->UpdateUrls( GURL("https://host"), net::SiteForCookies::FromUrl(GURL("https://host")), url::Origin::Create(GURL("https://host"))); EXPECT_FALSE( - container_host_insecure_parent->IsContextSecureForServiceWorker()); + container_host_insecure_parent->IsEligibleForServiceWorkerController()); // Secure URL and parent frame. container_host_secure_parent->UpdateUrls( GURL("https://host"), net::SiteForCookies::FromUrl(GURL("https://host")), url::Origin::Create(GURL("https://host"))); - EXPECT_TRUE(container_host_secure_parent->IsContextSecureForServiceWorker()); + EXPECT_TRUE( + container_host_secure_parent->IsEligibleForServiceWorkerController()); // Exceptional service worker scheme. GURL url(std::string(kServiceWorkerScheme) + "://host"); @@ -424,13 +426,14 @@ EXPECT_TRUE(OriginCanAccessServiceWorkers(url)); container_host_secure_parent->UpdateUrls( url, net::SiteForCookies::FromUrl(url), origin); - EXPECT_TRUE(container_host_secure_parent->IsContextSecureForServiceWorker()); + EXPECT_TRUE( + container_host_secure_parent->IsEligibleForServiceWorkerController()); // Exceptional service worker scheme with insecure parent frame. container_host_insecure_parent->UpdateUrls( url, net::SiteForCookies::FromUrl(url), origin); EXPECT_FALSE( - container_host_insecure_parent->IsContextSecureForServiceWorker()); + container_host_insecure_parent->IsEligibleForServiceWorkerController()); } TEST_F(ServiceWorkerContainerHostTest, UpdateUrls_SameOriginRedirect) { @@ -1185,9 +1188,8 @@ : public ServiceWorkerContextCoreObserver { public: explicit TestServiceWorkerContextCoreObserver( - ServiceWorkerContextWrapper* wrapper) - : observer_(this) { - observer_.Add(wrapper); + ServiceWorkerContextWrapper* wrapper) { + observation_.Observe(wrapper); } void OnControlleeAdded(int64_t version_id, @@ -1219,8 +1221,9 @@ int on_controllee_removed_count_ = 0; int on_controllee_navigation_committed_count_ = 0; - ScopedObserver<ServiceWorkerContextWrapper, ServiceWorkerContextCoreObserver> - observer_; + base::ScopedObservation<ServiceWorkerContextWrapper, + ServiceWorkerContextCoreObserver> + observation_{this}; }; TEST_F(ServiceWorkerContainerHostTestWithBackForwardCache, ControlleeEvents) {
diff --git a/content/browser/service_worker/service_worker_context_unittest.cc b/content/browser/service_worker/service_worker_context_unittest.cc index 590d886..e0b9f1d4 100644 --- a/content/browser/service_worker/service_worker_context_unittest.cc +++ b/content/browser/service_worker/service_worker_context_unittest.cc
@@ -9,7 +9,7 @@ #include "base/bind.h" #include "base/files/scoped_temp_dir.h" #include "base/run_loop.h" -#include "base/scoped_observer.h" +#include "base/scoped_observation.h" #include "base/time/time.h" #include "content/browser/service_worker/embedded_worker_test_helper.h" #include "content/browser/service_worker/fake_embedded_worker_instance_client.h" @@ -283,9 +283,8 @@ base::Optional<bool> is_running; }; - explicit TestServiceWorkerContextObserver(ServiceWorkerContext* context) - : scoped_observer_(this) { - scoped_observer_.Add(context); + explicit TestServiceWorkerContextObserver(ServiceWorkerContext* context) { + scoped_observation_.Observe(context); } ~TestServiceWorkerContextObserver() override = default; @@ -374,7 +373,7 @@ } void OnDestruct(content::ServiceWorkerContext* context) override { - scoped_observer_.Remove(context); + scoped_observation_.RemoveObservation(); EventLog log; log.type = EventType::Destruct; @@ -384,8 +383,8 @@ const std::vector<EventLog>& events() { return events_; } private: - ScopedObserver<ServiceWorkerContext, ServiceWorkerContextObserver> - scoped_observer_; + base::ScopedObservation<ServiceWorkerContext, ServiceWorkerContextObserver> + scoped_observation_{this}; std::vector<EventLog> events_; DISALLOW_COPY_AND_ASSIGN(TestServiceWorkerContextObserver); };
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 a7fffbc..275f6ae 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler.cc +++ b/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -303,7 +303,7 @@ return; } - if (!container_host_->IsContextSecureForServiceWorker()) { + if (!container_host_->IsEligibleForServiceWorkerController()) { // TODO(falken): Figure out a way to surface in the page's DevTools // console that the service worker was blocked for security. TRACE_EVENT_WITH_FLOW1(
diff --git a/content/browser/service_worker/service_worker_main_resource_handle.h b/content/browser/service_worker/service_worker_main_resource_handle.h index fcd2d3f..d393068 100644 --- a/content/browser/service_worker/service_worker_main_resource_handle.h +++ b/content/browser/service_worker/service_worker_main_resource_handle.h
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "content/browser/service_worker/service_worker_accessed_callback.h" +#include "content/browser/service_worker/service_worker_main_resource_handle_core.h" #include "content/common/content_export.h" #include "services/metrics/public/cpp/ukm_source_id.h" #include "services/network/public/mojom/network_context.mojom.h" @@ -25,7 +26,6 @@ namespace content { class ServiceWorkerContextWrapper; -class ServiceWorkerMainResourceHandleCore; // This class is used to manage the lifetime of ServiceWorkerContainerHosts // created for main resource requests (navigations and web workers). This is a
diff --git a/content/browser/service_worker/service_worker_main_resource_handle_core.h b/content/browser/service_worker/service_worker_main_resource_handle_core.h index b0736715..fcbc9f64 100644 --- a/content/browser/service_worker/service_worker_main_resource_handle_core.h +++ b/content/browser/service_worker/service_worker_main_resource_handle_core.h
@@ -69,6 +69,16 @@ return container_host_; } + void set_parent_container_host( + base::WeakPtr<ServiceWorkerContainerHost> container_host) { + DCHECK(!parent_container_host_); + parent_container_host_ = std::move(container_host); + } + + base::WeakPtr<ServiceWorkerContainerHost> parent_container_host() { + return parent_container_host_; + } + void set_interceptor( std::unique_ptr<ServiceWorkerControlleeRequestHandler> interceptor) { interceptor_ = std::move(interceptor); @@ -90,6 +100,8 @@ scoped_refptr<ServiceWorkerContextWrapper> context_wrapper_; base::WeakPtr<ServiceWorkerMainResourceHandle> ui_handle_; base::WeakPtr<ServiceWorkerContainerHost> container_host_; + // Only used for workers with a blob URL. + base::WeakPtr<ServiceWorkerContainerHost> parent_container_host_; std::unique_ptr<ServiceWorkerControlleeRequestHandler> interceptor_; ServiceWorkerAccessedCallback service_worker_accessed_callback_;
diff --git a/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc b/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc index 938e4f8..ceccb2b 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc +++ b/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc
@@ -116,6 +116,7 @@ DCHECK(host_receiver); DCHECK(client_remote); base::WeakPtr<ServiceWorkerContainerHost> container_host; + bool inherit_container_host_only = false; if (request_destination == network::mojom::RequestDestination::kDocument || request_destination == network::mojom::RequestDestination::kIframe) { @@ -135,6 +136,18 @@ container_host = context_core->CreateContainerHostForWorker( std::move(host_receiver), process_id, std::move(client_remote), client_info); + + // For the blob worker case, inherit the controller from the worker's + // parent. See + // https://w3c.github.io/ServiceWorker/#control-and-use-worker-client + base::WeakPtr<ServiceWorkerContainerHost> parent_container_host = + handle_core->parent_container_host(); + if (parent_container_host && + tentative_resource_request.url.SchemeIsBlob()) { + container_host->InheritControllerFrom(*parent_container_host, + tentative_resource_request.url); + inherit_container_host_only = true; + } } DCHECK(container_host); handle_core->set_container_host(container_host); @@ -146,6 +159,19 @@ context_core->AsWeakPtr(), container_host, request_destination, skip_service_worker, handle_core->service_worker_accessed_callback())); + + // For the blob worker case, we only inherit the controller and do not + // let it intercept the requests. Blob URLs are not eligible to go through + // service worker interception. So just call the loader callback now. + // We don't use the interceptor but have to set it because we need + // ControllerServiceWorkerInfoPtr and ServiceWorkerObjectHost from the + // subresource loader params which is created by the interceptor. + if (inherit_container_host_only) { + LoaderCallbackWrapperOnCoreThread( + handle_core, std::move(interceptor_on_ui), std::move(loader_callback), + /*handler=*/{}); + return; + } } // If |initialize_container_host_only| is true, we have already determined @@ -193,7 +219,12 @@ // Returns true if a ServiceWorkerMainResourceLoaderInterceptor should be // created for a worker with this |url|. -bool ShouldCreateForWorker(const GURL& url) { +bool ShouldCreateForWorker( + const GURL& url, + base::WeakPtr<ServiceWorkerContainerHost> parent_container_host) { + // Blob URL can be controlled by a parent's controller. + if (url.SchemeIsBlob() && parent_container_host) + return true; // Create the handler even for insecure HTTP since it's used in the // case of redirect to HTTPS. return url.SchemeIsHTTPOrHTTPS() || OriginCanAccessServiceWorkers(url); @@ -239,9 +270,9 @@ network::mojom::RequestDestination::kSharedWorker) << resource_request.destination; - // Create the handler even for insecure HTTP since it's used in the - // case of redirect to HTTPS. - if (!ShouldCreateForWorker(resource_request.url)) + if (!ShouldCreateForWorker( + resource_request.url, + navigation_handle->core()->parent_container_host())) return nullptr; return base::WrapUnique(new ServiceWorkerMainResourceLoaderInterceptor(
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc index 7b7b07db..a2f31cc 100644 --- a/content/browser/service_worker/service_worker_register_job.cc +++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -783,8 +783,8 @@ !it->IsAtEnd(); it->Advance()) { ServiceWorkerContainerHost* container_host = it->GetContainerHost(); DCHECK(container_host->IsContainerForClient()); - if (!blink::ServiceWorkerScopeMatches(registration->scope(), - container_host->url())) { + if (!blink::ServiceWorkerScopeMatches( + registration->scope(), container_host->GetUrlForScopeMatch())) { continue; } container_host->AddMatchingRegistration(registration);
diff --git a/content/browser/service_worker/service_worker_registration.cc b/content/browser/service_worker/service_worker_registration.cc index d5e4b568..1313a77 100644 --- a/content/browser/service_worker/service_worker_registration.cc +++ b/content/browser/service_worker/service_worker_registration.cc
@@ -300,7 +300,7 @@ continue; // "2. If client is not a secure context, continue." - if (!container_host->IsContextSecureForServiceWorker()) + if (!container_host->IsEligibleForServiceWorkerController()) continue; // "3. Let registration be the result of running Match Service Worker
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 43b082a..2597bbb 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -29,7 +29,7 @@ #include "base/memory/scoped_refptr.h" #include "base/path_service.h" #include "base/run_loop.h" -#include "base/scoped_observer.h" +#include "base/scoped_observation.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" @@ -467,19 +467,18 @@ explicit RenderWidgetHostVisibilityObserver(RenderWidgetHostImpl* rwhi, bool expected_visibility_state) : expected_visibility_state_(expected_visibility_state), - observer_(this), was_observed_(false), did_fail_(false), render_widget_(rwhi) { - observer_.Add(render_widget_); + observation_.Observe(render_widget_); message_loop_runner_ = new MessageLoopRunner; } bool WaitUntilSatisfied() { if (!was_observed_) message_loop_runner_->Run(); - if (observer_.IsObserving(render_widget_)) - observer_.Remove(render_widget_); + if (observation_.IsObservingSource(render_widget_)) + observation_.RemoveObservation(); return !did_fail_; } @@ -493,12 +492,14 @@ } void RenderWidgetHostDestroyed(RenderWidgetHost* widget_host) override { - observer_.Remove(widget_host); + DCHECK(observation_.IsObservingSource(widget_host)); + observation_.RemoveObservation(); } bool expected_visibility_state_; scoped_refptr<MessageLoopRunner> message_loop_runner_; - ScopedObserver<RenderWidgetHost, RenderWidgetHostObserver> observer_; + base::ScopedObservation<RenderWidgetHost, RenderWidgetHostObserver> + observation_{this}; bool was_observed_; bool did_fail_; RenderWidgetHost* render_widget_;
diff --git a/content/browser/worker_host/dedicated_worker_host.cc b/content/browser/worker_host/dedicated_worker_host.cc index b42465b79..887472c5 100644 --- a/content/browser/worker_host/dedicated_worker_host.cc +++ b/content/browser/worker_host/dedicated_worker_host.cc
@@ -12,6 +12,7 @@ #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/loader/content_security_notifier.h" #include "content/browser/renderer_host/render_frame_host_impl.h" +#include "content/browser/service_worker/service_worker_container_host.h" #include "content/browser/service_worker/service_worker_main_resource_handle.h" #include "content/browser/service_worker/service_worker_object_host.h" #include "content/browser/storage_partition_impl.h" @@ -51,7 +52,6 @@ : service_(service), token_(token), worker_process_host_(worker_process_host), - scoped_process_host_observer_(this), creator_render_frame_host_id_(creator_render_frame_host_id), ancestor_render_frame_host_id_(ancestor_render_frame_host_id), creator_origin_(creator_origin), @@ -65,7 +65,7 @@ DCHECK(worker_process_host_->IsInitializedAndNotDead()); DCHECK(coep_reporter_); - scoped_process_host_observer_.Add(worker_process_host_); + scoped_process_host_observation_.Observe(worker_process_host_); service_->NotifyWorkerCreated(token_, worker_process_host_->GetID(), ancestor_render_frame_host_id_, this); @@ -185,6 +185,24 @@ service_worker_handle_ = std::make_unique<ServiceWorkerMainResourceHandle>( storage_partition_impl->GetServiceWorkerContext(), base::DoNothing()); + // For blob URL workers, inherit the controller from the worker's parent. + // See https://w3c.github.io/ServiceWorker/#control-and-use-worker-client + if (script_url.SchemeIsBlob()) { + if (creator_render_frame_host_id_) { + base::WeakPtr<ServiceWorkerContainerHost> creator_container_host = + RenderFrameHostImpl::FromID(creator_render_frame_host_id_.value()) + ->GetLastCommittedServiceWorkerHost(); + + service_worker_handle_->core()->set_parent_container_host( + creator_container_host); + } else { + // TODO(https://crbug.com/1017034): When this worker is nested, the worker + // should inherit the active service worker from the parent worker host. + // Implement this behavior. + NOTIMPLEMENTED(); + } + } + // Get a storage domain. auto partition_domain = nearest_ancestor_render_frame_host->GetSiteInstance()->GetPartitionDomain(
diff --git a/content/browser/worker_host/dedicated_worker_host.h b/content/browser/worker_host/dedicated_worker_host.h index 673f2afd4..b716163 100644 --- a/content/browser/worker_host/dedicated_worker_host.h +++ b/content/browser/worker_host/dedicated_worker_host.h
@@ -8,7 +8,7 @@ #include <memory> #include "base/optional.h" -#include "base/scoped_observer.h" +#include "base/scoped_observation.h" #include "build/build_config.h" #include "content/browser/browser_interface_broker_impl.h" #include "content/public/browser/global_routing_id.h" @@ -168,8 +168,8 @@ // The RenderProcessHost that hosts this worker. RenderProcessHost* const worker_process_host_; - ScopedObserver<RenderProcessHost, RenderProcessHostObserver> - scoped_process_host_observer_; + base::ScopedObservation<RenderProcessHost, RenderProcessHostObserver> + scoped_process_host_observation_{this}; // The ID of the frame that directly starts this worker. This is base::nullopt // when this worker is nested.
diff --git a/content/browser/worker_host/dedicated_worker_service_impl_unittest.cc b/content/browser/worker_host/dedicated_worker_service_impl_unittest.cc index 225797e..b9ac189 100644 --- a/content/browser/worker_host/dedicated_worker_service_impl_unittest.cc +++ b/content/browser/worker_host/dedicated_worker_service_impl_unittest.cc
@@ -8,7 +8,7 @@ #include <utility> #include "base/run_loop.h" -#include "base/scoped_observer.h" +#include "base/scoped_observation.h" #include "base/test/scoped_feature_list.h" #include "content/browser/site_instance_impl.h" #include "content/browser/worker_host/dedicated_worker_host.h" @@ -211,9 +211,11 @@ TEST_P(DedicatedWorkerServiceImplTest, DedicatedWorkerServiceObserver) { // Set up the observer. TestDedicatedWorkerServiceObserver observer; - ScopedObserver<DedicatedWorkerService, DedicatedWorkerService::Observer> - scoped_dedicated_worker_service_observer_(&observer); - scoped_dedicated_worker_service_observer_.Add(GetDedicatedWorkerService()); + base::ScopedObservation<DedicatedWorkerService, + DedicatedWorkerService::Observer> + scoped_dedicated_worker_service_observation_(&observer); + scoped_dedicated_worker_service_observation_.Observe( + GetDedicatedWorkerService()); std::unique_ptr<TestWebContents> web_contents = CreateWebContents(GURL("http://example.com/"));
diff --git a/content/browser/worker_host/shared_worker_host.cc b/content/browser/worker_host/shared_worker_host.cc index 403949f9..b4409b70 100644 --- a/content/browser/worker_host/shared_worker_host.cc +++ b/content/browser/worker_host/shared_worker_host.cc
@@ -113,7 +113,6 @@ worker_process_host_(worker_process_host), scoped_process_host_ref_( std::make_unique<ScopedProcessHostRef>(worker_process_host)), - scoped_process_host_observer_(this), next_connection_request_id_(1), devtools_handle_(std::make_unique<ScopedDevToolsHandle>(this)), ukm_source_id_(ukm::ConvertToSourceId(ukm::AssignNewSourceId(), @@ -126,7 +125,7 @@ // when two clients call new SharedWorker() at around the same time. worker_receiver_ = worker_.BindNewPipeAndPassReceiver(); - scoped_process_host_observer_.Add(worker_process_host_); + scoped_process_host_observation_.Observe(worker_process_host_); service_->NotifyWorkerCreated(token_, worker_process_host_->GetID(), devtools_handle_->dev_tools_token());
diff --git a/content/browser/worker_host/shared_worker_host.h b/content/browser/worker_host/shared_worker_host.h index ac039dfc..335891e 100644 --- a/content/browser/worker_host/shared_worker_host.h +++ b/content/browser/worker_host/shared_worker_host.h
@@ -13,7 +13,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/scoped_observer.h" +#include "base/scoped_observation.h" #include "base/strings/string16.h" #include "base/unguessable_token.h" #include "content/browser/browser_interface_broker_impl.h" @@ -227,8 +227,8 @@ std::unique_ptr<ScopedProcessHostRef> scoped_process_host_ref_; // Observe the destruction of |worker_process_host_|. - ScopedObserver<RenderProcessHost, RenderProcessHostObserver> - scoped_process_host_observer_; + base::ScopedObservation<RenderProcessHost, RenderProcessHostObserver> + scoped_process_host_observation_{this}; int next_connection_request_id_;
diff --git a/content/browser/worker_host/shared_worker_service_impl_unittest.cc b/content/browser/worker_host/shared_worker_service_impl_unittest.cc index fc0869f..660e25f 100644 --- a/content/browser/worker_host/shared_worker_service_impl_unittest.cc +++ b/content/browser/worker_host/shared_worker_service_impl_unittest.cc
@@ -13,7 +13,7 @@ #include "base/containers/queue.h" #include "base/macros.h" #include "base/run_loop.h" -#include "base/scoped_observer.h" +#include "base/scoped_observation.h" #include "build/build_config.h" #include "content/browser/site_instance_impl.h" #include "content/browser/worker_host/mock_shared_worker.h" @@ -1323,11 +1323,12 @@ TEST_F(SharedWorkerServiceImplTest, Observer) { TestSharedWorkerServiceObserver observer; - ScopedObserver<SharedWorkerService, SharedWorkerService::Observer> - scoped_observer(&observer); - scoped_observer.Add(content::BrowserContext::GetDefaultStoragePartition( - browser_context_.get()) - ->GetSharedWorkerService()); + base::ScopedObservation<SharedWorkerService, SharedWorkerService::Observer> + scoped_observation(&observer); + scoped_observation.Observe( + content::BrowserContext::GetDefaultStoragePartition( + browser_context_.get()) + ->GetSharedWorkerService()); std::unique_ptr<TestWebContents> web_contents = CreateWebContents(GURL("http://example.com/")); @@ -1433,11 +1434,12 @@ TEST_F(SharedWorkerServiceImplTest, CollapseDuplicateNotifications) { TestSharedWorkerServiceObserver observer; - ScopedObserver<SharedWorkerService, SharedWorkerService::Observer> - scoped_observer(&observer); - scoped_observer.Add(content::BrowserContext::GetDefaultStoragePartition( - browser_context_.get()) - ->GetSharedWorkerService()); + base::ScopedObservation<SharedWorkerService, SharedWorkerService::Observer> + scoped_observation(&observer); + scoped_observation.Observe( + content::BrowserContext::GetDefaultStoragePartition( + browser_context_.get()) + ->GetSharedWorkerService()); const GURL kUrl("http://example.com/w.js"); const char kName[] = "name"; @@ -1525,11 +1527,12 @@ TEST_F(SharedWorkerServiceImplTest, Observer_OnClientConnectionLost) { TestSharedWorkerServiceObserver observer; - ScopedObserver<SharedWorkerService, SharedWorkerService::Observer> - scoped_observer(&observer); - scoped_observer.Add(content::BrowserContext::GetDefaultStoragePartition( - browser_context_.get()) - ->GetSharedWorkerService()); + base::ScopedObservation<SharedWorkerService, SharedWorkerService::Observer> + scoped_observation(&observer); + scoped_observation.Observe( + content::BrowserContext::GetDefaultStoragePartition( + browser_context_.get()) + ->GetSharedWorkerService()); std::unique_ptr<TestWebContents> web_contents = CreateWebContents(GURL("http://example.com/"));
diff --git a/content/common/frame.mojom b/content/common/frame.mojom index dab17d4..599059d 100644 --- a/content/common/frame.mojom +++ b/content/common/frame.mojom
@@ -92,9 +92,6 @@ // It is safe to call this without calling BlockRequests. ResumeBlockedRequests(); - // Cancels blocked requests. BlockRequests must have been called before. - CancelBlockedRequests(); - // Samsung Galaxy Note-specific "smart clip" stylus text getter. // Extracts the data at the given rect. [EnableIf=is_android]
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index dcb0d7c6..5913443f7 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -478,18 +478,6 @@ // feature policy. virtual bool IsFeatureEnabled(blink::mojom::FeaturePolicyFeature feature) = 0; - // Returns true if the given |threshold_value| is below the threshold value - // specified in the policy for |feature| for this RenderFrameHost. See - // third_party/blink/public/common/feature_policy/document_policy.h for how to - // compare values of different types. Use this in the browser process to - // determine whether access to a feature is allowed. - virtual bool IsFeatureEnabled(blink::mojom::DocumentPolicyFeature feature, - blink::PolicyValue threshold_value) = 0; - // Same as above, with |threshold_value| set to the max value the given - // |feature| can have. - virtual bool IsFeatureEnabled( - blink::mojom::DocumentPolicyFeature feature) = 0; - // Opens view-source tab for the document last committed in this // RenderFrameHost. virtual void ViewSource() = 0;
diff --git a/content/public/test/dump_accessibility_test_helper.cc b/content/public/test/dump_accessibility_test_helper.cc index c73daf8..4398146 100644 --- a/content/public/test/dump_accessibility_test_helper.cc +++ b/content/public/test/dump_accessibility_test_helper.cc
@@ -21,11 +21,85 @@ namespace content { +using base::FilePath; +using ui::AXNodeFilter; +using ui::AXPropertyFilter; + namespace { const char kCommentToken = '#'; const char kMarkSkipFile[] = "#<skip"; const char kSignalDiff[] = "*"; const char kMarkEndOfFile[] = "<-- End-of-file -->"; + +struct TypeInfo { + std::string type; + struct Mapping { + std::string directive_prefix; + base::FilePath::StringType expectations_file_postfix; + } mapping; +}; + +const TypeInfo kTypeInfos[] = {{ + "android", + { + "@ANDROID", + FILE_PATH_LITERAL("-android"), + }, + }, + { + "blink", + { + "@BLINK", + FILE_PATH_LITERAL("-blink"), + }, + }, + { + "linux", + { + "@AURALINUX", + FILE_PATH_LITERAL("-auralinux"), + }, + }, + { + "mac", + { + "@MAC", + FILE_PATH_LITERAL("-mac"), + }, + }, + { + "content", + { + "@", + FILE_PATH_LITERAL(""), + }, + }, + { + "uia", + { + "@UIA-WIN", + FILE_PATH_LITERAL("-uia-win"), + }, + }, + { + "win", + { + "@WIN", + FILE_PATH_LITERAL("-win"), + }, + }}; + +const TypeInfo::Mapping* TypeMapping(const std::string& type) { + const TypeInfo::Mapping* mapping = nullptr; + for (const auto& info : kTypeInfos) { + if (info.type == type) { + mapping = &info.mapping; + } + } + CHECK(mapping) << "Unknown dump accessibility type " << type; + return mapping; +} + } // namespace DumpAccessibilityTestHelper::DumpAccessibilityTestHelper( @@ -64,6 +138,98 @@ return base::FilePath(); } +bool DumpAccessibilityTestHelper::ParsePropertyFilter( + const std::string& line, + std::vector<AXPropertyFilter>* filters) const { + const TypeInfo::Mapping* mapping = TypeMapping(expectation_type_); + if (!mapping) { + return false; + } + + std::string directive = mapping->directive_prefix + "-ALLOW-EMPTY:"; + if (base::StartsWith(line, directive, base::CompareCase::SENSITIVE)) { + filters->emplace_back(line.substr(directive.size()), + AXPropertyFilter::ALLOW_EMPTY); + return true; + } + + directive = mapping->directive_prefix + "-ALLOW:"; + if (base::StartsWith(line, directive, base::CompareCase::SENSITIVE)) { + filters->emplace_back(line.substr(directive.size()), + AXPropertyFilter::ALLOW); + return true; + } + + directive = mapping->directive_prefix + "-DENY:"; + if (base::StartsWith(line, directive, base::CompareCase::SENSITIVE)) { + filters->emplace_back(line.substr(directive.size()), + AXPropertyFilter::DENY); + return true; + } + + return false; +} + +bool DumpAccessibilityTestHelper::ParseNodeFilter( + const std::string& line, + std::vector<AXNodeFilter>* filters) const { + const TypeInfo::Mapping* mapping = TypeMapping(expectation_type_); + if (!mapping) { + return false; + } + + std::string directive = mapping->directive_prefix + "-DENY-NODE:"; + if (base::StartsWith(line, directive, base::CompareCase::SENSITIVE)) { + const auto& node_filter = line.substr(directive.size()); + const auto& parts = base::SplitString( + node_filter, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + // Silently skip over parsing errors like the rest of the enclosing code. + if (parts.size() == 2) { + filters->emplace_back(parts[0], parts[1]); + return true; + } + } + + return false; +} + +DumpAccessibilityTestHelper::Directive +DumpAccessibilityTestHelper::ParseDirective(const std::string& line) const { + // Directives have format of @directive:value. + if (!base::StartsWith(line, "@")) { + return {}; + } + + auto directive_end_pos = line.find_first_of(':'); + if (directive_end_pos == std::string::npos) { + return {}; + } + + const TypeInfo::Mapping* mapping = TypeMapping(expectation_type_); + if (!mapping) { + return {}; + } + + std::string directive = line.substr(0, directive_end_pos); + std::string value = line.substr(directive_end_pos + 1); + if (directive == "@NO-LOAD-EXPECTED") { + return {Directive::kNoLoadExpected, value}; + } + if (directive == "@WAIT-FOR") { + return {Directive::kWaitFor, value}; + } + if (directive == "@EXECUTE-AND-WAIT-FOR") { + return {Directive::kExecuteAndWaitFor, value}; + } + if (directive == mapping->directive_prefix + "-RUN-UNTIL-EVENT") { + return {Directive::kRunUntil, value}; + } + if (directive == "@DEFAULT-ACTION-ON") { + return {Directive::kDefaultActionOn, value}; + } + return {}; +} + base::Optional<std::vector<std::string>> DumpAccessibilityTestHelper::LoadExpectationFile( const base::FilePath& expected_file) { @@ -150,35 +316,18 @@ return !is_different; } -base::FilePath::StringType -DumpAccessibilityTestHelper::GetExpectedFileSuffix() { - if (expectation_type_ == "android") { - return FILE_PATH_LITERAL("-expected-android.txt"); +FilePath::StringType DumpAccessibilityTestHelper::GetExpectedFileSuffix() + const { + const TypeInfo::Mapping* mapping = TypeMapping(expectation_type_); + if (!mapping) { + return FILE_PATH_LITERAL(""); } - if (expectation_type_ == "blink") { - return FILE_PATH_LITERAL("-expected-blink.txt"); - } - if (expectation_type_ == "linux") { - return FILE_PATH_LITERAL("-expected-auralinux.txt"); - } - if (expectation_type_ == "mac") { - return FILE_PATH_LITERAL("-expected-mac.txt"); - } - if (expectation_type_ == "content") { - return FILE_PATH_LITERAL("-expected.txt"); - } - if (expectation_type_ == "uia") { - return FILE_PATH_LITERAL("-expected-uia-win.txt"); - } - if (expectation_type_ == "win") { - return FILE_PATH_LITERAL("-expected-win.txt"); - } - NOTREACHED(); - return FILE_PATH_LITERAL(""); + return FILE_PATH_LITERAL("-expected") + mapping->expectations_file_postfix + + FILE_PATH_LITERAL(".txt"); } -base::FilePath::StringType -DumpAccessibilityTestHelper::GetVersionSpecificExpectedFileSuffix() { +FilePath::StringType +DumpAccessibilityTestHelper::GetVersionSpecificExpectedFileSuffix() const { #if defined(OS_WIN) if (expectation_type_ == "uia" && base::win::GetVersion() == base::win::Version::WIN7) {
diff --git a/content/public/test/dump_accessibility_test_helper.h b/content/public/test/dump_accessibility_test_helper.h index 3c739a5..0eccf5b 100644 --- a/content/public/test/dump_accessibility_test_helper.h +++ b/content/public/test/dump_accessibility_test_helper.h
@@ -13,6 +13,11 @@ class FilePath; } +namespace ui { +struct AXNodeFilter; +struct AXPropertyFilter; +} // namespace ui + namespace content { // A helper class for writing accessibility tree dump tests. @@ -26,6 +31,50 @@ // an empty path. base::FilePath GetExpectationFilePath(const base::FilePath& test_file_path); + // Parses property filter directive, if the line is a valid property filter + // directive, then a new property filter is created and appneded to the list, + // true is returned, otherwise false. + bool ParsePropertyFilter(const std::string& line, + std::vector<ui::AXPropertyFilter>* filters) const; + + // Parses node filter directive, if the line is a valid node filter directive + // then a new node filter is created and appneded to the list, true is + // returned, otherwise false. + bool ParseNodeFilter(const std::string& line, + std::vector<ui::AXNodeFilter>* filters) const; + + struct Directive { + enum Type { + // No directive. + kNone, + + // Instructs to not wait for document load for url defined by the + // directive. + kNoLoadExpected, + + // Delays a test unitl a string defined by the directive is present + // in the dump. + kWaitFor, + + // Delays a test until a string returned by a script defined by the + // directive is present in the dump. + kExecuteAndWaitFor, + + // Indicates event recording should continue at least until a specific + // event has been received. + kRunUntil, + + // Invokes default action on an accessible object defined by the + // directive. + kDefaultActionOn, + } type; + + std::string value; + }; + + // Parses directives from the given line. + Directive ParseDirective(const std::string& line) const; + // Loads the given expectation file and returns the contents. An expectation // file may be empty, in which case an empty vector is returned. // Returns nullopt if the file contains a skip marker. @@ -47,12 +96,12 @@ // Example: // HTML test: test-file.html // Expected: test-file-expected-mac.txt. - base::FilePath::StringType GetExpectedFileSuffix(); + base::FilePath::StringType GetExpectedFileSuffix() const; // Some Platforms expect different outputs depending on the version. // Most test outputs are identical but this allows a version specific // expected file to be used. - base::FilePath::StringType GetVersionSpecificExpectedFileSuffix(); + base::FilePath::StringType GetVersionSpecificExpectedFileSuffix() const; FRIEND_TEST_ALL_PREFIXES(DumpAccessibilityTestHelperTest, TestDiffLines);
diff --git a/content/renderer/loader/url_loader_client_impl.cc b/content/renderer/loader/url_loader_client_impl.cc index 9381fbb..7c0cd0f 100644 --- a/content/renderer/loader/url_loader_client_impl.cc +++ b/content/renderer/loader/url_loader_client_impl.cc
@@ -165,6 +165,14 @@ // mojo::DataPipeDrainer::Client void OnDataAvailable(const void* data, size_t num_bytes) override { DCHECK(draining_); + SCOPED_CRASH_KEY_NUMBER(OnDataAvailable, buffered_body_bytes, + buffered_body_.size()); + SCOPED_CRASH_KEY_NUMBER(OnDataAvailable, remaining_bytes, + bytes_remaining_in_buffer_); + SCOPED_CRASH_KEY_NUMBER(OnDataAvailable, data_bytes, num_bytes); + SCOPED_CRASH_KEY_STRING256( + OnDataAvailable, last_loaded_url, + owner_->last_loaded_url().possibly_invalid_spec()); const auto span = base::make_span(static_cast<const char*>(data), num_bytes); buffered_body_.insert(buffered_body_.end(), span.begin(), span.end());
diff --git a/content/renderer/loader/url_loader_client_impl.h b/content/renderer/loader/url_loader_client_impl.h index cf9ba31..5fb24d0 100644 --- a/content/renderer/loader/url_loader_client_impl.h +++ b/content/renderer/loader/url_loader_client_impl.h
@@ -76,6 +76,8 @@ mojo::ScopedDataPipeConsumerHandle body) override; void OnComplete(const network::URLLoaderCompletionStatus& status) override; + const GURL& last_loaded_url() const { return last_loaded_url_; } + private: class BodyBuffer; class DeferredMessage;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index e5d4db6..402add0 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -3017,10 +3017,6 @@ frame_request_blocker_->Resume(); } -void RenderFrameImpl::CancelBlockedRequests() { - frame_request_blocker_->Cancel(); -} - void RenderFrameImpl::AllowBindings(int32_t enabled_bindings_flags) { enabled_bindings_ |= enabled_bindings_flags; }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 662c847b0..22851071 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -450,7 +450,6 @@ GetCanonicalUrlForSharingCallback callback) override; void BlockRequests() override; void ResumeBlockedRequests() override; - void CancelBlockedRequests() override; void UpdateBrowserControlsState(BrowserControlsState constraints, BrowserControlsState current, bool animate) override;
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index 952442c57..c073c9f5 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -120,16 +120,6 @@ RenderFrameHostImpl::ReportHeavyAdIssue(resolution, reason); } -void TestRenderFrameHost::AddUniqueMessageToConsole( - blink::mojom::ConsoleMessageLevel level, - const std::string& message) { - if (std::find(console_messages_.begin(), console_messages_.end(), message) == - console_messages_.end()) { - console_messages_.push_back(message); - } - RenderFrameHostImpl::AddUniqueMessageToConsole(level, message); -} - bool TestRenderFrameHost::IsTestRenderFrameHost() const { return true; }
diff --git a/content/test/test_render_frame_host.h b/content/test/test_render_frame_host.h index 880f0fa2..e255f50 100644 --- a/content/test/test_render_frame_host.h +++ b/content/test/test_render_frame_host.h
@@ -69,8 +69,6 @@ const std::string& message) override; void ReportHeavyAdIssue(blink::mojom::HeavyAdResolutionStatus resolution, blink::mojom::HeavyAdReason reason) override; - void AddUniqueMessageToConsole(blink::mojom::ConsoleMessageLevel level, - const std::string& message) override; bool IsTestRenderFrameHost() const override; // Public overrides to expose RenderFrameHostImpl's mojo methods to tests.
diff --git a/courgette/disassembler_win32_x64_unittest.cc b/courgette/disassembler_win32_x64_unittest.cc index 718bfd0..b47ccfc2 100644 --- a/courgette/disassembler_win32_x64_unittest.cc +++ b/courgette/disassembler_win32_x64_unittest.cc
@@ -10,7 +10,7 @@ #include <string> #include <vector> -#include "base/stl_util.h" +#include "base/ranges/algorithm.h" #include "courgette/base_test_unittest.h" class DisassemblerWin32X64Test : public BaseTest { @@ -47,7 +47,7 @@ std::vector<courgette::RVA> relocs; bool can_parse_relocs = disassembler->ParseRelocs(&relocs); EXPECT_TRUE(can_parse_relocs); - EXPECT_TRUE(base::STLIsSorted(relocs)); + EXPECT_TRUE(base::ranges::is_sorted(relocs)); const uint8_t* offset_p = disassembler->FileOffsetToPointer(0); EXPECT_EQ(reinterpret_cast<const void*>(file1.c_str()),
diff --git a/courgette/disassembler_win32_x86_unittest.cc b/courgette/disassembler_win32_x86_unittest.cc index d6c27e0..28cddc8 100644 --- a/courgette/disassembler_win32_x86_unittest.cc +++ b/courgette/disassembler_win32_x86_unittest.cc
@@ -10,7 +10,7 @@ #include <string> #include <vector> -#include "base/stl_util.h" +#include "base/ranges/algorithm.h" #include "courgette/base_test_unittest.h" class DisassemblerWin32X86Test : public BaseTest { @@ -47,7 +47,7 @@ std::vector<courgette::RVA> relocs; bool can_parse_relocs = disassembler->ParseRelocs(&relocs); EXPECT_TRUE(can_parse_relocs); - EXPECT_TRUE(base::STLIsSorted(relocs)); + EXPECT_TRUE(base::ranges::is_sorted(relocs)); const uint8_t* offset_p = disassembler->FileOffsetToPointer(0); EXPECT_EQ(reinterpret_cast<const void*>(file1.c_str()),
diff --git a/extensions/common/manifest_handlers/externally_connectable.cc b/extensions/common/manifest_handlers/externally_connectable.cc index af0ee54f..65837bd 100644 --- a/extensions/common/manifest_handlers/externally_connectable.cc +++ b/extensions/common/manifest_handlers/externally_connectable.cc
@@ -10,7 +10,7 @@ #include <memory> #include "base/memory/ptr_util.h" -#include "base/stl_util.h" +#include "base/ranges/algorithm.h" #include "base/strings/utf_string_conversions.h" #include "components/crx_file/id_util.h" #include "extensions/common/api/extensions_manifest_types.h" @@ -204,7 +204,7 @@ bool ExternallyConnectableInfo::IdCanConnect(const std::string& id) { if (all_ids) return true; - DCHECK(base::STLIsSorted(ids)); + DCHECK(base::ranges::is_sorted(ids)); return std::binary_search(ids.begin(), ids.end(), id); }
diff --git a/extensions/renderer/bindings/argument_spec.cc b/extensions/renderer/bindings/argument_spec.cc index 9637be5..4fc4d5f 100644 --- a/extensions/renderer/bindings/argument_spec.cc +++ b/extensions/renderer/bindings/argument_spec.cc
@@ -4,6 +4,7 @@ #include "extensions/renderer/bindings/argument_spec.h" +#include "base/check.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -190,6 +191,9 @@ enum_values_.insert(std::move(enum_value)); } } + } else if (type_ == ArgumentType::FUNCTION) { + serialize_function_ = + dict->FindBoolKey("serializableFunction").value_or(false); } // Check if we should preserve null in objects. Right now, this is only used @@ -301,19 +305,8 @@ case ArgumentType::BINARY: return ParseArgumentToAny(context, value, out_value, v8_out_value, error); case ArgumentType::FUNCTION: - if (out_value) { - // Certain APIs (contextMenus) have functions as parameters other than - // the callback (contextMenus uses it for an onclick listener). Our - // generated types have adapted to consider functions "objects" and - // serialize them as dictionaries. - // TODO(devlin): It'd be awfully nice to get rid of this eccentricity. - *out_value = std::make_unique<base::DictionaryValue>(); - } - - if (v8_out_value) - *v8_out_value = value; - - return true; + return ParseArgumentToFunction(context, value, out_value, v8_out_value, + error); case ArgumentType::REF: { DCHECK(ref_); const ArgumentSpec* reference = refs.GetSpec(ref_.value()); @@ -754,6 +747,43 @@ return true; } +bool ArgumentSpec::ParseArgumentToFunction( + v8::Local<v8::Context> context, + v8::Local<v8::Value> value, + std::unique_ptr<base::Value>* out_value, + v8::Local<v8::Value>* v8_out_value, + std::string* error) const { + DCHECK_EQ(ArgumentType::FUNCTION, type_); + DCHECK(value->IsFunction()); + if (out_value) { + if (serialize_function_) { + v8::Local<v8::String> serialized_function; + if (!value.As<v8::Function>()->FunctionProtoToString(context).ToLocal( + &serialized_function)) { + *error = api_errors::ScriptThrewError(); + return false; + } + std::string str; + // If ToLocal() succeeds, this should always be a string. + CHECK(gin::Converter<std::string>::FromV8(context->GetIsolate(), + serialized_function, &str)); + *out_value = std::make_unique<base::Value>(std::move(str)); + } else { // Not a serializable function. + // Certain APIs (contextMenus) have functions as parameters other than + // the callback (contextMenus uses it for an onclick listener). Our + // generated types have adapted to consider functions "objects" and + // serialize them as dictionaries. + // TODO(devlin): It'd be awfully nice to get rid of this eccentricity. + *out_value = std::make_unique<base::DictionaryValue>(); + } + } + + if (v8_out_value) + *v8_out_value = value; + + return true; +} + std::string ArgumentSpec::GetInvalidTypeError( v8::Local<v8::Value> value) const { return api_errors::InvalidType(GetTypeName().c_str(),
diff --git a/extensions/renderer/bindings/argument_spec.h b/extensions/renderer/bindings/argument_spec.h index 56506a3..ababad6 100644 --- a/extensions/renderer/bindings/argument_spec.h +++ b/extensions/renderer/bindings/argument_spec.h
@@ -107,6 +107,9 @@ instance_of_ = std::move(instance_of); } void set_preserve_null(bool preserve_null) { preserve_null_ = preserve_null; } + void set_serialize_function(bool serialize_function) { + serialize_function_ = serialize_function; + } private: // Initializes this object according to |type_string| and |dict|. @@ -136,6 +139,11 @@ std::unique_ptr<base::Value>* out_value, v8::Local<v8::Value>* v8_out_value, std::string* error) const; + bool ParseArgumentToFunction(v8::Local<v8::Context> context, + v8::Local<v8::Value> value, + std::unique_ptr<base::Value>* out_value, + v8::Local<v8::Value>* v8_out_value, + std::string* error) const; // Returns an error message indicating the type of |value| does not match the // expected type. @@ -156,6 +164,10 @@ // Whether to preserve null properties found in objects. bool preserve_null_ = false; + // Whether to serialize (by stringifying) a function argument. Only valid for + // arguments of type FUNCTION. + bool serialize_function_ = false; + // The reference the argument points to, if any. Note that if this is set, // none of the following fields describing the argument will be. base::Optional<std::string> ref_;
diff --git a/extensions/renderer/bindings/argument_spec_unittest.cc b/extensions/renderer/bindings/argument_spec_unittest.cc index da8f082..312205d1 100644 --- a/extensions/renderer/bindings/argument_spec_unittest.cc +++ b/extensions/renderer/bindings/argument_spec_unittest.cc
@@ -7,6 +7,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/stl_util.h" +#include "base/strings/stringprintf.h" #include "base/values.h" #include "extensions/renderer/bindings/api_binding_test_util.h" #include "extensions/renderer/bindings/api_invocation_errors.h" @@ -1016,4 +1017,37 @@ } } +// Tests the serialization of functions that are explicitly marked as +// serializable (otherwise, they are represented as empty DictionaryValues). +TEST_F(ArgumentSpecUnitTest, SerializableFunctions) { + constexpr char kFunctionSpec[] = + R"({ + "type": "function", + "serializableFunction": true + })"; + ArgumentSpec spec(*ValueFromString(kFunctionSpec)); + + constexpr char kExpectedSerialization[] = R"("function() { }")"; + ExpectSuccess(spec, "(function() { })", kExpectedSerialization); + + { + constexpr char kNonTrivialFunction[] = + R"(function(foo, bar, baz) { let alpha = baz; })"; + ExpectSuccess(spec, base::StringPrintf("(%s)", kNonTrivialFunction), + base::StringPrintf(R"("%s")", kNonTrivialFunction)); + } + + // Test a couple tricky values with custom toString() implementations. + ExpectSuccess(spec, + R"(var f = function() { }; + f.toString = function() { throw new Error('haha!'); }; + f;)", + kExpectedSerialization); + ExpectSuccess(spec, + R"(var g = function() { }; + g.toString = function() { return 'function() { return 3; }'; }; + g;)", + kExpectedSerialization); +} + } // namespace extensions
diff --git a/gpu/command_buffer/service/image_reader_gl_owner.cc b/gpu/command_buffer/service/image_reader_gl_owner.cc index 4790d4a..5efa957 100644 --- a/gpu/command_buffer/service/image_reader_gl_owner.cc +++ b/gpu/command_buffer/service/image_reader_gl_owner.cc
@@ -240,12 +240,13 @@ // Get the java surface object from the Android native window. JNIEnv* env = base::android::AttachCurrentThread(); - auto j_surface = base::android::ScopedJavaLocalRef<jobject>::Adopt( - env, loader_.ANativeWindow_toSurface(env, window)); + jobject j_surface = loader_.ANativeWindow_toSurface(env, window); DCHECK(j_surface); // Get the scoped java surface that is owned externally. - return gl::ScopedJavaSurface::AcquireExternalSurface(j_surface); + // TODO(1146071): use of JavaParamRef temporary to try to debug crash. + return gl::ScopedJavaSurface::AcquireExternalSurface( + base::android::JavaParamRef<jobject>(env, j_surface)); } void ImageReaderGLOwner::UpdateTexImage() {
diff --git a/infra/config/generated/tricium-prod.cfg b/infra/config/generated/tricium-prod.cfg index daa23d9a..8faec8b 100644 --- a/infra/config/generated/tricium-prod.cfg +++ b/infra/config/generated/tricium-prod.cfg
@@ -6,9 +6,6 @@ group: "tricium-chromium-requesters" } -# Analyzer definitions -# These are analyzers that are only applicable to this repository. - functions { type: ANALYZER name: "ClangTidy" @@ -43,6 +40,25 @@ functions { type: ANALYZER + name: "ChromiumWrapper" + needs: GIT_FILE_DETAILS + provides: RESULTS + owner: "qyearsley@chromium.org" + monorail_component: "Infra>Platform>Tricium>Analyzer" + impls { + runtime_platform: LINUX + provides_for_platform: LINUX + recipe { + project: "chromium" + bucket: "try" + builder: "tricium-simple" + } + deadline: 900 + } +} + +functions { + type: ANALYZER name: "Metrics" needs: GIT_FILE_DETAILS provides: RESULTS @@ -62,20 +78,13 @@ } } -# Selections (enabled functions) - selections { function: "ClangTidy" platform: LINUX } selections { - function: "GitFileIsolator" - platform: UBUNTU -} - -selections { - function: "HttpsCheck" + function: "ChromiumWrapper" platform: UBUNTU } @@ -84,29 +93,6 @@ platform: UBUNTU } -selections { - function: "MojomCommentator" - platform: UBUNTU -} - -selections { - function: "Pylint" - platform: UBUNTU - configs { - name: "disable" - value: "all" - } - configs { - name: "enable" - value: "syntax-error,unused-variable,undefined-variable,unused-import" - } -} - -selections { - function: "SpellChecker" - platform: UBUNTU -} - repos { gerrit_project { host: "chromium-review.googlesource.com"
diff --git a/infra/config/tricium-prod.cfg b/infra/config/tricium-prod.cfg index daa23d9a..8faec8b 100644 --- a/infra/config/tricium-prod.cfg +++ b/infra/config/tricium-prod.cfg
@@ -6,9 +6,6 @@ group: "tricium-chromium-requesters" } -# Analyzer definitions -# These are analyzers that are only applicable to this repository. - functions { type: ANALYZER name: "ClangTidy" @@ -43,6 +40,25 @@ functions { type: ANALYZER + name: "ChromiumWrapper" + needs: GIT_FILE_DETAILS + provides: RESULTS + owner: "qyearsley@chromium.org" + monorail_component: "Infra>Platform>Tricium>Analyzer" + impls { + runtime_platform: LINUX + provides_for_platform: LINUX + recipe { + project: "chromium" + bucket: "try" + builder: "tricium-simple" + } + deadline: 900 + } +} + +functions { + type: ANALYZER name: "Metrics" needs: GIT_FILE_DETAILS provides: RESULTS @@ -62,20 +78,13 @@ } } -# Selections (enabled functions) - selections { function: "ClangTidy" platform: LINUX } selections { - function: "GitFileIsolator" - platform: UBUNTU -} - -selections { - function: "HttpsCheck" + function: "ChromiumWrapper" platform: UBUNTU } @@ -84,29 +93,6 @@ platform: UBUNTU } -selections { - function: "MojomCommentator" - platform: UBUNTU -} - -selections { - function: "Pylint" - platform: UBUNTU - configs { - name: "disable" - value: "all" - } - configs { - name: "enable" - value: "syntax-error,unused-variable,undefined-variable,unused-import" - } -} - -selections { - function: "SpellChecker" - platform: UBUNTU -} - repos { gerrit_project { host: "chromium-review.googlesource.com"
diff --git a/ios/chrome/browser/autofill/form_structure_browsertest.mm b/ios/chrome/browser/autofill/form_structure_browsertest.mm index 7130dad..2478611d 100644 --- a/ios/chrome/browser/autofill/form_structure_browsertest.mm +++ b/ios/chrome/browser/autofill/form_structure_browsertest.mm
@@ -138,6 +138,8 @@ autofill::features::kAutofillEnableSupportForMoreStructureInNames, // TODO(crbug.com/1125978): Remove once launched. autofill::features::kAutofillEnableSupportForMoreStructureInAddresses, + // TODO(crbug.com/896689): Remove once launched. + autofill::features::kAutofillNameSectionsWithRendererIds, }, // Disabled {autofill::features::kAutofillRestrictUnownedFieldsToFormlessCheckout}); @@ -212,6 +214,7 @@ // deterministic. for (const auto& form_kv : forms) { const auto* form = form_kv.second.get(); + std::map<std::string, int> section_to_index; for (const auto& field : *form) { std::string name = base::UTF16ToUTF8(field->name); if (base::StartsWith(name, "gChrome~field~", @@ -220,6 +223,7 @@ // to have a behavior similar to other platforms. name = ""; } + std::string section = field->section; if (base::StartsWith(section, "gChrome~field~", base::CompareCase::SENSITIVE)) { @@ -228,6 +232,22 @@ size_t first_underscore = section.find_first_of('_'); section = section.substr(first_underscore); } + + // Normalize the section by replacing the unique but platform-dependent + // integers in |field->section| with consecutive unique integers. + size_t last_underscore = section.find_last_of('_'); + size_t next_dash = section.find_first_of('-', last_underscore); + int new_section_index = static_cast<int>(section_to_index.size() + 1); + int section_index = + section_to_index.insert(std::make_pair(section, new_section_index)) + .first->second; + if (last_underscore != std::string::npos && + next_dash != std::string::npos) { + section = base::StringPrintf( + "%s%d%s", section.substr(0, last_underscore + 1).c_str(), + section_index, section.substr(next_dash).c_str()); + } + forms_string += field->Type().ToString(); forms_string += " | " + name; forms_string += " | " + base::UTF16ToUTF8(field->label);
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm index 6904a70..07d18a5 100644 --- a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm +++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm
@@ -34,6 +34,7 @@ #include "components/metrics/cpu_metrics_provider.h" #include "components/metrics/demographics/demographic_metrics_provider.h" #include "components/metrics/drive_metrics_provider.h" +#include "components/metrics/entropy_state_provider.h" #include "components/metrics/field_trials_provider.h" #include "components/metrics/metrics_log_uploader.h" #include "components/metrics/metrics_pref_names.h" @@ -264,6 +265,8 @@ } void IOSChromeMetricsServiceClient::RegisterMetricsServiceProviders() { + PrefService* local_state = GetApplicationContext()->GetLocalState(); + metrics_service_->RegisterMetricsProvider( std::make_unique<metrics::NetworkMetricsProvider>( base::BindRepeating(&GetNetworkConnectionTrackerAsync))); @@ -272,8 +275,7 @@ std::make_unique<OmniboxMetricsProvider>()); auto stability_metrics_provider = - std::make_unique<IOSChromeStabilityMetricsProvider>( - GetApplicationContext()->GetLocalState()); + std::make_unique<IOSChromeStabilityMetricsProvider>(local_state); stability_metrics_provider_ = stability_metrics_provider.get(); metrics_service_->RegisterMetricsProvider( std::move(stability_metrics_provider)); @@ -288,6 +290,9 @@ metrics_state_manager_->IsMetricsReportingEnabled())); metrics_service_->RegisterMetricsProvider( + std::make_unique<metrics::EntropyStateProvider>(local_state)); + + metrics_service_->RegisterMetricsProvider( std::make_unique<metrics::ScreenInfoMetricsProvider>()); metrics_service_->RegisterMetricsProvider(
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client_unittest.mm b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client_unittest.mm index f0a87bcd..ad35bc10 100644 --- a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client_unittest.mm +++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client_unittest.mm
@@ -95,7 +95,7 @@ // This is the number of metrics providers that are registered inside // IOSChromeMetricsServiceClient::Initialize(). - expected_providers += 13; + expected_providers += 14; std::unique_ptr<IOSChromeMetricsServiceClient> chrome_metrics_service_client = IOSChromeMetricsServiceClient::Create(metrics_state_manager_.get());
diff --git a/ios/chrome/browser/passwords/password_controller_js_unittest.mm b/ios/chrome/browser/passwords/password_controller_js_unittest.mm index 89fc5508..8f9faff 100644 --- a/ios/chrome/browser/passwords/password_controller_js_unittest.mm +++ b/ios/chrome/browser/passwords/password_controller_js_unittest.mm
@@ -643,6 +643,39 @@ @"document.getElementById('user').value == '%@'", password)); } +// Check that a matching and complete password form is successfully filled +// with the generated password. +TEST_F(PasswordControllerJsTest, + FillPasswordFormWithGeneratedPassword_SucceedsOutsideFormTag) { + LoadHtmlAndInject(@"<html>" + " <body>" + " <input type=\"text\" id=\"user\" name=\"user\">" + " <input type=\"password\" id=\"ps1\" name=\"ps1\">" + " <input type=\"password\" id=\"ps2\" name=\"ps2\">" + " <input type=\"submit\" name=\"go\">" + " </body>" + "</html>"); + SetUpUniqueIDs(); + + NSString* const password = @"abc"; + uint32_t const newPasswordIdentifier = 1; + uint32_t const confirmPasswordIdentifier = 2; + EXPECT_NSEQ(@YES, + ExecuteJavaScriptWithFormat( + @"__gCrWeb.passwords." + @"fillPasswordFormWithGeneratedPassword(-1, %u, %u, '%@')", + newPasswordIdentifier, confirmPasswordIdentifier, password)); + EXPECT_NSEQ(@YES, + ExecuteJavaScriptWithFormat( + @"document.getElementById('ps1').value == '%@'", password)); + EXPECT_NSEQ(@YES, + ExecuteJavaScriptWithFormat( + @"document.getElementById('ps2').value == '%@'", password)); + EXPECT_NSEQ(@NO, + ExecuteJavaScriptWithFormat( + @"document.getElementById('user').value == '%@'", password)); +} + // Check that a form with only password field (i.e. w/o username) is filled. TEST_F(PasswordControllerJsTest, FillOnlyPasswordField) { LoadHtmlAndInject(
diff --git a/ios/chrome/browser/ui/main/scene_state.h b/ios/chrome/browser/ui/main/scene_state.h index 1716ec2..e8336bfd 100644 --- a/ios/chrome/browser/ui/main/scene_state.h +++ b/ios/chrome/browser/ui/main/scene_state.h
@@ -113,6 +113,9 @@ // Adds a new agent. Agents are owned by the scene state. - (void)addAgent:(id<SceneAgent>)agent; +// Array of all agents added to this scene state. +- (NSArray*)connectedAgents; + @end #endif // IOS_CHROME_BROWSER_UI_MAIN_SCENE_STATE_H_
diff --git a/ios/chrome/browser/ui/main/scene_state.mm b/ios/chrome/browser/ui/main/scene_state.mm index 1963ba83..4825069 100644 --- a/ios/chrome/browser/ui/main/scene_state.mm +++ b/ios/chrome/browser/ui/main/scene_state.mm
@@ -70,6 +70,10 @@ [agent setSceneState:self]; } +- (NSArray*)connectedAgents { + return self.agents; +} + #pragma mark - Setters & Getters. - (void)setWindow:(UIWindow*)window {
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details.mm index ae87cc3..96dc6c3 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details.mm
@@ -38,7 +38,10 @@ _website = base::SysUTF8ToNSString(nameWithLink.second.spec()); _changePasswordURL = password_manager::CreateChangePasswordUrl(form.url); } - _username = base::SysUTF16ToNSString(form.username_value); + + if (!form.blocked_by_user) { + _username = base::SysUTF16ToNSString(form.username_value); + } if (form.federation_origin.opaque()) { _password = base::SysUTF16ToNSString(form.password_value);
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm index 43c03e8..948236e7 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
@@ -155,8 +155,8 @@ [model addItem:[self websiteItem] toSectionWithIdentifier:SectionIdentifierPassword]; - // Blocked password forms don't have username value. - if ([self.password.username length]) { + // Blocked password forms have username equal to nil. + if (self.password.username != nil) { self.usernameTextItem = [self usernameItem]; [model addItem:self.usernameTextItem toSectionWithIdentifier:SectionIdentifierPassword];
diff --git a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm index c932150..f881d4b 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm
@@ -1482,6 +1482,21 @@ [[EarlGrey selectElementWithMatcher:PasswordDetailUsername()] assertWithMatcher:grey_textFieldValue(@"concrete username")]; + // Empty username should work as well. + [[EarlGrey selectElementWithMatcher:PasswordDetailUsername()] + performAction:grey_replaceText(@"")]; + + [[EarlGrey selectElementWithMatcher:NavigationBarDoneButton()] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:EditConfirmationButton()] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:PasswordDetailUsername()] + assertWithMatcher:grey_textFieldValue(@"")]; + + TapEdit(); + [[EarlGrey selectElementWithMatcher:PasswordDetailUsername()] performAction:grey_replaceText(@"new username")];
diff --git a/ios/chrome/browser/ui/settings/utils/content_setting_backed_boolean.mm b/ios/chrome/browser/ui/settings/utils/content_setting_backed_boolean.mm index ffca1d5..03fdc10a 100644 --- a/ios/chrome/browser/ui/settings/utils/content_setting_backed_boolean.mm +++ b/ios/chrome/browser/ui/settings/utils/content_setting_backed_boolean.mm
@@ -43,8 +43,7 @@ // content_settings::Observer implementation. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) override; + ContentSettingsType content_type) override; private: ContentSettingBackedBoolean* setting_; // weak @@ -59,15 +58,15 @@ void ContentSettingsObserverBridge::OnContentSettingChanged( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, - ContentSettingsType content_type, - const std::string& resource_identifier) { + ContentSettingsType content_type) { // Ignore when it's the ContentSettingBackedBoolean that is changing the // content setting. if (setting_.isModifyingContentSetting) { return; } const ContentSettingsDetails settings_details( - primary_pattern, secondary_pattern, content_type, resource_identifier); + primary_pattern, secondary_pattern, content_type, + /*resource_identifier=*/std::string()); ContentSettingsType settingID = settings_details.type(); // Unfortunately, because the ContentSettingsPolicyProvider doesn't publish // the specific content setting on policy updates, we must refresh on every
diff --git a/media/capture/mojom/video_capture_types.mojom b/media/capture/mojom/video_capture_types.mojom index 67207867..8d4f4c68 100644 --- a/media/capture/mojom/video_capture_types.mojom +++ b/media/capture/mojom/video_capture_types.mojom
@@ -229,6 +229,7 @@ kFuchsiaSysmemInvalidBufferSize, kFuchsiaUnsupportedPixelFormat, kFuchsiaFailedToMapSysmemBuffer, + kCrosHalV3DeviceContextDuplicatedClient, }; enum VideoCaptureFrameDropReason {
diff --git a/media/capture/mojom/video_capture_types_mojom_traits.cc b/media/capture/mojom/video_capture_types_mojom_traits.cc index 03398d0e..d94dd8a 100644 --- a/media/capture/mojom/video_capture_types_mojom_traits.cc +++ b/media/capture/mojom/video_capture_types_mojom_traits.cc
@@ -701,6 +701,9 @@ return media::mojom::VideoCaptureError::kFuchsiaUnsupportedPixelFormat; case media::VideoCaptureError::kFuchsiaFailedToMapSysmemBuffer: return media::mojom::VideoCaptureError::kFuchsiaFailedToMapSysmemBuffer; + case media::VideoCaptureError::kCrosHalV3DeviceContextDuplicatedClient: + return media::mojom::VideoCaptureError:: + kCrosHalV3DeviceContextDuplicatedClient; } NOTREACHED(); return media::mojom::VideoCaptureError::kNone; @@ -1243,6 +1246,11 @@ case media::mojom::VideoCaptureError::kFuchsiaFailedToMapSysmemBuffer: *output = media::VideoCaptureError::kFuchsiaFailedToMapSysmemBuffer; return true; + case media::mojom::VideoCaptureError:: + kCrosHalV3DeviceContextDuplicatedClient: + *output = + media::VideoCaptureError::kCrosHalV3DeviceContextDuplicatedClient; + return true; } NOTREACHED(); return false;
diff --git a/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera.java b/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera.java index 4984a021..1e7af6e6 100644 --- a/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera.java +++ b/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera.java
@@ -509,6 +509,7 @@ public void getPhotoCapabilitiesAsync(long callbackId) { final android.hardware.Camera.Parameters parameters = getCameraParameters(mCamera); if (parameters == null) { + mCamera = null; VideoCaptureJni.get().onGetPhotoCapabilitiesReply( mNativeVideoCaptureDeviceAndroid, VideoCaptureCamera.this, callbackId, null); return; @@ -695,6 +696,7 @@ int fillLightMode, boolean hasTorch, boolean torch, double colorTemperature) { android.hardware.Camera.Parameters parameters = getCameraParameters(mCamera); if (parameters == null) { + mCamera = null; return; } @@ -846,12 +848,14 @@ } mPreviewParameters = getCameraParameters(mCamera); if (mPreviewParameters == null) { + mCamera = null; notifyTakePhotoError(callbackId); return; } android.hardware.Camera.Parameters photoParameters = getCameraParameters(mCamera); if (photoParameters == null) { + mCamera = null; notifyTakePhotoError(callbackId); return; }
diff --git a/media/capture/video/chromeos/camera_device_context.cc b/media/capture/video/chromeos/camera_device_context.cc index 0de1b5c..2de1625 100644 --- a/media/capture/video/chromeos/camera_device_context.cc +++ b/media/capture/video/chromeos/camera_device_context.cc
@@ -4,25 +4,50 @@ #include "media/capture/video/chromeos/camera_device_context.h" +#include "base/strings/string_number_conversions.h" + namespace media { -CameraDeviceContext::CameraDeviceContext( - std::unique_ptr<VideoCaptureDevice::Client> client) - : state_(State::kStopped), - sensor_orientation_(0), - screen_rotation_(0), - client_(std::move(client)) { - DCHECK(client_); +CameraDeviceContext::CameraDeviceContext() + : state_(State::kStopped), sensor_orientation_(0), screen_rotation_(0) { DETACH_FROM_SEQUENCE(sequence_checker_); } CameraDeviceContext::~CameraDeviceContext() = default; +bool CameraDeviceContext::AddClient( + ClientType client_type, + std::unique_ptr<VideoCaptureDevice::Client> client) { + DCHECK(client); + base::AutoLock lock(client_lock_); + if (!clients_.insert({client_type, std::move(client)}).second) { + SetErrorState( + media::VideoCaptureError::kCrosHalV3DeviceContextDuplicatedClient, + FROM_HERE, + std::string("Duplicated client in camera device context: ") + + base::NumberToString(static_cast<uint32_t>(client_type))); + return false; + } + return true; +} + +void CameraDeviceContext::RemoveClient(ClientType client_type) { + base::AutoLock lock(client_lock_); + auto client = clients_.find(client_type); + if (client == clients_.end()) { + return; + } + clients_.erase(client); +} + void CameraDeviceContext::SetState(State state) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); state_ = state; if (state_ == State::kCapturing) { - client_->OnStarted(); + base::AutoLock lock(client_lock_); + for (const auto& client : clients_) { + client.second->OnStarted(); + } } } @@ -36,32 +61,52 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); state_ = State::kError; LOG(ERROR) << reason; - client_->OnError(error, from_here, reason); + base::AutoLock lock(client_lock_); + for (const auto& client : clients_) { + client.second->OnError(error, from_here, reason); + } } void CameraDeviceContext::LogToClient(std::string message) { - client_->OnLog(message); + base::AutoLock lock(client_lock_); + for (const auto& client : clients_) { + client.second->OnLog(message); + } } void CameraDeviceContext::SubmitCapturedVideoCaptureBuffer( + ClientType client_type, VideoCaptureDevice::Client::Buffer buffer, const VideoCaptureFormat& frame_format, base::TimeTicks reference_time, base::TimeDelta timestamp, const VideoFrameMetadata& metadata) { - client_->OnIncomingCapturedBufferExt( + base::AutoLock lock(client_lock_); + auto client = clients_.find(client_type); + if (client == clients_.end()) { + return; + } + + client->second->OnIncomingCapturedBufferExt( std::move(buffer), frame_format, gfx::ColorSpace(), reference_time, timestamp, gfx::Rect(frame_format.frame_size), std::move(metadata)); } void CameraDeviceContext::SubmitCapturedGpuMemoryBuffer( + ClientType client_type, gfx::GpuMemoryBuffer* buffer, const VideoCaptureFormat& frame_format, base::TimeTicks reference_time, base::TimeDelta timestamp) { - client_->OnIncomingCapturedGfxBuffer(buffer, frame_format, - GetCameraFrameRotation(), reference_time, - timestamp); + base::AutoLock lock(client_lock_); + auto client = clients_.find(client_type); + if (client == clients_.end()) { + return; + } + + client->second->OnIncomingCapturedGfxBuffer(buffer, frame_format, + GetCameraFrameRotation(), + reference_time, timestamp); } void CameraDeviceContext::SetSensorOrientation(int sensor_orientation) { @@ -91,13 +136,20 @@ } bool CameraDeviceContext::ReserveVideoCaptureBufferFromPool( + ClientType client_type, gfx::Size size, VideoPixelFormat format, VideoCaptureDevice::Client::Buffer* buffer) { + base::AutoLock lock(client_lock_); + auto client = clients_.find(client_type); + if (client == clients_.end()) { + return false; + } + // Use a dummy frame feedback id as we don't need it. constexpr int kDummyFrameFeedbackId = 0; - auto result = - client_->ReserveOutputBuffer(size, format, kDummyFrameFeedbackId, buffer); + auto result = client->second->ReserveOutputBuffer( + size, format, kDummyFrameFeedbackId, buffer); return result == VideoCaptureDevice::Client::ReserveResult::kSucceeded; }
diff --git a/media/capture/video/chromeos/camera_device_context.h b/media/capture/video/chromeos/camera_device_context.h index b139b0b..b7c64d5 100644 --- a/media/capture/video/chromeos/camera_device_context.h +++ b/media/capture/video/chromeos/camera_device_context.h
@@ -8,15 +8,23 @@ #include <memory> #include <string> +#include "base/containers/flat_map.h" #include "base/sequence_checker.h" +#include "base/synchronization/lock.h" #include "media/capture/video/video_capture_device.h" namespace media { +enum class ClientType : uint32_t { + kPreviewClient = 0, + kVideoClient = 1, +}; + // A class storing the context of a running CameraDeviceDelegate. // // The class is also used to forward/translate events and method calls to a -// given VideoCaptureDevice::Client. +// given VideoCaptureDevice::Client. This class supposes to have two clients +// at most. One is for preview and another is for video. class CAPTURE_EXPORT CameraDeviceContext { public: // The internal state of the running CameraDeviceDelegate. The state @@ -91,11 +99,13 @@ kError, }; - explicit CameraDeviceContext( - std::unique_ptr<VideoCaptureDevice::Client> client); + CameraDeviceContext(); ~CameraDeviceContext(); + bool AddClient(ClientType client_type, + std::unique_ptr<VideoCaptureDevice::Client> client); + void RemoveClient(ClientType client_type); void SetState(State state); State GetState(); @@ -114,6 +124,7 @@ // The buffer would be passed to the renderer process directly through // |client_->OnIncomingCapturedBufferExt|. void SubmitCapturedVideoCaptureBuffer( + ClientType client_type, VideoCaptureDevice::Client::Buffer buffer, const VideoCaptureFormat& frame_format, base::TimeTicks reference_time, @@ -125,7 +136,8 @@ // |client_->OnIncomingCapturedGfxBuffer|, which would perform buffer copy // and/or format conversion to an I420 SharedMemory-based video capture buffer // for client consumption. - void SubmitCapturedGpuMemoryBuffer(gfx::GpuMemoryBuffer* buffer, + void SubmitCapturedGpuMemoryBuffer(ClientType client_type, + gfx::GpuMemoryBuffer* buffer, const VideoCaptureFormat& frame_format, base::TimeTicks reference_time, base::TimeDelta timestamp); @@ -149,10 +161,14 @@ // Reserves a video capture buffer from the buffer pool provided by the video // |client_|. Returns true if the operation succeeds; false otherwise. bool ReserveVideoCaptureBufferFromPool( + ClientType client_type, gfx::Size size, VideoPixelFormat format, VideoCaptureDevice::Client::Buffer* buffer); + // Returns true if there is a client. + bool HasClient(); + private: friend class RequestManagerTest; @@ -170,9 +186,10 @@ // 270. int screen_rotation_; - std::unique_ptr<VideoCaptureDevice::Client> client_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(CameraDeviceContext); + base::Lock client_lock_; + // A map for client type and client instance. + base::flat_map<ClientType, std::unique_ptr<VideoCaptureDevice::Client>> + clients_ GUARDED_BY(client_lock_); }; } // namespace media
diff --git a/media/capture/video/chromeos/camera_device_delegate.cc b/media/capture/video/chromeos/camera_device_delegate.cc index e729188..87804bd2 100644 --- a/media/capture/video/chromeos/camera_device_delegate.cc +++ b/media/capture/video/chromeos/camera_device_delegate.cc
@@ -23,7 +23,6 @@ #include "media/capture/video/blob_utils.h" #include "media/capture/video/chromeos/camera_3a_controller.h" #include "media/capture/video/chromeos/camera_buffer_factory.h" -#include "media/capture/video/chromeos/camera_device_context.h" #include "media/capture/video/chromeos/camera_hal_delegate.h" #include "media/capture/video/chromeos/camera_metadata_utils.h" #include "media/capture/video/chromeos/request_manager.h" @@ -272,11 +271,13 @@ VideoCaptureDeviceDescriptor device_descriptor, scoped_refptr<CameraHalDelegate> camera_hal_delegate, scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner, - CameraAppDeviceImpl* camera_app_device) + CameraAppDeviceImpl* camera_app_device, + ClientType client_type) : device_descriptor_(device_descriptor), camera_hal_delegate_(std::move(camera_hal_delegate)), ipc_task_runner_(std::move(ipc_task_runner)), - camera_app_device_(camera_app_device) {} + camera_app_device_(camera_app_device), + client_type_(client_type) {} CameraDeviceDelegate::~CameraDeviceDelegate() = default; @@ -715,7 +716,7 @@ device_context_, chrome_capture_params_.buffer_type, std::make_unique<CameraBufferFactory>(), base::BindRepeating(&RotateAndBlobify), ipc_task_runner_, - camera_app_device_); + camera_app_device_, client_type_); camera_3a_controller_ = std::make_unique<Camera3AController>( static_metadata_, request_manager_.get(), ipc_task_runner_); device_ops_->Initialize(
diff --git a/media/capture/video/chromeos/camera_device_delegate.h b/media/capture/video/chromeos/camera_device_delegate.h index 54e05ed0..01a37cf 100644 --- a/media/capture/video/chromeos/camera_device_delegate.h +++ b/media/capture/video/chromeos/camera_device_delegate.h
@@ -12,6 +12,7 @@ #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "base/single_thread_task_runner.h" +#include "media/capture/video/chromeos/camera_device_context.h" #include "media/capture/video/chromeos/capture_metadata_dispatcher.h" #include "media/capture/video/chromeos/mojom/camera3.mojom.h" #include "media/capture/video/chromeos/mojom/camera_common.mojom.h" @@ -25,7 +26,6 @@ class Camera3AController; class CameraAppDeviceImpl; -class CameraDeviceContext; class CameraHalDelegate; class RequestManager; @@ -99,7 +99,8 @@ VideoCaptureDeviceDescriptor device_descriptor, scoped_refptr<CameraHalDelegate> camera_hal_delegate, scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner, - CameraAppDeviceImpl* camera_app_device); + CameraAppDeviceImpl* camera_app_device, + ClientType client_type); ~CameraDeviceDelegate() final; @@ -271,6 +272,8 @@ ResultMetadata result_metadata_; gfx::Rect active_array_size_; + ClientType client_type_; + base::WeakPtrFactory<CameraDeviceDelegate> weak_ptr_factory_{this}; DISALLOW_IMPLICIT_CONSTRUCTORS(CameraDeviceDelegate);
diff --git a/media/capture/video/chromeos/camera_device_delegate_unittest.cc b/media/capture/video/chromeos/camera_device_delegate_unittest.cc index 2891ccc..6cf14f0 100644 --- a/media/capture/video/chromeos/camera_device_delegate_unittest.cc +++ b/media/capture/video/chromeos/camera_device_delegate_unittest.cc
@@ -162,7 +162,7 @@ camera_device_delegate_ = std::make_unique<CameraDeviceDelegate>( devices_info[0].descriptor, camera_hal_delegate_, - device_delegate_thread_.task_runner(), nullptr); + device_delegate_thread_.task_runner(), nullptr, client_type_); } void GetNumberOfFakeCameras( @@ -462,15 +462,17 @@ } unittest_internal::NiceMockVideoCaptureClient* ResetDeviceContext() { + client_type_ = ClientType::kPreviewClient; auto mock_client = std::make_unique<unittest_internal::NiceMockVideoCaptureClient>(); auto* client_ptr = mock_client.get(); - device_context_ = - std::make_unique<CameraDeviceContext>(std::move(mock_client)); + device_context_ = std::make_unique<CameraDeviceContext>(); + device_context_->AddClient(client_type_, std::move(mock_client)); return client_ptr; } void ResetDevice() { + device_context_->RemoveClient(client_type_); ASSERT_TRUE(device_delegate_thread_.IsRunning()); ASSERT_TRUE(camera_device_delegate_); ASSERT_TRUE(device_delegate_thread_.task_runner()->DeleteSoon( @@ -516,6 +518,7 @@ base::Thread device_delegate_thread_; std::unique_ptr<CameraDeviceContext> device_context_; + ClientType client_type_; private: base::Thread hal_delegate_thread_;
diff --git a/media/capture/video/chromeos/request_manager.cc b/media/capture/video/chromeos/request_manager.cc index cb64da2..f13fedf9 100644 --- a/media/capture/video/chromeos/request_manager.cc +++ b/media/capture/video/chromeos/request_manager.cc
@@ -18,7 +18,6 @@ #include "base/strings/string_number_conversions.h" #include "base/trace_event/trace_event.h" #include "media/capture/video/chromeos/camera_buffer_factory.h" -#include "media/capture/video/chromeos/camera_device_context.h" #include "media/capture/video/chromeos/camera_metadata_utils.h" #include "media/capture/video/chromeos/video_capture_features_chromeos.h" #include "mojo/public/cpp/platform/platform_handle.h" @@ -43,7 +42,8 @@ std::unique_ptr<CameraBufferFactory> camera_buffer_factory, BlobifyCallback blobify_callback, scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner, - CameraAppDeviceImpl* camera_app_device) + CameraAppDeviceImpl* camera_app_device, + ClientType client_type) : callback_ops_(this, std::move(callback_ops_receiver)), capture_interface_(std::move(capture_interface)), device_context_(device_context), @@ -52,13 +52,15 @@ stream_buffer_manager_( new StreamBufferManager(device_context_, video_capture_use_gmb_, - std::move(camera_buffer_factory))), + std::move(camera_buffer_factory), + client_type)), blobify_callback_(std::move(blobify_callback)), ipc_task_runner_(std::move(ipc_task_runner)), capturing_(false), partial_result_count_(1), first_frame_shutter_time_(base::TimeTicks()), - camera_app_device_(std::move(camera_app_device)) { + camera_app_device_(std::move(camera_app_device)), + client_type_(client_type) { DCHECK(ipc_task_runner_->BelongsToCurrentThread()); DCHECK(callback_ops_.is_bound()); DCHECK(device_context_); @@ -864,7 +866,7 @@ metadata.rotation = VideoRotation::VIDEO_ROTATION_0; } device_context_->SubmitCapturedVideoCaptureBuffer( - std::move(*buffer), format, pending_result.reference_time, + client_type_, std::move(*buffer), format, pending_result.reference_time, pending_result.timestamp, metadata); // |buffer| ownership is transferred to client, so we need to reserve a // new video buffer. @@ -874,7 +876,7 @@ StreamType::kPreviewOutput, buffer_ipc_id); CHECK(gmb); device_context_->SubmitCapturedGpuMemoryBuffer( - gmb, + client_type_, gmb, stream_buffer_manager_->GetStreamCaptureFormat( StreamType::kPreviewOutput), pending_result.reference_time, pending_result.timestamp);
diff --git a/media/capture/video/chromeos/request_manager.h b/media/capture/video/chromeos/request_manager.h index f71699d..f5d4fdad 100644 --- a/media/capture/video/chromeos/request_manager.h +++ b/media/capture/video/chromeos/request_manager.h
@@ -16,6 +16,7 @@ #include "base/optional.h" #include "media/capture/mojom/image_capture.mojom.h" #include "media/capture/video/chromeos/camera_app_device_impl.h" +#include "media/capture/video/chromeos/camera_device_context.h" #include "media/capture/video/chromeos/camera_device_delegate.h" #include "media/capture/video/chromeos/capture_metadata_dispatcher.h" #include "media/capture/video/chromeos/mojom/camera3.mojom.h" @@ -29,7 +30,6 @@ namespace media { class CameraBufferFactory; -class CameraDeviceContext; // The JPEG transport header as defined by Android camera HAL v3 API. The JPEG // transport header is at the end of the blob buffer filled by the HAL. @@ -107,7 +107,8 @@ std::unique_ptr<CameraBufferFactory> camera_buffer_factory, BlobifyCallback blobify_callback, scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner, - CameraAppDeviceImpl* camera_app_device); + CameraAppDeviceImpl* camera_app_device, + ClientType client_type); ~RequestManager() override; // Sets up the stream context and allocate buffers according to the @@ -363,6 +364,8 @@ CameraAppDeviceImpl* camera_app_device_; // Weak. + ClientType client_type_; + base::WeakPtrFactory<RequestManager> weak_ptr_factory_{this}; DISALLOW_IMPLICIT_CONSTRUCTORS(RequestManager);
diff --git a/media/capture/video/chromeos/request_manager_unittest.cc b/media/capture/video/chromeos/request_manager_unittest.cc index 74fad9d..6227b6f3 100644 --- a/media/capture/video/chromeos/request_manager_unittest.cc +++ b/media/capture/video/chromeos/request_manager_unittest.cc
@@ -86,22 +86,28 @@ public: void SetUp() override { quit_ = false; - device_context_ = std::make_unique<CameraDeviceContext>( - std::make_unique<unittest_internal::MockVideoCaptureClient>()); - - request_manager_ = std::make_unique<RequestManager>( - mock_callback_ops_.BindNewPipeAndPassReceiver(), - std::make_unique<MockStreamCaptureInterface>(), device_context_.get(), - VideoCaptureBufferType::kSharedMemory, - std::make_unique<FakeCameraBufferFactory>(), - base::BindRepeating( - [](const uint8_t* buffer, const uint32_t bytesused, - const VideoCaptureFormat& capture_format, - const int rotation) { return mojom::Blob::New(); }), - base::ThreadTaskRunnerHandle::Get(), nullptr); + client_type_ = ClientType::kPreviewClient; + device_context_ = std::make_unique<CameraDeviceContext>(); + if (device_context_->AddClient( + client_type_, + std::make_unique<unittest_internal::MockVideoCaptureClient>())) { + request_manager_ = std::make_unique<RequestManager>( + mock_callback_ops_.BindNewPipeAndPassReceiver(), + std::make_unique<MockStreamCaptureInterface>(), device_context_.get(), + VideoCaptureBufferType::kSharedMemory, + std::make_unique<FakeCameraBufferFactory>(), + base::BindRepeating( + [](const uint8_t* buffer, const uint32_t bytesused, + const VideoCaptureFormat& capture_format, + const int rotation) { return mojom::Blob::New(); }), + base::ThreadTaskRunnerHandle::Get(), nullptr, client_type_); + } } - void TearDown() override { request_manager_.reset(); } + void TearDown() override { + device_context_->RemoveClient(client_type_); + request_manager_.reset(); + } void DoLoop() { run_loop_.reset(new base::RunLoop()); @@ -181,8 +187,10 @@ unittest_internal::MockVideoCaptureClient* GetMockVideoCaptureClient() { EXPECT_NE(nullptr, device_context_); + base::AutoLock lock(device_context_->client_lock_); + EXPECT_TRUE(!device_context_->clients_.empty()); return reinterpret_cast<unittest_internal::MockVideoCaptureClient*>( - device_context_->client_.get()); + device_context_->clients_[client_type_].get()); } std::map<uint32_t, RequestManager::CaptureResult>& GetPendingResults() { @@ -275,7 +283,7 @@ std::unique_ptr<RequestManager> request_manager_; mojo::Remote<cros::mojom::Camera3CallbackOps> mock_callback_ops_; std::unique_ptr<CameraDeviceContext> device_context_; - cros::mojom::Camera3StreamPtr stream; + ClientType client_type_; private: std::unique_ptr<base::RunLoop> run_loop_;
diff --git a/media/capture/video/chromeos/stream_buffer_manager.cc b/media/capture/video/chromeos/stream_buffer_manager.cc index ce40c8e..2cfb2de 100644 --- a/media/capture/video/chromeos/stream_buffer_manager.cc +++ b/media/capture/video/chromeos/stream_buffer_manager.cc
@@ -14,7 +14,6 @@ #include "base/trace_event/trace_event.h" #include "gpu/ipc/common/gpu_memory_buffer_support.h" #include "media/capture/video/chromeos/camera_buffer_factory.h" -#include "media/capture/video/chromeos/camera_device_context.h" #include "media/capture/video/chromeos/camera_metadata_utils.h" #include "media/capture/video/chromeos/pixel_format_utils.h" #include "media/capture/video/chromeos/request_builder.h" @@ -28,10 +27,12 @@ StreamBufferManager::StreamBufferManager( CameraDeviceContext* device_context, bool video_capture_use_gmb, - std::unique_ptr<CameraBufferFactory> camera_buffer_factory) + std::unique_ptr<CameraBufferFactory> camera_buffer_factory, + ClientType client_type) : device_context_(device_context), video_capture_use_gmb_(video_capture_use_gmb), - camera_buffer_factory_(std::move(camera_buffer_factory)) { + camera_buffer_factory_(std::move(camera_buffer_factory)), + client_type_(client_type) { if (video_capture_use_gmb_) { gmb_support_ = std::make_unique<gpu::GpuMemoryBufferSupport>(); } @@ -155,7 +156,8 @@ // We have to reserve a new buffer because the size is different. Buffer rotated_buffer; if (!device_context_->ReserveVideoCaptureBufferFromPool( - format->frame_size, format->pixel_format, &rotated_buffer)) { + client_type_, format->frame_size, format->pixel_format, + &rotated_buffer)) { DLOG(WARNING) << "Failed to reserve video capture buffer"; original_gmb->Unmap(); return std::move(buffer_pair.vcd_buffer); @@ -440,7 +442,7 @@ } Buffer vcd_buffer; if (!device_context_->ReserveVideoCaptureBufferFromPool( - stream_context->buffer_dimension, + client_type_, stream_context->buffer_dimension, stream_context->capture_format.pixel_format, &vcd_buffer)) { DLOG(WARNING) << "Failed to reserve video capture buffer"; return;
diff --git a/media/capture/video/chromeos/stream_buffer_manager.h b/media/capture/video/chromeos/stream_buffer_manager.h index e6e0d56..50ed6a3 100644 --- a/media/capture/video/chromeos/stream_buffer_manager.h +++ b/media/capture/video/chromeos/stream_buffer_manager.h
@@ -18,6 +18,7 @@ #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "base/single_thread_task_runner.h" +#include "media/capture/video/chromeos/camera_device_context.h" #include "media/capture/video/chromeos/camera_device_delegate.h" #include "media/capture/video/chromeos/mojom/camera3.mojom.h" #include "media/capture/video_capture_types.h" @@ -37,7 +38,6 @@ namespace media { class CameraBufferFactory; -class CameraDeviceContext; struct BufferInfo; @@ -51,7 +51,8 @@ StreamBufferManager( CameraDeviceContext* device_context, bool video_capture_use_gmb, - std::unique_ptr<CameraBufferFactory> camera_buffer_factory); + std::unique_ptr<CameraBufferFactory> camera_buffer_factory, + ClientType client_type); ~StreamBufferManager(); void ReserveBuffer(StreamType stream_type); @@ -163,6 +164,8 @@ std::unique_ptr<CameraBufferFactory> camera_buffer_factory_; + ClientType client_type_; + base::WeakPtrFactory<StreamBufferManager> weak_ptr_factory_{this}; DISALLOW_IMPLICIT_CONSTRUCTORS(StreamBufferManager);
diff --git a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc index 6a210da4..7fa73eef 100644 --- a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc +++ b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc
@@ -122,7 +122,8 @@ camera_app_device_(camera_app_device), cleanup_callback_(std::move(cleanup_callback)), power_manager_client_proxy_( - base::MakeRefCounted<PowerManagerClientProxy>()) { + base::MakeRefCounted<PowerManagerClientProxy>()), + client_type_(ClientType::kPreviewClient) { power_manager_client_proxy_->Init(weak_ptr_factory_.GetWeakPtr(), capture_task_runner_, std::move(ui_task_runner)); @@ -152,12 +153,14 @@ return; } capture_params_ = params; - device_context_ = std::make_unique<CameraDeviceContext>(std::move(client)); - - camera_device_delegate_ = std::make_unique<CameraDeviceDelegate>( - device_descriptor_, camera_hal_delegate_, - camera_device_ipc_thread_.task_runner(), camera_app_device_); - OpenDevice(); + device_context_ = std::make_unique<CameraDeviceContext>(); + if (device_context_->AddClient(client_type_, std::move(client))) { + camera_device_delegate_ = std::make_unique<CameraDeviceDelegate>( + device_descriptor_, camera_hal_delegate_, + camera_device_ipc_thread_.task_runner(), camera_app_device_, + client_type_); + OpenDevice(); + } } void VideoCaptureDeviceChromeOSHalv3::StopAndDeAllocate() { @@ -169,6 +172,7 @@ CloseDevice(base::UnguessableToken()); camera_device_ipc_thread_.Stop(); camera_device_delegate_.reset(); + device_context_->RemoveClient(client_type_); device_context_.reset(); }
diff --git a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h index 2e9fea3..9f5a03e 100644 --- a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h +++ b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h
@@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread.h" +#include "media/capture/video/chromeos/camera_device_context.h" #include "media/capture/video/chromeos/display_rotation_observer.h" #include "media/capture/video/video_capture_device.h" #include "media/capture/video/video_capture_device_descriptor.h" @@ -26,7 +27,6 @@ class CameraAppDeviceImpl; class CameraHalDelegate; -class CameraDeviceContext; class CameraDeviceDelegate; // Implementation of VideoCaptureDevice for ChromeOS with CrOS camera HALv3. @@ -102,6 +102,9 @@ scoped_refptr<PowerManagerClientProxy> power_manager_client_proxy_; + // The client type in CameraDeviceContext. + ClientType client_type_; + base::WeakPtrFactory<VideoCaptureDeviceChromeOSHalv3> weak_ptr_factory_{this}; DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureDeviceChromeOSHalv3);
diff --git a/media/capture/video_capture_types.h b/media/capture/video_capture_types.h index 375b6d05..23e1826a 100644 --- a/media/capture/video_capture_types.h +++ b/media/capture/video_capture_types.h
@@ -189,7 +189,8 @@ kFuchsiaSysmemInvalidBufferSize = 120, kFuchsiaUnsupportedPixelFormat = 121, kFuchsiaFailedToMapSysmemBuffer = 122, - kMaxValue = 122 + kCrosHalV3DeviceContextDuplicatedClient = 123, + kMaxValue = 123 }; // WARNING: Do not change the values assigned to the entries. They are used for
diff --git a/media/cast/cast_sender_impl.cc b/media/cast/cast_sender_impl.cc index c31fd52..3ec4fb7 100644 --- a/media/cast/cast_sender_impl.cc +++ b/media/cast/cast_sender_impl.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/callback.h" #include "base/logging.h" #include "base/macros.h" @@ -131,13 +132,15 @@ VLOG(1) << "CastSenderImpl@" << this << "::InitializeVideo()"; + // No feedback callback, since it's ignored for CastSender. video_sender_ = std::make_unique<VideoSender>( cast_environment_, video_config, base::BindRepeating(&CastSenderImpl::OnVideoStatusChange, weak_factory_.GetWeakPtr(), status_change_cb), create_vea_cb, create_video_encode_mem_cb, transport_sender_, base::BindRepeating(&CastSenderImpl::SetTargetPlayoutDelay, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr()), + media::VideoCaptureFeedbackCB()); if (audio_sender_) { DCHECK(audio_sender_->GetTargetPlayoutDelay() == video_sender_->GetTargetPlayoutDelay());
diff --git a/media/cast/sender/video_sender.cc b/media/cast/sender/video_sender.cc index 3674c21..a2960f8 100644 --- a/media/cast/sender/video_sender.cc +++ b/media/cast/sender/video_sender.cc
@@ -93,7 +93,8 @@ const CreateVideoEncodeAcceleratorCallback& create_vea_cb, const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, CastTransport* const transport_sender, - PlayoutDelayChangeCB playout_delay_change_cb) + PlayoutDelayChangeCB playout_delay_change_cb, + media::VideoCaptureFeedbackCB feedback_callback) : FrameSender( cast_environment, transport_sender, @@ -108,6 +109,7 @@ frames_in_encoder_(0), last_bitrate_(0), playout_delay_change_cb_(std::move(playout_delay_change_cb)), + feedback_cb_(feedback_callback), low_latency_mode_(false), last_reported_encoder_utilization_(-1.0), last_reported_lossy_utilization_(-1.0) { @@ -326,10 +328,13 @@ // Key frames are artificially capped to 1.0 because their actual // utilization is atypical compared to the other frames in the stream, and // this can misguide the producer of the input video frames. - video_frame->feedback()->resource_utilization = + VideoFrameFeedback feedback; + feedback.resource_utilization = encoded_frame->dependency == EncodedFrame::KEY ? std::min(1.0, attenuated_utilization) : attenuated_utilization; + if (feedback_cb_) + feedback_cb_.Run(feedback); } SendEncodedFrame(encoder_bitrate, std::move(encoded_frame));
diff --git a/media/cast/sender/video_sender.h b/media/cast/sender/video_sender.h index aa1f9b1e..7bcb6358 100644 --- a/media/cast/sender/video_sender.h +++ b/media/cast/sender/video_sender.h
@@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/time/tick_clock.h" #include "base/time/time.h" +#include "media/base/video_frame_feedback.h" #include "media/cast/cast_config.h" #include "media/cast/cast_sender.h" #include "media/cast/common/rtp_time.h" @@ -45,7 +46,8 @@ const CreateVideoEncodeAcceleratorCallback& create_vea_cb, const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, CastTransport* const transport_sender, - PlayoutDelayChangeCB playout_delay_change_cb); + PlayoutDelayChangeCB playout_delay_change_cb, + media::VideoCaptureFeedbackCB feedback_callback); ~VideoSender() override; @@ -93,6 +95,8 @@ PlayoutDelayChangeCB playout_delay_change_cb_; + media::VideoCaptureFeedbackCB feedback_cb_; + // Indicates we are operating in a mode where the target playout latency is // low for best user experience. When operating in low latency mode, we // prefer dropping frames over increasing target playout time.
diff --git a/media/cast/sender/video_sender_unittest.cc b/media/cast/sender/video_sender_unittest.cc index 9415680d2..f4b4b82 100644 --- a/media/cast/sender/video_sender_unittest.cc +++ b/media/cast/sender/video_sender_unittest.cc
@@ -120,9 +120,21 @@ create_vea_cb, create_video_encode_mem_cb, transport_sender, - base::BindRepeating(&IgnorePlayoutDelayChanges)) {} + base::BindRepeating(&IgnorePlayoutDelayChanges), + base::BindRepeating(&PeerVideoSender::ProcessFeedback, + base::Unretained(this))) {} + using VideoSender::OnReceivedCastFeedback; using VideoSender::OnReceivedPli; + + void ProcessFeedback(const media::VideoFrameFeedback& feedback) { + feedback_ = feedback; + } + + VideoFrameFeedback GetFeedback() { return feedback_; } + + private: + VideoFrameFeedback feedback_; }; class TransportClient : public CastTransport::Client { @@ -567,13 +579,12 @@ EXPECT_EQ(nullptr, video_sender_->CreateVideoFrameFactory().get()); } -TEST_F(VideoSenderTest, PopulatesResourceUtilizationInFrameFeedback) { +TEST_F(VideoSenderTest, ReportsResourceUtilizationInCallback) { InitEncoder(false, true); ASSERT_EQ(STATUS_INITIALIZED, operational_status_); for (int i = 0; i < 3; ++i) { scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); - EXPECT_LE(video_frame->feedback()->resource_utilization, 0.0); const base::TimeTicks reference_time = testing_clock_.NowTicks(); video_sender_->InsertRawVideoFrame(video_frame, reference_time); @@ -586,7 +597,7 @@ // Check that the resource_utilization value is set and non-negative. Don't // check for specific values because they are dependent on real-world CPU // encode time, which can vary across test runs. - double utilization = video_frame->feedback()->resource_utilization; + double utilization = video_sender_->GetFeedback().resource_utilization; EXPECT_LE(0.0, utilization); if (i == 0) EXPECT_GE(1.0, utilization); // Key frames never exceed 1.0.
diff --git a/net/BUILD.gn b/net/BUILD.gn index 63d21c0..47cd72a1 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -928,7 +928,6 @@ "quic/quic_crypto_client_stream_factory.h", "quic/quic_event_logger.cc", "quic/quic_event_logger.h", - "quic/quic_flags_list.h", "quic/quic_http3_logger.cc", "quic/quic_http3_logger.h", "quic/quic_http_stream.cc", @@ -1034,7 +1033,6 @@ "spdy/platform/impl/spdy_bug_tracker_impl.h", "spdy/platform/impl/spdy_containers_impl.h", "spdy/platform/impl/spdy_estimate_memory_usage_impl.h", - "spdy/platform/impl/spdy_flags_impl.cc", "spdy/platform/impl/spdy_flags_impl.h", "spdy/platform/impl/spdy_logging_impl.h", "spdy/platform/impl/spdy_macros_impl.h",
diff --git a/net/dns/dns_test_util.cc b/net/dns/dns_test_util.cc index 0de0f38..1f1c4cb 100644 --- a/net/dns/dns_test_util.cc +++ b/net/dns/dns_test_util.cc
@@ -151,7 +151,9 @@ DnsResponse BuildTestDnsResponse( std::string name, uint16_t type, - const std::vector<DnsResourceRecord>& answers) { + const std::vector<DnsResourceRecord>& answers, + const std::vector<DnsResourceRecord>& authority, + const std::vector<DnsResourceRecord>& additional) { DCHECK(!name.empty()); std::string dns_name; @@ -159,8 +161,9 @@ base::Optional<DnsQuery> query(base::in_place, 0, std::move(dns_name), type); return DnsResponse(0, true /* is_authoritative */, answers, - {} /* authority_records */, {} /* additional_records */, - query, dns_protocol::kRcodeNOERROR /* rcode */, + authority /* authority_records */, + additional /* additional_records */, query, + dns_protocol::kRcodeNOERROR /* rcode */, false /* validate_answers_match_query */); }
diff --git a/net/dns/dns_test_util.h b/net/dns/dns_test_util.h index 7c59ef9..9bd91a74 100644 --- a/net/dns/dns_test_util.h +++ b/net/dns/dns_test_util.h
@@ -218,9 +218,12 @@ const std::map<uint16_t, std::string>& params, base::TimeDelta ttl = base::TimeDelta::FromDays(1)); -DnsResponse BuildTestDnsResponse(std::string name, - uint16_t type, - const std::vector<DnsResourceRecord>& answers); +DnsResponse BuildTestDnsResponse( + std::string name, + uint16_t type, + const std::vector<DnsResourceRecord>& answers, + const std::vector<DnsResourceRecord>& authority = {}, + const std::vector<DnsResourceRecord>& additional = {}); DnsResponse BuildTestDnsAddressResponse(std::string name, const IPAddress& ip,
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc index 5df4ffc9..032734f8 100644 --- a/net/dns/host_resolver_manager.cc +++ b/net/dns/host_resolver_manager.cc
@@ -462,6 +462,36 @@ net_log.AddEntry(type, phase, [&] { return results.NetLogParams(); }); } +void SaveMetricsForAdditionalHttpsRecord(const RecordParsed& record, + bool is_unsolicited) { + const HttpsRecordRdata* rdata = record.rdata<HttpsRecordRdata>(); + + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. + enum class UnsolicitedHttpsRecordStatus { + kMalformed = 0, + kAlias = 1, + kService = 2, + kMaxValue = kService + } status; + + if (!rdata || rdata->IsMalformed()) { + status = UnsolicitedHttpsRecordStatus::kMalformed; + } else if (rdata->IsAlias()) { + status = UnsolicitedHttpsRecordStatus::kAlias; + } else { + status = UnsolicitedHttpsRecordStatus::kService; + } + + if (is_unsolicited) { + UMA_HISTOGRAM_ENUMERATION("Net.DNS.DnsTask.AdditionalHttps.Unsolicited", + status); + } else { + UMA_HISTOGRAM_ENUMERATION("Net.DNS.DnsTask.AdditionalHttps.Requested", + status); + } +} + } // namespace //----------------------------------------------------------------------------- @@ -1712,6 +1742,16 @@ out_response_ttl->reset(); } + for (unsigned i = 0; i < response->additional_answer_count(); ++i) { + std::unique_ptr<const RecordParsed> record = + RecordParsed::CreateFrom(&parser, base::Time::Now()); + if (record && record->klass() == dns_protocol::kClassIN && + record->type() == dns_protocol::kTypeHttps) { + bool is_unsolicited = filter_dns_type != dns_protocol::kTypeHttps; + SaveMetricsForAdditionalHttpsRecord(*record, is_unsolicited); + } + } + return DnsResponse::DNS_PARSE_OK; }
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc index e36a523e..cdfededb 100644 --- a/net/dns/host_resolver_manager_unittest.cc +++ b/net/dns/host_resolver_manager_unittest.cc
@@ -9103,6 +9103,39 @@ EXPECT_EQ(resolve_context_->host_cache()->size(), 0u); } +TEST_F(HostResolverManagerDnsTest, HttpsQuery_AdditionalRecords) { + const std::string kName = "https.test"; + + MockDnsClientRuleList rules; + std::vector<DnsResourceRecord> records = { + BuildTestHttpsAliasRecord(kName, "alias.test")}; + std::vector<DnsResourceRecord> additional = { + BuildTestHttpsServiceRecord(kName, 3u, "service1.test", {}), + BuildTestHttpsServiceRecord(kName, 2u, "service2.test", {})}; + rules.emplace_back(kName, dns_protocol::kTypeHttps, false /* secure */, + MockDnsClientRule::Result(BuildTestDnsResponse( + kName, dns_protocol::kTypeHttps, records, + {} /* authority */, additional)), + false /* delay */); + + CreateResolver(); + UseMockDnsClient(CreateValidDnsConfig(), std::move(rules)); + + HostResolver::ResolveHostParameters parameters; + parameters.dns_query_type = DnsQueryType::HTTPS; + + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair(kName, 108), NetworkIsolationKey(), NetLogWithSource(), + parameters, resolve_context_.get(), resolve_context_->host_cache())); + // Experimental type, so does not affect overall result. + EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); + EXPECT_FALSE(response.request()->GetAddressResults()); + EXPECT_FALSE(response.request()->GetHostnameResults()); + EXPECT_FALSE(response.request()->GetTextResults()); + // Results never saved when overall result not OK. + EXPECT_FALSE(response.request()->GetExperimentalResultsForTesting()); +} + TEST_F(HostResolverManagerDnsTest, HttpsQuery_WrongType) { const std::string kName = "https.test"; @@ -9703,6 +9736,40 @@ EXPECT_FALSE(response.request()->GetExperimentalResultsForTesting()); } +TEST_F(HostResolverManagerDnsTest, UnsolicitedHttps) { + const char kName[] = "unsolicited.test"; + + MockDnsClientRuleList rules; + std::vector<DnsResourceRecord> records = { + BuildTestAddressRecord(kName, IPAddress(1, 2, 3, 4))}; + std::vector<DnsResourceRecord> additional = { + BuildTestHttpsAliasRecord(kName, "alias.test")}; + rules.emplace_back(kName, dns_protocol::kTypeA, true /* secure */, + MockDnsClientRule::Result(BuildTestDnsResponse( + kName, dns_protocol::kTypeA, records, + {} /* authority */, additional)), + false /* delay */); + rules.emplace_back(kName, dns_protocol::kTypeAAAA, true /* secure */, + MockDnsClientRule::Result(MockDnsClientRule::OK), + false /* delay */); + + CreateResolver(); + UseMockDnsClient(CreateValidDnsConfig(), std::move(rules)); + DnsConfigOverrides overrides; + overrides.secure_dns_mode = SecureDnsMode::kSecure; + resolver_->SetDnsConfigOverrides(overrides); + + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair(kName, 108), NetworkIsolationKey(), NetLogWithSource(), + base::nullopt, resolve_context_.get(), resolve_context_->host_cache())); + EXPECT_THAT(response.result_error(), IsOk()); + EXPECT_TRUE(response.request()->GetAddressResults()); + EXPECT_FALSE(response.request()->GetTextResults()); + EXPECT_FALSE(response.request()->GetHostnameResults()); + // Unsolicited records not included in results. + EXPECT_FALSE(response.request()->GetExperimentalResultsForTesting()); +} + class HostResolverManagerDnsTestIntegrity : public HostResolverManagerDnsTest { public: HostResolverManagerDnsTestIntegrity()
diff --git a/net/quic/platform/impl/quic_flags_impl.cc b/net/quic/platform/impl/quic_flags_impl.cc index e78398f..c92a7156 100644 --- a/net/quic/platform/impl/quic_flags_impl.cc +++ b/net/quic/platform/impl/quic_flags_impl.cc
@@ -22,7 +22,7 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #define QUIC_FLAG(flag, value) bool flag = value; -#include "net/quic/quic_flags_list.h" +#include "net/third_party/quiche/src/quic/core/quic_flags_list.h" #undef QUIC_FLAG #define DEFINE_QUIC_PROTOCOL_FLAG_SINGLE_VALUE(type, flag, value, doc) \ @@ -309,7 +309,7 @@ SetQuicFlagByName_bool(&flag, value); \ return; \ } -#include "net/quic/quic_flags_list.h" +#include "net/third_party/quiche/src/quic/core/quic_flags_list.h" #undef QUIC_FLAG #define QUIC_PROTOCOL_FLAG(type, flag, ...) \
diff --git a/net/quic/platform/impl/quic_flags_impl.h b/net/quic/platform/impl/quic_flags_impl.h index d9ba806..c1a2eee 100644 --- a/net/quic/platform/impl/quic_flags_impl.h +++ b/net/quic/platform/impl/quic_flags_impl.h
@@ -17,7 +17,7 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #define QUIC_FLAG(flag, value) QUIC_EXPORT_PRIVATE extern bool flag; -#include "net/quic/quic_flags_list.h" +#include "net/third_party/quiche/src/quic/core/quic_flags_list.h" #undef QUIC_FLAG #define QUIC_PROTOCOL_FLAG(type, flag, ...) \
diff --git a/net/quic/platform/impl/quic_test_impl.cc b/net/quic/platform/impl/quic_test_impl.cc index 1b5545e..859012f 100644 --- a/net/quic/platform/impl/quic_test_impl.cc +++ b/net/quic/platform/impl/quic_test_impl.cc
@@ -9,13 +9,13 @@ QuicFlagSaverImpl::QuicFlagSaverImpl() { #define QUIC_FLAG(flag, value) saved_##flag##_ = flag; -#include "net/quic/quic_flags_list.h" +#include "net/third_party/quiche/src/quic/core/quic_flags_list.h" #undef QUIC_FLAG } QuicFlagSaverImpl::~QuicFlagSaverImpl() { #define QUIC_FLAG(flag, value) flag = saved_##flag##_; -#include "net/quic/quic_flags_list.h" +#include "net/third_party/quiche/src/quic/core/quic_flags_list.h" #undef QUIC_FLAG }
diff --git a/net/quic/platform/impl/quic_test_impl.h b/net/quic/platform/impl/quic_test_impl.h index ed326f0..8ce1924 100644 --- a/net/quic/platform/impl/quic_test_impl.h +++ b/net/quic/platform/impl/quic_test_impl.h
@@ -22,7 +22,7 @@ private: #define QUIC_FLAG(flag, value) bool saved_##flag##_; -#include "net/quic/quic_flags_list.h" +#include "net/third_party/quiche/src/quic/core/quic_flags_list.h" #undef QUIC_FLAG }; @@ -35,7 +35,7 @@ << "Flag set to an unexpected value. A prior test is likely " \ << "setting a flag without using a QuicFlagSaver. Use QuicTest to " \ "avoid this issue."; -#include "net/quic/quic_flags_list.h" +#include "net/third_party/quiche/src/quic/core/quic_flags_list.h" #undef QUIC_FLAG } };
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h deleted file mode 100644 index e27f543..0000000 --- a/net/quic/quic_flags_list.h +++ /dev/null
@@ -1,335 +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. - -// This file intentionally does not have header guards, it's included -// inside a macro to generate values. The following line silences a -// presubmit warning that would otherwise be triggered by this: -// no-include-guard-because-multiply-included -// NOLINT(build/header_guard) - -// This file contains the list of QUIC reloadable and restart flags. - -// If true, require handshake confirmation for QUIC connections, functionally -// disabling 0-rtt handshakes. -// TODO(rtenneti): Enable this flag after CryptoServerTest's are fixed. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation, false) - -// When true, defaults to BBR congestion control instead of Cubic. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr, false) - -// If true, use BBRv2 as the default congestion controller. -// Takes precedence over --quic_default_to_bbr. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr_v2, false) - -// When true, set the initial congestion control window from connection options -// in QuicSentPacketManager rather than TcpCubicSenderBytes. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_unified_iw_options, false) - -// If true, QUIC offload pacing when using USPS as egress method. -QUIC_FLAG(FLAGS_quic_restart_flag_quic_offload_pacing_to_usps2, false) - -// If true, stop resetting ideal_next_packet_send_time_ in pacing sender. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, - false) - -// When the STMP connection option is sent by the client, timestamps in the QUIC -// ACK frame are sent and processed. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_timestamps, false) - -// If true and using Leto for QUIC shared-key calculations, GFE will react to a -// failure to contact Leto by sending a REJ containing a fallback ServerConfig, -// allowing the client to continue the handshake. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_send_quic_fallback_server_config_on_leto_error, - false) - -// If true, GFE will not request private keys when fetching QUIC ServerConfigs -// from Leto. -QUIC_FLAG(FLAGS_quic_restart_flag_dont_fetch_quic_private_keys_from_leto, false) - -// If true, set burst token to 2 in cwnd bootstrapping experiment. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_bursts, false) - -// If true, uses conservative cwnd gain and pacing gain. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_cwnd_and_pacing_gains, - false) - -// If true, allow client to enable BBRv2 on server via connection option 'B2ON'. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_allow_client_enabled_bbr_v2, false) - -// If true, disable QUIC version Q043. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q043, false) - -// If true, disable QUIC version Q046. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q046, false) - -// If true, disable QUIC version Q050. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q050, false) - -// A testonly reloadable flag that will always default to false. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_false, false) - -// A testonly reloadable flag that will always default to true. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_true, true) - -// A testonly restart flag that will always default to false. -QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_false, false) - -// A testonly restart flag that will always default to true. -QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_true, true) - -// When true, ensure the ACK delay is never less than the alarm granularity when -// ACK decimation is enabled. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_ack_delay_alarm_granularity, false) - -// If true, disable QUIC version h3-27. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_draft_27, true) - -// If true, QUIC BBRv2\'s PROBE_BW mode will not reduce cwnd below -// BDP+ack_height. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_avoid_too_low_probe_bw_cwnd, - false) - -// When true, the 1RTT and 2RTT connection options decrease the number of round -// trips in BBRv2 STARTUP without a 25% bandwidth increase to 1 or 2 round trips -// respectively. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_fewer_startup_round_trips, false) - -// If true, support for IETF QUIC 0-rtt is enabled. -QUIC_FLAG(FLAGS_quic_restart_flag_quic_enable_zero_rtt_for_tls_v2, true) - -// If true, default on PTO which unifies TLP + RTO loss recovery. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_on_pto, false) - -// If true, disable QUIC version h3-T050. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_t050, true) - -// If true, default-enable 5RTO blachole detection. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_quic_default_enable_5rto_blackhole_detection2, - true) - -// If true, disable QUIC version h3-29. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_draft_29, false) - -// If true, record the received min_ack_delay in transport parameters to QUIC -// config. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_record_received_min_ack_delay, true) - -// If true, disable blackhole detection on server side. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_server_blackhole_detection, - false) - -// If true, QUIC will default enable MTU discovery, with a target of 1450 bytes. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_mtu_discovery_at_server, false) - -// If true, while reading an IETF quic packet, start peer migration immediately -// when detecting the existence of any non-probing frame instead of at the end -// of the packet. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_start_peer_migration_earlier, false) - -// If true, QuicStream::kDefaultUrgency is 3, otherwise 1. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_http3_new_default_urgency_value, true) - -// If true, send PATH_RESPONSE upon receiving PATH_CHALLENGE regardless -// of perspective. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_path_response, false) - -// If true, when switching from BBR to BBR2, use BBR's CWND as the initial CWND. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_copy_bbr_cwnd_to_bbr2, true) - -// If true, send the lowest stream ID that can be retried by the client in a -// GOAWAY frame. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_http3_goaway_stream_id, true) - -// If true, close connection if writer is still blocked when OnCanWrite is -// called. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_quic_close_connection_in_on_can_write_with_blocked_writer, - true) - -// If true, include stream information in idle timeout connection close detail. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_add_stream_info_to_idle_close_detail, - true) - -// If true, use IETF QUIC application error codes in STOP_SENDING frames. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_stop_sending_uses_ietf_error_code, - true) - -// If true, QuicSpdySession's destructor won't need to do cleanup. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_clean_up_spdy_session_destructor, - true) - -// If true, discard INITIAL packet if the key has been dropped. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_quic_discard_initial_packet_with_key_dropped, - true) - -// If true, disable QUIC version h3-T051. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_t051, false) - -// If true, make sure there is pending timer credit when trying to PTO -// retransmit any packets. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_pto_pending_timer_count, true) - -// If true, QUIC connection will pass sent packet information to the debug -// visitor after a packet is recorded as sent in sent packet manager. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_quic_give_sent_packet_to_debug_visitor_after_sent, - true) - -// If true, abort async QPACK header decompression in QuicSpdyStream::OnClose(). -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_abort_qpack_on_stream_close, true) - -// If true, do not arm PTO for application data until handshake confirmed. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_arm_pto_for_application_data, - true) - -// If true, fix a potential out of order sending caused by handshake gets -// confirmed while the coalescer is not empty. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_out_of_order_sending2, true) - -// If true, remove processed undecryptable packets. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_undecryptable_packets2, true) - -// If true, QUIC BBRv2 will use inflight byte after congestion event to detect -// queuing during PROBE_UP. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_quic_bbr2_use_post_inflight_to_detect_queuing, - true) - -// If true, QUIC BBRv2 will use 15% inflight_hi headroom, which is the default -// for TCP. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_use_tcp_inflight_hi_headroom, - true) - -// If true, HTTP/3 will treat HTTP/2 specific SETTINGS as error. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_reject_spdy_settings, true) - -// If true, for IETF QUIC, uses 2 * RTTVAR when calculating PTO delay. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_2_rttvar, true) - -// Deallocate data in QuicMessageFrame right after the corresponding packet is -// sent. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_deallocate_message_right_after_sent, - true) - -// If true, drop initial keys at the end of writing and unify the fixes for -// missing initial keys. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_missing_initial_keys2, true) - -// If true, check whether framer has the right key before writing data. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_check_keys_before_writing, true) - -// If true, received error codes larger than QUIC_LAST_ERROR are preserved. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_do_not_clip_received_error_code, - false) - -// If true, HTTP/3 sesions will report error and close connection upon receiving -// HTTP/2 only frames. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_reject_spdy_frames, true) - -// If true, QuicConnection will initialize its self address to the self address -// of the first received packet, for all server connections and client -// connections that know its own address. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_connection_set_initial_self_address, - true) - -// If true, let QUIC connection handle PINGs instead of going through session. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_let_connection_handle_pings, true) - -// If true, use http2::HuffmanEncodeFast() instead of HuffmanEncode() and -// eliminate one string copy for QPACK encoding used in IETF QUIC. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_fast_huffman_encoder, true) - -// When true, QUIC+TLS versions will support key updates. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_key_update_supported, true) - -// If true, address is validated by successfully processing a HANDSHAKE or 1-RTT -// packet. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_address_validation, true) - -// If true, QuicStream will explicitly specify which RST_STREAM, STOP_SENDING -// frame to send. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_split_up_send_rst, false) - -// If true, send HTTP/3 GOAWAY frame when sending CONNECTION_CLOSE. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_goaway_with_connection_close, - false) - -// If true, ack frequency frame can be sent from server to client. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_can_send_ack_frequency, true) - -// If true, QUIC BBRv2 will support NetworkParams.max_initial_congestion_window -// when bootstrapping cwnd. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_support_max_bootstrap_cwnd, true) - -// If true, QUIC BBR2 will not exit STARTUP on excessive loss, if there was -// enough bandwidth growth in round. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_quic_bbr2_no_exit_startup_on_loss_with_bw_growth, - true) - -// Honor the AEAD confidentiality and integrity limits by initiating key update -// (if enabled) and/or closing the connection, as necessary. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_aead_limits, true) - -// If true, try to process undecryptable packets at the end of -// TlsServerHandshaker::DecryptCallback, if it is callback is run -// asynchronously. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_quic_process_undecryptable_packets_after_async_decrypt_callback, - true) - -// When true, QUIC server will send version negotiation packets even if the -// original connection ID was under 64bits in length. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_quic_send_version_negotiation_for_short_connection_ids, - false) - -// If true, use one of the 12 QPACK encoder stream error codes and 5 QPACK -// decoder stream error codes and QUIC_INTERNAL_ERROR instead of the two generic -// ones. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_granular_qpack_error_codes, false) - -// When true, the server delays its Initial ACK-only packets the full -// max_ack_delay. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_delay_initial_ack, false) - -// If true, session tickets will always be enabled in QUIC. -QUIC_FLAG(FLAGS_quic_restart_flag_quic_session_tickets_always_enabled, false) - -// If true and B2SL connection option is set, when QUIC BBR2 exits STARTUP due -// to loss, it will set the inflight_hi to the max of bdp and -// max_bytes_delivered_in_round. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_quic_bbr2_startup_loss_exit_use_max_delivered, - false) - -// If true, fix QuicSession::WillingAndAbleToWrite to check write keys when -// using CRYPTO frames. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_willing_and_able_to_write2, true) - -// If true, do not send control frames before encryption is established. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_encrypted_control_frames, false) - -// If true, use WriteOrBufferDataAtLevel to send crypto data. Existing -// WriteOrBufferData is used to send application data. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_write_or_buffer_data_at_level, - false) - -// When true, use quic::CertificateView to extract X.509 subjects from -// certificates. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_quic_extract_x509_subject_using_certificate_view, - false) - -// If true, use ScopedEncryptionLevelContext when sending data. -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_encryption_level_context, false) - -// If true, replace std::deque with circular_deque for unacked_packets. -QUIC_FLAG( - FLAGS_quic_reloadable_flag_quic_use_circular_deque_for_unacked_packets, - false)
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc index 0b3b5a9..82e9f2f 100644 --- a/net/quic/quic_network_transaction_unittest.cc +++ b/net/quic/quic_network_transaction_unittest.cc
@@ -8643,7 +8643,7 @@ packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true, false, VersionUsesHttp3(version_.transport_version) - ? quic::QuicStream::DefaultUrgency() + ? quic::QuicStream::kDefaultUrgency : ConvertRequestPriorityToQuicPriority( HttpProxyConnectJob::kH2QuicTunnelPriority), client_maker.ConnectRequestHeaders("mail.example.org:443"), 0, @@ -8697,7 +8697,7 @@ packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false, false, VersionUsesHttp3(version_.transport_version) - ? quic::QuicStream::DefaultUrgency() + ? quic::QuicStream::kDefaultUrgency : ConvertRequestPriorityToQuicPriority( HttpProxyConnectJob::kH2QuicTunnelPriority), std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0), @@ -9334,7 +9334,7 @@ packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true, false, VersionUsesHttp3(version_.transport_version) - ? quic::QuicStream::DefaultUrgency() + ? quic::QuicStream::kDefaultUrgency : ConvertRequestPriorityToQuicPriority( HttpProxyConnectJob::kH2QuicTunnelPriority), ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
diff --git a/net/quic/quic_test_packet_maker.cc b/net/quic/quic_test_packet_maker.cc index b9d30f11..d9495be 100644 --- a/net/quic/quic_test_packet_maker.cc +++ b/net/quic/quic_test_packet_maker.cc
@@ -559,7 +559,7 @@ if (quic::VersionUsesHttp3(version_.transport_version)) { MaybeAddHttp3SettingsFrames(); - if (priority != quic::QuicStream::DefaultUrgency()) { + if (priority != quic::QuicStream::kDefaultUrgency) { std::string priority_data = GenerateHttp3PriorityData(priority, stream_id); AddQuicStreamFrame(2, false, priority_data); @@ -607,7 +607,7 @@ if (quic::VersionUsesHttp3(version_.transport_version)) { MaybeAddHttp3SettingsFrames(); - if (priority != quic::QuicStream::DefaultUrgency()) { + if (priority != quic::QuicStream::kDefaultUrgency) { std::string priority_data = GenerateHttp3PriorityData(priority, stream_id); AddQuicStreamFrame(2, false, priority_data); @@ -646,7 +646,7 @@ if (quic::VersionUsesHttp3(version_.transport_version)) { MaybeAddHttp3SettingsFrames(); - if (priority != quic::QuicStream::DefaultUrgency()) { + if (priority != quic::QuicStream::kDefaultUrgency) { std::string priority_data = GenerateHttp3PriorityData(priority, stream_id); AddQuicStreamFrame(2, false, priority_data); @@ -799,7 +799,7 @@ return BuildPacket(); } - if (priority != quic::QuicStream::DefaultUrgency()) { + if (priority != quic::QuicStream::kDefaultUrgency) { std::string priority_data = GenerateHttp3PriorityData(priority, id); AddQuicStreamFrame(2, false, priority_data); } @@ -836,7 +836,7 @@ return BuildPacket(); } - if (priority != quic::QuicStream::DefaultUrgency()) { + if (priority != quic::QuicStream::kDefaultUrgency) { std::string priority_data = GenerateHttp3PriorityData(priority, id); AddQuicStreamFrame(2, false, priority_data); }
diff --git a/net/spdy/platform/impl/spdy_flags_impl.cc b/net/spdy/platform/impl/spdy_flags_impl.cc deleted file mode 100644 index ca291c6..0000000 --- a/net/spdy/platform/impl/spdy_flags_impl.cc +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/spdy/platform/impl/spdy_flags_impl.h" - -// If true, use http2::HuffmanSize() instead of -// spdy::HpackHuffmanTable::EncodedSize() and http2::HuffmanEncodeFast() -// instead of spdy::HpackHuffmanTable::EncodeString() for HPACK encoding used -// in HTTP/2 and Google QUIC (not IETF QUIC). -bool http2_use_fast_huffman_encoder = true; - -namespace spdy {} // namespace spdy
diff --git a/net/spdy/platform/impl/spdy_flags_impl.h b/net/spdy/platform/impl/spdy_flags_impl.h index ddfd969..88641073 100644 --- a/net/spdy/platform/impl/spdy_flags_impl.h +++ b/net/spdy/platform/impl/spdy_flags_impl.h
@@ -6,26 +6,18 @@ #define NET_SPDY_PLATFORM_IMPL_SPDY_FLAGS_IMPL_H_ #include "net/base/net_export.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -NET_EXPORT_PRIVATE extern bool http2_use_fast_huffman_encoder; - -inline bool GetSpdyReloadableFlagImpl(bool flag) { - return flag; -} +#define GetSpdyReloadableFlagImpl GetQuicReloadableFlagImpl #define SPDY_CODE_COUNT_IMPL(name) \ do { \ } while (0) -namespace spdy { - -inline bool GetSpdyRestartFlagImpl(bool flag) { - return flag; -} +#define GetSpdyRestartFlagImpl GetQuicRestartFlagImpl #define SPDY_CODE_COUNT_N_IMPL(name, instance, total) \ do { \ } while (0) -} // namespace spdy #endif // NET_SPDY_PLATFORM_IMPL_SPDY_FLAGS_IMPL_H_
diff --git a/remoting/host/win/BUILD.gn b/remoting/host/win/BUILD.gn index 97135b8..4bc787d 100644 --- a/remoting/host/win/BUILD.gn +++ b/remoting/host/win/BUILD.gn
@@ -158,6 +158,9 @@ "etw_trace_consumer.h", "etw_trace_controller.cc", "etw_trace_controller.h", + "event_trace_data.cc", + "event_trace_data.h", + "event_trace_data_unittest.cc", "launch_native_messaging_host_process.cc", "launch_native_messaging_host_process.h", "rdp_client_unittest.cc", @@ -371,6 +374,8 @@ "etw_trace_consumer.h", "etw_trace_controller.cc", "etw_trace_controller.h", + "event_trace_data.cc", + "event_trace_data.h", "host_service.cc", "host_service.h", "launch_native_messaging_host_process.cc",
diff --git a/remoting/host/win/event_trace_data.cc b/remoting/host/win/event_trace_data.cc new file mode 100644 index 0000000..b2be658 --- /dev/null +++ b/remoting/host/win/event_trace_data.cc
@@ -0,0 +1,99 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/host/win/event_trace_data.h" + +#include "base/check.h" +#include "base/logging.h" +#include "base/logging_win.h" +#include "base/notreached.h" + +namespace remoting { + +namespace { + +logging::LogSeverity EventTraceLevelToSeverity(uint8_t level) { + switch (level) { + case TRACE_LEVEL_NONE: + NOTREACHED(); + return logging::LOG_ERROR; + case TRACE_LEVEL_FATAL: + return logging::LOG_FATAL; + case TRACE_LEVEL_ERROR: + return logging::LOG_ERROR; + case TRACE_LEVEL_WARNING: + return logging::LOG_WARNING; + case TRACE_LEVEL_INFORMATION: + return logging::LOG_INFO; + default: + // These represent VLOG verbosity levels. + return TRACE_LEVEL_INFORMATION - level; + } +} + +} // namespace + +EventTraceData::EventTraceData() = default; + +EventTraceData::EventTraceData(EventTraceData&&) = default; + +EventTraceData& EventTraceData::operator=(EventTraceData&&) = default; + +EventTraceData::~EventTraceData() = default; + +EventTraceData EventTraceData::Create(EVENT_TRACE* event) { + EventTraceData data; + + data.event_type = event->Header.Class.Type; + + data.severity = EventTraceLevelToSeverity(event->Header.Class.Level); + data.process_id = event->Header.ProcessId; + data.thread_id = event->Header.ThreadId; + + FILETIME event_time = {}; + event_time.dwLowDateTime = event->Header.TimeStamp.LowPart; + event_time.dwHighDateTime = event->Header.TimeStamp.HighPart; + base::Time::FromFileTime(event_time).LocalExplode(&data.time_stamp); + + // Parse the MofData. The structure is defined in //base/logging_win.cc. + // - For LOG_MESSAGE events, the MofData buffer just contains the message. + // - For LOG_FULL_MESSAGE events, the MofData buffer is comprised of 5 fields + // which must be parsed (or skipped) in sequence. + if (data.event_type == logging::LOG_MESSAGE) { + data.message.assign(reinterpret_cast<const char*>(event->MofData), + event->MofLength); + } else if (data.event_type == logging::LOG_MESSAGE_FULL) { + const uint8_t* mof_data = reinterpret_cast<const uint8_t*>(event->MofData); + uint32_t offset = 0; + + // Read the size, skip past the stack info, and move the cursor. + DWORD stack_depth = *reinterpret_cast<const DWORD*>(mof_data); + int bytes_to_skip = sizeof(DWORD) + stack_depth * sizeof(intptr_t); + offset += bytes_to_skip; + + // Read the line info and move the cursor. + data.line = *reinterpret_cast<const int32_t*>(mof_data + offset); + offset += sizeof(int32_t); + + // Read the file info and move the cursor. + const char* file_info = reinterpret_cast<const char*>(mof_data + offset); + size_t str_len = strnlen_s(file_info, event->MofLength - offset); + data.file.assign(file_info); + offset += (str_len + 1); + + // Read the message and move the cursor. + const char* message = reinterpret_cast<const char*>(mof_data + offset); + str_len = strnlen_s(message, event->MofLength - offset); + data.message.assign(message); + offset += (str_len + 1); + + DCHECK_EQ(event->MofLength, offset); + } else { + NOTREACHED() << "Unknown event type: " << data.event_type; + } + + return data; +} + +} // namespace remoting
diff --git a/remoting/host/win/event_trace_data.h b/remoting/host/win/event_trace_data.h new file mode 100644 index 0000000..a76ae310 --- /dev/null +++ b/remoting/host/win/event_trace_data.h
@@ -0,0 +1,64 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_HOST_WIN_EVENT_TRACE_DATA_H_ +#define REMOTING_HOST_WIN_EVENT_TRACE_DATA_H_ + +#include <stdint.h> + +#include <string> + +#include "base/logging.h" +#include "base/logging_win.h" +#include "base/time/time.h" + +namespace remoting { + +// Generated from an EVENT_TRACE, this structure stores the interesting fields +// in order to simplify event parsing and logging. +struct EventTraceData { + public: + // Create an instance from the data in the |event| payload. + static EventTraceData Create(EVENT_TRACE* event); + + EventTraceData(EventTraceData&&); + EventTraceData& operator=(EventTraceData&&); + EventTraceData(const EventTraceData&) = delete; + EventTraceData& operator=(const EventTraceData&) = delete; + + ~EventTraceData(); + + // The message type of the event (e.g. LOG_MESSAGE). + uint8_t event_type = 0; + + // The severity of the event (e.g. warning, info, error). + logging::LogSeverity severity = logging::LOG_INFO; + + // The ID of the process which originally logged the event. + int process_id = 0; + + // The ID of the thread which originally logged the event. + int thread_id = 0; + + // The original timestamp from when the event was logged. + base::Time::Exploded time_stamp = {}; + + // The path of the file which logged the event. Note that this may not be + // present in all builds (it depends on the logging params). + std::string file; + + // The line in the file which logged the event. Note that this may not be + // present in all builds (it depends on the logging params). + int32_t line = 0; + + // The original message which was logged to ETW. + std::string message; + + private: + EventTraceData(); +}; + +} // namespace remoting + +#endif // REMOTING_HOST_WIN_EVENT_TRACE_DATA_H_
diff --git a/remoting/host/win/event_trace_data_unittest.cc b/remoting/host/win/event_trace_data_unittest.cc new file mode 100644 index 0000000..8ce8f0e --- /dev/null +++ b/remoting/host/win/event_trace_data_unittest.cc
@@ -0,0 +1,132 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/host/win/event_trace_data.h" + +#include "base/check.h" +#include "base/logging.h" +#include "base/logging_win.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace remoting { + +namespace { +constexpr int kProcessId = 12345; +constexpr int kThreadId = 54321; +constexpr DWORD kStackDepth = 5; +constexpr int32_t kLineNumber = 42; +constexpr char kFilePath[] = "//remoting/host/win/awesome_stuff.cc\0"; +constexpr char kTestLogMessage[] = "BlerghityBlah!\0"; +} // namespace + +class EventTraceDataTest : public ::testing::Test { + protected: + void InitForLogMessage(); + void InitForLogMessageFull(); + + size_t ReserveBufferSpace(size_t space_needed); + + FILETIME time_ = {}; + EVENT_TRACE event_trace_ = {}; + std::vector<uint8_t> buffer_; + + private: + void InitSharedFields(uint8_t type); +}; + +void EventTraceDataTest::InitSharedFields(uint8_t type) { + event_trace_.Header.Class.Type = type; + event_trace_.Header.Class.Level = TRACE_LEVEL_WARNING; + event_trace_.Header.ProcessId = kProcessId; + event_trace_.Header.ThreadId = kThreadId; + + GetSystemTimeAsFileTime(&time_); + event_trace_.Header.TimeStamp.LowPart = time_.dwLowDateTime; + event_trace_.Header.TimeStamp.HighPart = time_.dwHighDateTime; + + buffer_.clear(); +} + +void EventTraceDataTest::InitForLogMessage() { + InitSharedFields(static_cast<uint8_t>(logging::LOG_MESSAGE)); + + size_t message_length = strlen(kTestLogMessage) + 1; + buffer_.resize(message_length); + memcpy(buffer_.data(), kTestLogMessage, message_length); + + event_trace_.MofData = buffer_.data(); + event_trace_.MofLength = buffer_.size(); +} + +void EventTraceDataTest::InitForLogMessageFull() { + InitSharedFields(static_cast<uint8_t>(logging::LOG_MESSAGE_FULL)); + + // Set up the stack trace info. + size_t data_size = sizeof(DWORD); + size_t offset = ReserveBufferSpace(data_size); + memcpy(buffer_.data() + offset, &kStackDepth, data_size); + + // Allocate space for the 'stack trace' info. + data_size = kStackDepth * sizeof(intptr_t); + offset = ReserveBufferSpace(data_size); + memset(buffer_.data() + offset, 0, data_size); + + // Set the line number. + data_size = sizeof(DWORD); + offset = ReserveBufferSpace(data_size); + memcpy(buffer_.data() + offset, &kLineNumber, data_size); + + // Set the file path. + data_size = strlen(kFilePath) + 1; + offset = ReserveBufferSpace(data_size); + memcpy(buffer_.data() + offset, &kFilePath, data_size); + + // Set the log message. + data_size = strlen(kTestLogMessage) + 1; + offset = ReserveBufferSpace(data_size); + memcpy(buffer_.data() + offset, &kTestLogMessage, data_size); + + event_trace_.MofData = buffer_.data(); + event_trace_.MofLength = buffer_.size(); +} + +size_t EventTraceDataTest::ReserveBufferSpace(size_t space_needed) { + size_t original_size = buffer_.size(); + buffer_.resize(original_size + space_needed); + return original_size; +} + +TEST_F(EventTraceDataTest, LogMessage) { + InitForLogMessage(); + + EventTraceData data = EventTraceData::Create(&event_trace_); + + EXPECT_EQ(logging::LOG_MESSAGE, data.event_type); + EXPECT_EQ(logging::LOG_WARNING, data.severity); + EXPECT_EQ(kProcessId, data.process_id); + EXPECT_EQ(kThreadId, data.thread_id); + EXPECT_TRUE(data.time_stamp.HasValidValues()); + EXPECT_STREQ(kTestLogMessage, data.message.c_str()); + + // File and line data should not be filled in for this log message type. + EXPECT_EQ(std::string(), data.file); + EXPECT_EQ(0, data.line); +} + +TEST_F(EventTraceDataTest, LogFullMessage) { + InitForLogMessageFull(); + + EventTraceData data = EventTraceData::Create(&event_trace_); + + EXPECT_EQ(logging::LOG_MESSAGE_FULL, data.event_type); + EXPECT_EQ(logging::LOG_WARNING, data.severity); + EXPECT_EQ(kProcessId, data.process_id); + EXPECT_EQ(kThreadId, data.thread_id); + EXPECT_TRUE(data.time_stamp.HasValidValues()); + EXPECT_EQ(kLineNumber, data.line); + EXPECT_STREQ(kFilePath, data.file.c_str()); + EXPECT_STREQ(kTestLogMessage, data.message.c_str()); +} + +} // namespace remoting
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json index e2db4aad..7aaca9b 100644 --- a/testing/buildbot/chromium.clang.json +++ b/testing/buildbot/chromium.clang.json
@@ -16152,6 +16152,23 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "openscreen_unittests", + "test_id_prefix": "ninja://chrome/browser/media/router:openscreen_unittests/" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "pdf_unittests", "test_id_prefix": "ninja://pdf:pdf_unittests/" },
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 7262e4f..dd79d41 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -11825,6 +11825,27 @@ ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "openscreen_unittests", + "test_id_prefix": "ninja://chrome/browser/media/router:openscreen_unittests/" + }, + { + "args": [ + "--test-launcher-print-test-stdio=always" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Ubuntu-16.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "pdf_unittests", "test_id_prefix": "ninja://pdf:pdf_unittests/" },
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 30426bd..3b71f8f 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -2238,8 +2238,6 @@ }, 'openscreen_unittests': { 'remove_from': [ - 'Linux MSan Tests', # crbug.com/1143946 - 'ToTLinuxMSan', # crbug.com/1143946 'Linux CFI', # crbug.com/1143983 'CFI Linux ToT', # crbug.com/1143983 ],
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 28ac03d..12e6ab1 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1533,7 +1533,8 @@ "enable_features": [ "ChromeShareQRCode", "ChromeShareScreenshot", - "ChromeSharingHub" + "ChromeSharingHub", + "ChromeSharingHubV15" ], "min_os_version": "5.1" } @@ -2219,6 +2220,21 @@ ] } ], + "DirectCompositionForceFullDamage": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DirectCompositionForceFullDamage" + ] + } + ] + } + ], "DirectCompositionSoftwareOverlays": [ { "platforms": [ @@ -5488,6 +5504,27 @@ ] } ], + "ProbabilisticCryptidRenderer": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_empty", + "params": { + "asset-key": "empty", + "max-probability-per-million": "20000", + "moratorium-length-millis": "345600000", + "ramp-up-length-millis": "1814400000" + }, + "enable_features": [ + "ProbabilisticCryptidRenderer" + ] + } + ] + } + ], "ProtoDBSharedMigration": [ { "platforms": [
diff --git a/third_party/blink/public/platform/web_frame_request_blocker.h b/third_party/blink/public/platform/web_frame_request_blocker.h index 334b0065..0a999f9 100644 --- a/third_party/blink/public/platform/web_frame_request_blocker.h +++ b/third_party/blink/public/platform/web_frame_request_blocker.h
@@ -32,9 +32,6 @@ // Resumes any blocked subresource requests. virtual void Resume() = 0; - // Cancels any blocked subresource requests. - virtual void Cancel() = 0; - virtual std::unique_ptr<URLLoaderThrottle> GetThrottleIfRequestsBlocked() = 0; };
diff --git a/third_party/blink/renderer/bindings/core/v8/module_record_test.cc b/third_party/blink/renderer/bindings/core/v8/module_record_test.cc index 71bb2afc..3b5813b 100644 --- a/third_party/blink/renderer/bindings/core/v8/module_record_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/module_record_test.cc
@@ -204,32 +204,11 @@ EXPECT_EQ("b", resolver->Specifiers()[1]); } -class SaveResultFunction final : public ScriptFunction { - public: - static v8::Local<v8::Function> CreateFunction(ScriptState* script_state, - ScriptValue* output) { - SaveResultFunction* self = - MakeGarbageCollected<SaveResultFunction>(script_state, output); - return self->BindToV8Function(); - } - - SaveResultFunction(ScriptState* script_state, ScriptValue* output) - : ScriptFunction(script_state), output_(output) {} - - private: - ScriptValue Call(ScriptValue value) override { - *output_ = value; - return value; - } - - ScriptValue* output_; -}; - TEST_P(ModuleRecordTest, EvaluationErrorIsRemembered) { V8TestingScope scope; + ScriptState* state = scope.GetScriptState(); - auto* modulator = - MakeGarbageCollected<ModuleRecordTestModulator>(scope.GetScriptState()); + auto* modulator = MakeGarbageCollected<ModuleRecordTestModulator>(state); auto* resolver = modulator->GetTestModuleRecordResolver(); const KURL js_url_f("https://example.com/failure.js"); @@ -238,9 +217,8 @@ ScriptFetchOptions(), TextPosition::MinimumPosition(), ASSERT_NO_EXCEPTION); ASSERT_FALSE(module_failure.IsEmpty()); - ASSERT_TRUE(ModuleRecord::Instantiate(scope.GetScriptState(), module_failure, - js_url_f) - .IsEmpty()); + ASSERT_TRUE( + ModuleRecord::Instantiate(state, module_failure, js_url_f).IsEmpty()); ScriptEvaluationResult evaluation_result1 = JSModuleScript::CreateForTest(modulator, module_failure, js_url_f) ->RunScriptAndReturnValue(); @@ -253,40 +231,16 @@ js_url_c, ScriptFetchOptions(), TextPosition::MinimumPosition(), scope.GetExceptionState()); ASSERT_FALSE(module.IsEmpty()); - ASSERT_TRUE( - ModuleRecord::Instantiate(scope.GetScriptState(), module, js_url_c) - .IsEmpty()); + ASSERT_TRUE(ModuleRecord::Instantiate(state, module, js_url_c).IsEmpty()); ScriptEvaluationResult evaluation_result2 = JSModuleScript::CreateForTest(modulator, module, js_url_c) ->RunScriptAndReturnValue(); - if (base::FeatureList::IsEnabled(features::kTopLevelAwait)) { - EXPECT_EQ(evaluation_result1.GetResultType(), - ScriptEvaluationResult::ResultType::kSuccess); - EXPECT_EQ(evaluation_result2.GetResultType(), - ScriptEvaluationResult::ResultType::kSuccess); - - ScriptValue value1; - ScriptValue value2; - evaluation_result1.GetPromise(scope.GetScriptState()) - .Then(v8::Local<v8::Function>(), SaveResultFunction::CreateFunction( - scope.GetScriptState(), &value1)); - evaluation_result2.GetPromise(scope.GetScriptState()) - .Then(v8::Local<v8::Function>(), SaveResultFunction::CreateFunction( - scope.GetScriptState(), &value2)); - v8::MicrotasksScope::PerformCheckpoint( - scope.GetScriptState()->GetIsolate()); - EXPECT_FALSE(value1.IsEmpty()); - EXPECT_FALSE(value2.IsEmpty()); - EXPECT_EQ(value1, value2); - } else { - EXPECT_EQ(evaluation_result1.GetResultType(), - ScriptEvaluationResult::ResultType::kException); - EXPECT_EQ(evaluation_result2.GetResultType(), - ScriptEvaluationResult::ResultType::kException); - EXPECT_EQ(evaluation_result1.GetExceptionForModule(), - evaluation_result2.GetExceptionForModule()); - } + v8::Local<v8::Value> exception1 = GetException(state, evaluation_result1); + v8::Local<v8::Value> exception2 = GetException(state, evaluation_result2); + EXPECT_FALSE(exception1.IsEmpty()); + EXPECT_FALSE(exception2.IsEmpty()); + EXPECT_EQ(exception1, exception2); ASSERT_EQ(1u, resolver->ResolveCount()); EXPECT_EQ("failure", resolver->Specifiers()[0]); @@ -339,34 +293,17 @@ scope.GetIsolate(), "throw 'bar';", js_url, js_url, ScriptFetchOptions(), TextPosition::MinimumPosition(), ASSERT_NO_EXCEPTION); ASSERT_FALSE(module.IsEmpty()); - ScriptValue exception = + ScriptValue instantiation_exception = ModuleRecord::Instantiate(scope.GetScriptState(), module, js_url); - ASSERT_TRUE(exception.IsEmpty()); + ASSERT_TRUE(instantiation_exception.IsEmpty()); ScriptEvaluationResult result = JSModuleScript::CreateForTest(modulator, module, js_url) ->RunScriptAndReturnValue(); - v8::Local<v8::Value> value; - if (base::FeatureList::IsEnabled(features::kTopLevelAwait)) { - ASSERT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kSuccess); - ScriptValue script_value; - result.GetPromise(scope.GetScriptState()) - .Then(v8::Local<v8::Function>(), - SaveResultFunction::CreateFunction(scope.GetScriptState(), - &script_value)); - v8::MicrotasksScope::PerformCheckpoint( - scope.GetScriptState()->GetIsolate()); - EXPECT_FALSE(script_value.IsEmpty()); - value = script_value.V8Value(); - } else { - ASSERT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kException); - value = result.GetExceptionForModule(); - } - ASSERT_TRUE(value->IsString()); - EXPECT_EQ("bar", ToCoreString(v8::Local<v8::String>::Cast(value))); + v8::Local<v8::Value> exception = GetException(scope.GetScriptState(), result); + ASSERT_TRUE(exception->IsString()); + EXPECT_EQ("bar", ToCoreString(exception.As<v8::String>())); } // Instantiate tests once with TLA and once without:
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc index 7bc077a3..dea409f 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
@@ -452,7 +452,7 @@ } } -// Creates an entangled pair of channels. Adds one end to |stream_channels_| as +// Creates an entangled pair of channels. Adds one end to |streams_| as // a MessagePortChannel, and returns the other end as a MessagePort. MessagePort* SerializedScriptValue::AddStreamChannel( ExecutionContext* execution_context) { @@ -468,7 +468,7 @@ // 9. Set dataHolder.[[port]] to ! StructuredSerializeWithTransfer(port2, // « port2 »). - stream_channels_.push_back(MessagePortChannel(pipe.TakePort1())); + streams_.push_back(Stream(pipe.TakePort1())); return local_port; }
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h index 940a1b6..c057291f 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h +++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h
@@ -37,11 +37,14 @@ #include "base/optional.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/common/messaging/message_port_channel.h" +#include "third_party/blink/public/common/messaging/message_port_descriptor.h" #include "third_party/blink/public/mojom/file_system_access/native_file_system_transfer_token.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/transferables.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/mojo/mojo_handle.h" +#include "third_party/blink/renderer/core/streams/readable_stream_transferring_optimizer.h" +#include "third_party/blink/renderer/core/streams/writable_stream_transferring_optimizer.h" #include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h" @@ -73,11 +76,32 @@ USING_FAST_MALLOC(SerializedScriptValue); public: + class Stream final { + DISALLOW_NEW(); + + public: + explicit Stream(MessagePortDescriptor descriptor) + : channel(std::move(descriptor)) {} + Stream(MessagePortDescriptor descriptor, + std::unique_ptr<ReadableStreamTransferringOptimizer> optimizer) + : channel(std::move(descriptor)), + readable_optimizer(std::move(optimizer)) {} + Stream(MessagePortDescriptor descriptor, + std::unique_ptr<WritableStreamTransferringOptimizer> optimizer) + : channel(std::move(descriptor)), + writable_optimizer(std::move(optimizer)) {} + + MessagePortChannel channel; + std::unique_ptr<ReadableStreamTransferringOptimizer> readable_optimizer; + std::unique_ptr<WritableStreamTransferringOptimizer> writable_optimizer; + }; + using ArrayBufferContentsArray = Vector<ArrayBufferContents, 1>; using SharedArrayBufferContentsArray = Vector<ArrayBufferContents, 1>; using ImageBitmapContentsArray = Vector<scoped_refptr<StaticBitmapImage>, 1>; using TransferredWasmModulesArray = WTF::Vector<v8::CompiledWasmModule>; using MessagePortChannelArray = Vector<MessagePortChannel>; + using StreamArray = Vector<Stream>; using NativeFileSystemTokensArray = Vector<mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken>>; @@ -266,7 +290,7 @@ } void SetImageBitmapContentsArray(ImageBitmapContentsArray contents); - MessagePortChannelArray& GetStreamChannels() { return stream_channels_; } + StreamArray& GetStreams() { return streams_; } bool IsLockedToAgentCluster() const { return !wasm_modules_.IsEmpty() || @@ -363,9 +387,9 @@ ArrayBufferContentsArray array_buffer_contents_array_; ImageBitmapContentsArray image_bitmap_contents_array_; - // |stream_channels_| is also single-use but is special-cased because it works + // |streams_| is also single-use but is special-cased because it works // with ServiceWorkers. - MessagePortChannelArray stream_channels_; + StreamArray streams_; // These do not have one-use transferred contents, like the above. TransferredWasmModulesArray wasm_modules_;
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc index 3f800c0e..fefb064 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
@@ -183,9 +183,12 @@ // TODO(ricea): Make ExtendableMessageEvent store an // UnpackedSerializedScriptValue like MessageEvent does, and then this // special case won't be necessary. + Vector<MessagePortChannel> channels; + for (auto& stream : serialized_script_value_->GetStreams()) { + channels.push_back(stream.channel); + } transferred_stream_ports_ = MessagePort::EntanglePorts( - *ExecutionContext::From(script_state_), - serialized_script_value_->GetStreamChannels()); + *ExecutionContext::From(script_state_), channels); } // There's nothing else to transfer if the deserializer was not given an
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc index 63970e2a..339e1bb 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
@@ -1934,8 +1934,8 @@ auto corrupted_serialized_script_value = SerializedScriptValue::Create(serialized_value, sizeof(serialized_value)); - corrupted_serialized_script_value->GetStreamChannels() = - serialized_script_value->GetStreamChannels(); + corrupted_serialized_script_value->GetStreams() = + std::move(serialized_script_value->GetStreams()); // Entangle the message ports. MessagePortArray* transferred_message_ports = MessagePort::EntanglePorts(
diff --git a/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc b/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc index d601232..598bbba 100644 --- a/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc +++ b/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
@@ -237,7 +237,7 @@ blink_feature = WebFeature::kV8RegExpReplaceCalledOnSlowRegExp; break; case v8::Isolate::kSharedArrayBufferConstructed: - if (CurrentExecutionContext(isolate)->CrossOriginIsolatedCapability()) { + if (!CurrentExecutionContext(isolate)->CrossOriginIsolatedCapability()) { blink_feature = WebFeature::kV8SharedArrayBufferConstructedWithoutIsolation; } else {
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc index 75dd40b2..25ed2c8 100644 --- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc +++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -36,6 +36,7 @@ #include "third_party/blink/renderer/core/dom/container_node.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/frame/event_handler_registry.h" @@ -43,6 +44,7 @@ #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/frame/web_feature.h" +#include "third_party/blink/renderer/core/html/forms/html_field_set_element.h" #include "third_party/blink/renderer/core/html/forms/html_input_element.h" #include "third_party/blink/renderer/core/html/forms/html_text_area_element.h" #include "third_party/blink/renderer/core/html/html_iframe_element.h" @@ -686,6 +688,20 @@ AdjustStyleForDisplay(style, layout_parent_style, element, element ? &element->GetDocument() : nullptr); + // TOOD(crbug.com/1146925): Sticky content in a scrollable FIELDSET triggers + // a DHCECK failure in |StickyPositionScrollingConstraints:: + // AncestorContainingBlockOffset()|. We disable it until the root cause is + // fixed. + if (style.GetPosition() == EPosition::kSticky && element) { + for (const Node& ancestor : FlatTreeTraversal::AncestorsOf(*element)) { + if (const auto* fieldset = DynamicTo<HTMLFieldSetElement>(ancestor)) { + if (!fieldset->ComputedStyleRef().IsOverflowVisibleAlongBothAxes()) + style.SetPosition(EPosition::kStatic); + break; + } + } + } + // If this is a child of a LayoutNGCustom, we need the name of the parent // layout function for invalidation purposes. if (layout_parent_style.IsDisplayLayoutCustomBox()) {
diff --git a/third_party/blink/renderer/core/execution_context/execution_context.cc b/third_party/blink/renderer/core/execution_context/execution_context.cc index 38b062d..7826bb952 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context.cc +++ b/third_party/blink/renderer/core/execution_context/execution_context.cc
@@ -233,6 +233,11 @@ return lifecycle_state_ == mojom::blink::FrameLifecycleState::kPaused; } +bool ExecutionContext::IsLoadDeferred() const { + return lifecycle_state_ == mojom::blink::FrameLifecycleState::kPaused || + lifecycle_state_ == mojom::blink::FrameLifecycleState::kFrozen; +} + int ExecutionContext::CircularSequentialID() { ++circular_sequential_id_; if (circular_sequential_id_ > ((1U << 31) - 1U))
diff --git a/third_party/blink/renderer/core/execution_context/execution_context.h b/third_party/blink/renderer/core/execution_context/execution_context.h index f2b39235c..60528556 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context.h +++ b/third_party/blink/renderer/core/execution_context/execution_context.h
@@ -239,6 +239,7 @@ mojom::FrameLifecycleState ContextPauseState() const { return lifecycle_state_; } + bool IsLoadDeferred() const; // Gets the next id in a circular sequence from 1 to 2^31-1. int CircularSequentialID();
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index af91265..62ec3bc 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -2284,12 +2284,16 @@ return; paused_ = is_paused; - GetDocument()->Fetcher()->SetDefersLoading(is_paused); - Loader().SetDefersLoading(is_paused); + GetDocument()->Fetcher()->SetDefersLoading(IsLoadDeferred()); + Loader().SetDefersLoading(IsLoadDeferred()); // TODO(altimin): Move this to PageScheduler level. GetFrameScheduler()->SetPaused(is_paused); } +bool LocalFrame::IsLoadDeferred() { + return frozen_ || paused_; +} + void LocalFrame::DidFreeze() { DCHECK(IsAttached()); GetDocument()->DispatchFreezeEvent(); @@ -2303,6 +2307,9 @@ document_resource_coordinator->SetLifecycleState( performance_manager::mojom::LifecycleState::kFrozen); } + + GetDocument()->Fetcher()->SetDefersLoading(true); + Loader().SetDefersLoading(true); } void LocalFrame::DidResume() { @@ -2319,6 +2326,8 @@ document_resource_coordinator->SetLifecycleState( performance_manager::mojom::LifecycleState::kRunning); } + GetDocument()->Fetcher()->SetDefersLoading(IsLoadDeferred()); + Loader().SetDefersLoading(IsLoadDeferred()); } void LocalFrame::MaybeLogAdClickNavigation() {
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index 78be3eb..68a8aa70be 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -719,6 +719,8 @@ PolicyContainer* GetPolicyContainer() { return policy_container_.get(); } void SetPolicyContainer(std::unique_ptr<PolicyContainer> container); + bool IsLoadDeferred(); + private: friend class FrameNavigationDisabler; FRIEND_TEST_ALL_PREFIXES(LocalFrameTest, CharacterIndexAtPointWithPinchZoom);
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc index 02b1b73b..5c6219e2 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
@@ -41,6 +41,11 @@ } } +void LocalFrameUkmAggregator::AbsoluteMetricRecord::reset() { + interval_duration = base::TimeDelta(); + main_frame_duration = base::TimeDelta(); +} + LocalFrameUkmAggregator::LocalFrameUkmAggregator(int64_t source_id, ukm::UkmRecorder* recorder) : source_id_(source_id), @@ -51,8 +56,6 @@ primary_metric_.reset(); // Define the UMA for the primary metric. - primary_metric_.uma_counter.reset( - new CustomCountHistogram("Blink.MainFrame.UpdateTime", 0, 10000000, 50)); primary_metric_.pre_fcp_uma_counter.reset(new CustomCountHistogram( "Blink.MainFrame.UpdateTime.PreFCP", 0, 10000000, 50)); primary_metric_.post_fcp_uma_counter.reset(new CustomCountHistogram( @@ -66,30 +69,9 @@ const char* const uma_prefcp_postscript = ".PreFCP"; const char* const uma_postfcp_postscript = ".PostFCP"; const char* const uma_pre_fcp_aggregated_postscript = ".AggregatedPreFCP"; - const char* const uma_percentage_preamble = "Blink.MainFrame."; - const char* const uma_percentage_postscript = "Ratio"; - - // Set up sub-strings for the bucketed UMA metrics - Vector<String> threshold_substrings; - if (!bucket_thresholds().size()) { - threshold_substrings.push_back(".All"); - } else { - threshold_substrings.push_back(String::Format( - ".LessThan%" PRId64 "ms", bucket_thresholds()[0].InMilliseconds())); - for (wtf_size_t i = 1; i < bucket_thresholds().size(); ++i) { - threshold_substrings.push_back( - String::Format(".%" PRId64 "msTo%" PRId64 "ms", - bucket_thresholds()[i - 1].InMilliseconds(), - bucket_thresholds()[i].InMilliseconds())); - } - threshold_substrings.push_back(String::Format( - ".MoreThan%" PRId64 "ms", - bucket_thresholds()[bucket_thresholds().size() - 1].InMilliseconds())); - } // Populate all the sub-metrics. absolute_metric_records_.ReserveInitialCapacity(kCount); - main_frame_percentage_records_.ReserveInitialCapacity(kCount); for (const MetricInitializationData& metric_data : metrics_data()) { // Absolute records report the absolute time for each metric per frame. // They also aggregate the time spent in each stage between navigation @@ -103,8 +85,6 @@ uma_name.Append(uma_preamble); uma_name.Append(metric_data.name); uma_name.Append(uma_postscript); - absolute_record.uma_counter.reset(new CustomCountHistogram( - uma_name.ToString().Utf8().c_str(), 0, 10000000, 50)); StringBuilder pre_fcp_uma_name; pre_fcp_uma_name.Append(uma_name); pre_fcp_uma_name.Append(uma_prefcp_postscript); @@ -121,27 +101,12 @@ absolute_record.uma_aggregate_counter.reset(new CustomCountHistogram( aggregated_uma_name.ToString().Utf8().c_str(), 0, 10000000, 50)); } - - // Percentage records report the ratio of each metric to the primary metric. - // UMA counters are also associated with the ratios and we allocate and own - // them here. - auto& percentage_record = main_frame_percentage_records_.emplace_back(); - percentage_record.reset(); - for (auto bucket_substring : threshold_substrings) { - StringBuilder uma_percentage_name; - uma_percentage_name.Append(uma_percentage_preamble); - uma_percentage_name.Append(metric_data.name); - uma_percentage_name.Append(uma_percentage_postscript); - uma_percentage_name.Append(bucket_substring); - percentage_record.uma_counters_per_bucket.push_back( - std::make_unique<CustomCountHistogram>( - uma_percentage_name.ToString().Utf8().c_str(), 0, 10000000, 50)); - } } // Make space in the current sample. current_sample_.sub_metrics_durations.Grow(static_cast<wtf_size_t>(kCount)); - current_sample_.sub_metric_percentages.Grow(static_cast<wtf_size_t>(kCount)); + current_sample_.sub_main_frame_durations.Grow( + static_cast<wtf_size_t>(kCount)); } LocalFrameUkmAggregator::~LocalFrameUkmAggregator() { @@ -169,36 +134,36 @@ std::unique_ptr<cc::BeginMainFrameMetrics> metrics_data = std::make_unique<cc::BeginMainFrameMetrics>(); metrics_data->handle_input_events = - main_frame_percentage_records_[static_cast<unsigned>( - MetricId::kHandleInputEvents)] - .interval_duration; + absolute_metric_records_[static_cast<unsigned>( + MetricId::kHandleInputEvents)] + .main_frame_duration; metrics_data->animate = - main_frame_percentage_records_[static_cast<unsigned>(MetricId::kAnimate)] - .interval_duration; + absolute_metric_records_[static_cast<unsigned>(MetricId::kAnimate)] + .main_frame_duration; metrics_data->style_update = - main_frame_percentage_records_[static_cast<unsigned>(MetricId::kStyle)] - .interval_duration; + absolute_metric_records_[static_cast<unsigned>(MetricId::kStyle)] + .main_frame_duration; metrics_data->layout_update = - main_frame_percentage_records_[static_cast<unsigned>(MetricId::kLayout)] - .interval_duration; + absolute_metric_records_[static_cast<unsigned>(MetricId::kLayout)] + .main_frame_duration; metrics_data->prepaint = - main_frame_percentage_records_[static_cast<unsigned>(MetricId::kPrePaint)] - .interval_duration; + absolute_metric_records_[static_cast<unsigned>(MetricId::kPrePaint)] + .main_frame_duration; metrics_data->compositing_assignments = - main_frame_percentage_records_[static_cast<unsigned>( - MetricId::kCompositingAssignments)] - .interval_duration; + absolute_metric_records_[static_cast<unsigned>( + MetricId::kCompositingAssignments)] + .main_frame_duration; metrics_data->compositing_inputs = - main_frame_percentage_records_[static_cast<unsigned>( - MetricId::kCompositingInputs)] - .interval_duration; + absolute_metric_records_[static_cast<unsigned>( + MetricId::kCompositingInputs)] + .main_frame_duration; metrics_data->paint = - main_frame_percentage_records_[static_cast<unsigned>(MetricId::kPaint)] - .interval_duration; + absolute_metric_records_[static_cast<unsigned>(MetricId::kPaint)] + .main_frame_duration; metrics_data->composite_commit = - main_frame_percentage_records_[static_cast<unsigned>( - MetricId::kCompositingCommit)] - .interval_duration; + absolute_metric_records_[static_cast<unsigned>( + MetricId::kCompositingCommit)] + .main_frame_duration; metrics_data->should_measure_smoothness = (fcp_state_ >= kThisFrameReachedFCP); return metrics_data; @@ -213,7 +178,6 @@ base::TimeDelta& duration) { if (!calls_to_next_forced_style_layout_uma_) { auto& record = absolute_metric_records_[kForcedStyleAndLayout]; - record.uma_counter->CountMicroseconds(duration); if (fcp_state_ == kHavePassedFCP) record.post_fcp_uma_counter->CountMicroseconds(duration); else @@ -248,17 +212,18 @@ DCHECK_LT(metric_index, absolute_metric_records_.size()); auto& record = absolute_metric_records_[metric_index]; record.interval_duration += duration; + if (in_main_frame_update_) + record.main_frame_duration += duration; if (is_pre_fcp) record.pre_fcp_aggregate += duration; // Record the UMA // ForcedStyleAndLayout happen so frequently on some pages that we overflow // the signed 32 counter for number of events in a 30 minute period. So // randomly record with probability 1/100. - if (record.uma_counter) { + if (record.pre_fcp_uma_counter) { if (metric_index == static_cast<size_t>(kForcedStyleAndLayout)) { RecordForcedStyleLayoutUMA(duration); } else { - record.uma_counter->CountMicroseconds(duration); if (is_pre_fcp) { record.pre_fcp_uma_counter->CountMicroseconds(duration); } else { @@ -266,13 +231,6 @@ } } } - - // Only record ratios when inside a main frame. - if (in_main_frame_update_) { - // Just record the duration for ratios. We compute the ratio later - // when we know the frame time. - main_frame_percentage_records_[metric_index].interval_duration += duration; - } } void LocalFrameUkmAggregator::RecordImplCompositorSample( @@ -319,7 +277,6 @@ bool report_fcp_metrics = (fcp_state_ == kThisFrameReachedFCP); // Record UMA - primary_metric_.uma_counter->CountMicroseconds(duration); if (report_as_pre_fcp) primary_metric_.pre_fcp_uma_counter->CountMicroseconds(duration); else @@ -330,23 +287,6 @@ if (report_as_pre_fcp) primary_metric_.pre_fcp_aggregate += duration; - // Compute all the dependent metrics, after finding which bucket we're in - // for UMA data. - size_t bucket_index = bucket_thresholds().size(); - for (size_t i = 0; i < bucket_index; ++i) { - if (duration < bucket_thresholds()[i]) { - bucket_index = i; - } - } - - for (auto& record : main_frame_percentage_records_) { - auto percentage = base::ClampRound<base::HistogramBase::Sample>( - 100 * record.interval_duration / duration); - record.uma_counters_per_bucket[bucket_index]->Count(percentage); - } - - // Record here to avoid resetting the ratios before this data point is - // recorded. UpdateEventTimeAndUpdateSampleIfNeeded(trackers); // Report the FCP metrics, if necessary, after updating the sample so that @@ -391,9 +331,8 @@ for (unsigned i = 0; i < static_cast<unsigned>(kCount); ++i) { current_sample_.sub_metrics_durations[i] = absolute_metric_records_[i].interval_duration; - current_sample_.sub_metric_percentages[i] = base::ClampRound<unsigned>( - 100 * main_frame_percentage_records_[i].interval_duration / - primary_metric_.interval_duration); + current_sample_.sub_main_frame_durations[i] = + absolute_metric_records_[i].main_frame_duration; } current_sample_.trackers = trackers; } @@ -451,7 +390,8 @@ builder \ .Set##name( \ current_sample_.sub_metrics_durations[index].InMicroseconds()) \ - .Set##name##Percentage(current_sample_.sub_metric_percentages[index]); \ + .Set##name##BeginMainFrame( \ + current_sample_.sub_main_frame_durations[index].InMicroseconds()); \ break ukm::builders::Blink_UpdateTime builder(source_id_); @@ -493,8 +433,6 @@ primary_metric_.reset(); for (auto& record : absolute_metric_records_) record.reset(); - for (auto& record : main_frame_percentage_records_) - record.reset(); } bool LocalFrameUkmAggregator::AllMetricsAreZero() { @@ -504,6 +442,9 @@ if (record.interval_duration.InMicroseconds()) { return false; } + if (record.main_frame_duration.InMicroseconds()) { + return false; + } } return true; }
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h index c61642f..6eb81f8 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
@@ -79,24 +79,16 @@ // // It may generate an event. trackers is a bit encoding of the active frame //. // sequence trackers, informing us of why the BeginMainFrame was requested. // -// In the example above, the event name is "my_event". It will measure 7 +// In the example above, the event name is "my_event". It will measure 4 // metrics: // "primary_metric", // "sub_metric1", // "sub_metric2", // "sub_metric3" -// "sub_metric1Percentage", -// "sub_metric2Percentage", -// "sub_metric3Percentage" // -// It will report 13 UMA values: +// It will report 4 UMA values: // "primary_uma_counter", -// "sub_uma_metric1", "sub_uma_metric2", "sub_uma_metric3", -// "sub_uma_ratio1.LessThan1ms", "sub_uma_ratio1.1msTo5ms", -// "sub_uma_ratio1.MoreThan5ms", "sub_uma_ratio2.LessThan1ms", -// "sub_uma_ratio2.1msTo5ms", "sub_uma_ratio2.MoreThan5ms", -// "sub_uma_ratio3.LessThan1ms", "sub_uma_ratio3.1msTo5ms", -// "sub_uma_ratio3.MoreThan5ms" +// "sub_uma_metric1", "sub_uma_metric2", "sub_uma_metric3" // // Note that these have to be specified in the appropriate ukm.xml file // and histograms.xml file. Runtime errors indicate missing or mis-named @@ -180,15 +172,6 @@ return data; } - // Modify this array if the UMA ratio metrics should be bucketed in a - // different way. - static base::span<const base::TimeDelta> bucket_thresholds() { - static const base::TimeDelta thresholds[] = { - base::TimeDelta::FromMilliseconds(1), - base::TimeDelta::FromMilliseconds(5)}; - return thresholds; - } - public: // This class will start a timer upon creation, which will end when the // object is destroyed. Upon destruction it will record a sample into the @@ -267,7 +250,6 @@ private: struct AbsoluteMetricRecord { - std::unique_ptr<CustomCountHistogram> uma_counter; std::unique_ptr<CustomCountHistogram> pre_fcp_uma_counter; std::unique_ptr<CustomCountHistogram> post_fcp_uma_counter; std::unique_ptr<CustomCountHistogram> uma_aggregate_counter; @@ -275,25 +257,21 @@ // Accumulated at each sample, then reset with a call to // RecordEndOfFrameMetrics. base::TimeDelta interval_duration; + + // Accumulated at each sample when within a BeginMainFrame, + // reset with a call to RecordEndOfFrameMetrics. + base::TimeDelta main_frame_duration; + + // Accumulated at each sample up to the time of First Contentful Paint. base::TimeDelta pre_fcp_aggregate; - void reset() { interval_duration = base::TimeDelta(); } - }; - - struct MainFramePercentageRecord { - Vector<std::unique_ptr<CustomCountHistogram>> uma_counters_per_bucket; - - // Accumulated at each sample, then reset with a call to - // RecordEndOfFrameMetrics. - base::TimeDelta interval_duration; - - void reset() { interval_duration = base::TimeDelta(); } + void reset(); }; struct SampleToRecord { base::TimeDelta primary_metric_duration; Vector<base::TimeDelta> sub_metrics_durations; - Vector<unsigned> sub_metric_percentages; + Vector<base::TimeDelta> sub_main_frame_durations; cc::ActiveFrameSequenceTrackers trackers; }; @@ -335,7 +313,6 @@ const char* const event_name_; AbsoluteMetricRecord primary_metric_; Vector<AbsoluteMetricRecord> absolute_metric_records_; - Vector<MainFramePercentageRecord> main_frame_percentage_records_; // The current sample to report. When RecordEvent() is called we // check for uniform_random[0,1) < 1 / n where n is the number of frames
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc index fcbf085..930b6dc 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc
@@ -44,8 +44,8 @@ return LocalFrameUkmAggregator::metrics_data()[index].name; } - std::string GetPercentageMetricName(int index) { - return GetMetricName(index) + "Percentage"; + std::string GetBeginMainFrameMetricName(int index) { + return GetMetricName(index) + "BeginMainFrame"; } void ChooseNextFrameForTest() { aggregator().ChooseNextFrameForTest(); } @@ -61,7 +61,7 @@ void VerifyUpdateEntry(unsigned index, unsigned expected_primary_metric, unsigned expected_sub_metric, - float expected_percentage, + unsigned expected_begin_main_frame, unsigned expected_reasons, bool expected_before_fcp) { auto entries = recorder().GetEntriesByName("Blink.UpdateTime"); @@ -81,10 +81,12 @@ EXPECT_NEAR(*metric_value / 1e3, expected_sub_metric, 0.001); EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric( - entry, GetPercentageMetricName(i))); - const int64_t* metric_percentage = ukm::TestUkmRecorder::GetEntryMetric( - entry, GetPercentageMetricName(i)); - EXPECT_NEAR(*metric_percentage, expected_percentage, 0.5); + entry, GetBeginMainFrameMetricName(i))); + const int64_t* metric_begin_main_frame = + ukm::TestUkmRecorder::GetEntryMetric(entry, + GetBeginMainFrameMetricName(i)); + EXPECT_NEAR(*metric_begin_main_frame / 1e3, expected_begin_main_frame, + 0.001); } EXPECT_TRUE( ukm::TestUkmRecorder::EntryHasMetric(entry, "MainFrameIsBeforeFCP")); @@ -133,6 +135,14 @@ aggregator().RecordEndOfFrameMetrics(start_time, Now(), trackers); } + void SimulatePreFrame(unsigned millisecond_per_step) { + for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) { + auto timer = aggregator().GetScopedTimer(i); + test_task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(millisecond_per_step)); + } + } + bool SampleMatchesIteration(int64_t iteration_count) { return aggregator() .current_sample_.sub_metrics_durations[0] @@ -184,11 +194,45 @@ float expected_primary_metric = millisecond_for_step * LocalFrameUkmAggregator::kCount; float expected_sub_metric = millisecond_for_step; - float expected_percentage = - 100.0 / static_cast<float>(LocalFrameUkmAggregator::kCount); + float expected_begin_main_frame = millisecond_for_step; VerifyUpdateEntry(0u, expected_primary_metric, expected_sub_metric, - expected_percentage, 12, true); + expected_begin_main_frame, 12, true); +} + +TEST_F(LocalFrameUkmAggregatorTest, PreFrameWorkIsRecorded) { + // Verifies that we correctly account for work done before the begin + // main frame, and then within the begin main frame. + + // Although the tests use a mock clock, the UKM aggregator checks if the + // system has a high resolution clock before recording results. As a result, + // the tests will fail if the system does not have a high resolution clock. + if (!base::TimeTicks::IsHighResolution()) + return; + + // The initial interval is always zero, so we should see one set of metrics + // for the initial frame, regardless of the initial interval. + unsigned millisecond_for_step = 1; + base::TimeTicks start_time = + Now() + base::TimeDelta::FromMilliseconds(millisecond_for_step) * + LocalFrameUkmAggregator::kCount; + SimulatePreFrame(millisecond_for_step); + SimulateFrame(start_time, millisecond_for_step, 12); + + // Metrics are not reported until destruction. + EXPECT_EQ(recorder().entries_count(), 0u); + + // Reset the aggregator. Should record one pre-FCP metric. + ResetAggregator(); + EXPECT_EQ(recorder().entries_count(), 1u); + + float expected_primary_metric = + millisecond_for_step * LocalFrameUkmAggregator::kCount; + float expected_sub_metric = millisecond_for_step * 2; + float expected_begin_main_frame = millisecond_for_step; + + VerifyUpdateEntry(0u, expected_primary_metric, expected_sub_metric, + expected_begin_main_frame, 12, true); } TEST_F(LocalFrameUkmAggregatorTest, PreAndPostFCPAreRecorded) { @@ -213,11 +257,10 @@ float expected_primary_metric = millisecond_per_step * LocalFrameUkmAggregator::kCount; float expected_sub_metric = millisecond_per_step; - float expected_percentage = - 100.0 / static_cast<float>(LocalFrameUkmAggregator::kCount); + float expected_begin_main_frame = millisecond_per_step; VerifyUpdateEntry(0u, expected_primary_metric, expected_sub_metric, - expected_percentage, 4, true); + expected_begin_main_frame, 4, true); // Take another step. Should reset the frame count and report the first post- // fcp frame. A failure here iundicates that we did not reset the frame, @@ -237,10 +280,8 @@ // been recorded. EXPECT_EQ(recorder().entries_count(), 3u); - expected_percentage = - millisecond_per_step * 100.0 / static_cast<float>(millisecond_per_frame); VerifyUpdateEntry(1u, millisecond_per_frame, millisecond_per_step, - expected_percentage, 4, false); + expected_begin_main_frame, 4, false); } TEST_F(LocalFrameUkmAggregatorTest, AggregatedPreFCPEventRecorded) {
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc index a981645..7cdf765f 100644 --- a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
@@ -253,7 +253,7 @@ } bool HTMLTextAreaElement::TypeShouldForceLegacyLayout() const { - if (RuntimeEnabledFeatures::LayoutNGTextAreaEnabled()) + if (RuntimeEnabledFeatures::LayoutNGTextControlEnabled()) return false; UseCounter::Count(GetDocument(), WebFeature::kLegacyLayoutByTextControl); return true;
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element_test.cc b/third_party/blink/renderer/core/html/forms/html_text_area_element_test.cc index 0cd24755..18af3c9 100644 --- a/third_party/blink/renderer/core/html/forms/html_text_area_element_test.cc +++ b/third_party/blink/renderer/core/html/forms/html_text_area_element_test.cc
@@ -12,10 +12,10 @@ namespace blink { class HTMLTextAreaElementTest : public testing::WithParamInterface<bool>, - private ScopedLayoutNGTextAreaForTest, + private ScopedLayoutNGTextControlForTest, public RenderingTest { public: - HTMLTextAreaElementTest() : ScopedLayoutNGTextAreaForTest(GetParam()) {} + HTMLTextAreaElementTest() : ScopedLayoutNGTextControlForTest(GetParam()) {} protected: HTMLTextAreaElement& TestElement() {
diff --git a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc index 78051266..129fb5d4 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc +++ b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc
@@ -65,7 +65,7 @@ } bool EditingViewPortElement::TypeShouldForceLegacyLayout() const { - return !RuntimeEnabledFeatures::LayoutNGTextFieldEnabled(); + return !RuntimeEnabledFeatures::LayoutNGTextControlEnabled(); } // --------------------------- @@ -123,9 +123,7 @@ } bool TextControlInnerEditorElement::TypeShouldForceLegacyLayout() const { - if (OwnerShadowHost()->HasTagName(html_names::kInputTag)) - return !RuntimeEnabledFeatures::LayoutNGTextFieldEnabled(); - return !RuntimeEnabledFeatures::LayoutNGTextAreaEnabled(); + return !RuntimeEnabledFeatures::LayoutNGTextControlEnabled(); } LayoutObject* TextControlInnerEditorElement::CreateLayoutObject( @@ -255,7 +253,7 @@ } bool SearchFieldCancelButtonElement::TypeShouldForceLegacyLayout() const { - return !RuntimeEnabledFeatures::LayoutNGTextFieldEnabled(); + return !RuntimeEnabledFeatures::LayoutNGTextControlEnabled(); } // ----------------------------
diff --git a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc index 0853397..c8606c3 100644 --- a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc +++ b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
@@ -277,7 +277,7 @@ } bool TextFieldInputType::TypeShouldForceLegacyLayout() const { - if (RuntimeEnabledFeatures::LayoutNGTextFieldEnabled()) + if (RuntimeEnabledFeatures::LayoutNGTextControlEnabled()) return false; UseCounter::Count(GetElement().GetDocument(), WebFeature::kLegacyLayoutByTextControl);
diff --git a/third_party/blink/renderer/core/html/resources/html.css b/third_party/blink/renderer/core/html/resources/html.css index 48509cf..da6f733a 100644 --- a/third_party/blink/renderer/core/html/resources/html.css +++ b/third_party/blink/renderer/core/html/resources/html.css
@@ -567,7 +567,7 @@ input[type="file" i] { align-items: baseline; color: inherit; - overflow: hidden; + overflow: hidden !important; text-align: start !important; text-overflow: ellipsis; white-space: pre;
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc index 3045a67..14f106f 100644 --- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc +++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -320,20 +320,6 @@ if (!layout_object || !containing_view) return element_info; - // if (auto* context = element->GetDisplayLockContext()) { - // if (context->IsLocked()) { - // // If it's a locked element, use the values from the locked frame rect. - // // TODO(vmpstr): Verify that these values are correct here. - // element_info->setString( - // "nodeWidth", - // String::Number(context->GetLockedContentLogicalWidth().ToDouble())); - // element_info->setString( - // "nodeHeight", - // String::Number(context->GetLockedContentLogicalHeight().ToDouble())); - // } - // return element_info; - //} - // layoutObject the getBoundingClientRect() data in the tooltip // to be consistent with the rulers (see http://crbug.com/262338). DOMRect* bounding_box = element->getBoundingClientRect(); @@ -1477,6 +1463,13 @@ AppendQuad(border, highlight_config.border, Color::kTransparent, "border"); AppendQuad(margin, highlight_config.margin, Color::kTransparent, "margin"); + // Don't append node's grid / flex info if it's locked since those values may + // not be generated yet. + if (auto* context = layout_object->GetDisplayLockContext()) { + if (context->IsLocked()) + return; + } + if (highlight_config.css_grid != Color::kTransparent || highlight_config.grid_highlight_config) { grid_info_ = protocol::ListValue::create();
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 08e65a1..1834a9f5 100644 --- a/third_party/blink/renderer/core/layout/layout_frame_set.cc +++ b/third_party/blink/renderer/core/layout/layout_frame_set.cc
@@ -112,7 +112,7 @@ // Count the total length of all of the fixed columns/rows -> totalFixed. // Count the number of columns/rows which are fixed -> countFixed. if (grid[i].IsAbsolute()) { - grid_layout[i] = max<int>(grid[i].Value() * effective_zoom, 0); + grid_layout[i] = clampTo<int>(max(grid[i].Value() * effective_zoom, 0.0)); total_fixed += grid_layout[i]; count_fixed++; } @@ -121,7 +121,8 @@ // totalPercent. Count the number of columns/rows which are percentages -> // countPercent. if (grid[i].IsPercentage()) { - grid_layout[i] = max<int>(grid[i].Value() * available_len / 100., 0); + grid_layout[i] = + clampTo<int>(max(grid[i].Value() * available_len / 100., 0.0)); total_percent += grid_layout[i]; count_percent++; } @@ -130,7 +131,7 @@ // totalRelative. Count the number of columns/rows which are relative -> // countRelative. if (grid[i].IsRelative()) { - total_relative += max<int>(grid[i].Value(), 1); + total_relative += clampTo<int>(max(grid[i].Value(), 1.0)); count_relative++; } }
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_test.cc b/third_party/blink/renderer/core/layout/layout_text_control_test.cc index 43c4ebc..ae4cce2 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control_test.cc +++ b/third_party/blink/renderer/core/layout/layout_text_control_test.cc
@@ -16,9 +16,7 @@ class LayoutTextControlTest : public testing::WithParamInterface<bool>, public RenderingTest { public: - LayoutTextControlTest() - : scoped_text_area_flag_(GetParam()), - scoped_text_field_flag_(GetParam()) {} + LayoutTextControlTest() : scoped_text_control_flag_(GetParam()) {} protected: TextControlElement* GetTextControlElementById(const char* id) { @@ -51,8 +49,7 @@ } private: - ScopedLayoutNGTextAreaForTest scoped_text_area_flag_; - ScopedLayoutNGTextFieldForTest scoped_text_field_flag_; + ScopedLayoutNGTextControlForTest scoped_text_control_flag_; }; INSTANTIATE_TEST_SUITE_P(All, LayoutTextControlTest, testing::Bool());
diff --git a/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_test.cc b/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_test.cc index 74242d2..3217da1 100644 --- a/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_test.cc +++ b/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_test.cc
@@ -7,6 +7,7 @@ #include <memory> #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/bindings/core/v8/module_record.h" +#include "third_party/blink/renderer/bindings/core/v8/script_evaluation_result.h" #include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h" #include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" @@ -15,19 +16,26 @@ #include "third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.h" #include "third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.h" #include "third_party/blink/renderer/core/script/js_module_script.h" +#include "third_party/blink/renderer/core/testing/module_test_base.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" namespace blink { -class LayoutWorkletTest : public PageTestBase { +class LayoutWorkletTest : public PageTestBase, public ParametrizedModuleTest { public: void SetUp() override { + ParametrizedModuleTest::SetUp(); PageTestBase::SetUp(IntSize()); layout_worklet_ = MakeGarbageCollected<LayoutWorklet>(*GetDocument().domWindow()); proxy_ = layout_worklet_->CreateGlobalScope(); } + void TearDown() override { + PageTestBase::TearDown(); + ParametrizedModuleTest::TearDown(); + } + LayoutWorkletGlobalScopeProxy* GetProxy() { return LayoutWorkletGlobalScopeProxy::From(proxy_.Get()); } @@ -70,18 +78,17 @@ Persistent<LayoutWorklet> layout_worklet_; }; -TEST_F(LayoutWorkletTest, ParseProperties) { +TEST_P(LayoutWorkletTest, ParseProperties) { ScriptState::Scope scope(GetScriptState()); - EXPECT_EQ(EvaluateScriptModule(R"JS( + ScriptEvaluationResult result = EvaluateScriptModule(R"JS( registerLayout('foo', class { static get inputProperties() { return ['--prop', 'flex-basis', 'thing'] } static get childInputProperties() { return ['--child-prop', 'margin-top', 'other-thing'] } async intrinsicSizes() { } async layout() { } }); - )JS") - .GetResultType(), - ScriptEvaluationResult::ResultType::kSuccess); + )JS"); + EXPECT_FALSE(GetResult(GetScriptState(), result).IsEmpty()); LayoutWorkletGlobalScope* global_scope = GetGlobalScope(); CSSLayoutDefinition* definition = global_scope->FindDefinition("foo"); @@ -107,7 +114,7 @@ // TODO(ikilpatrick): Move all the tests below to wpt tests once we have the // layout API actually have effects that we can test in script. -TEST_F(LayoutWorkletTest, RegisterLayout) { +TEST_P(LayoutWorkletTest, RegisterLayout) { ScriptState::Scope scope(GetScriptState()); ScriptEvaluationResult result = EvaluateScriptModule(R"JS( registerLayout('foo', class { @@ -116,8 +123,7 @@ }); )JS"); - EXPECT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kSuccess); + EXPECT_FALSE(GetResult(GetScriptState(), result).IsEmpty()); result = EvaluateScriptModule(R"JS( registerLayout('bar', class { @@ -128,11 +134,10 @@ }); )JS"); - EXPECT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kSuccess); + EXPECT_FALSE(GetResult(GetScriptState(), result).IsEmpty()); } -TEST_F(LayoutWorkletTest, RegisterLayout_EmptyName) { +TEST_P(LayoutWorkletTest, RegisterLayout_EmptyName) { ScriptState::Scope scope(GetScriptState()); ScriptEvaluationResult result = EvaluateScriptModule(R"JS( registerLayout('', class { @@ -140,11 +145,10 @@ )JS"); // "The empty string is not a valid name." - EXPECT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kException); + EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty()); } -TEST_F(LayoutWorkletTest, RegisterLayout_Duplicate) { +TEST_P(LayoutWorkletTest, RegisterLayout_Duplicate) { ScriptState::Scope scope(GetScriptState()); ScriptEvaluationResult result = EvaluateScriptModule(R"JS( registerLayout('foo', class { @@ -158,11 +162,10 @@ )JS"); // "A class with name:'foo' is already registered." - EXPECT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kException); + EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty()); } -TEST_F(LayoutWorkletTest, RegisterLayout_NoIntrinsicSizes) { +TEST_P(LayoutWorkletTest, RegisterLayout_NoIntrinsicSizes) { ScriptState::Scope scope(GetScriptState()); ScriptEvaluationResult result = EvaluateScriptModule(R"JS( registerLayout('foo', class { @@ -170,11 +173,10 @@ )JS"); // "The 'intrinsicSizes' property on the prototype does not exist." - EXPECT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kException); + EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty()); } -TEST_F(LayoutWorkletTest, RegisterLayout_ThrowingPropertyGetter) { +TEST_P(LayoutWorkletTest, RegisterLayout_ThrowingPropertyGetter) { ScriptState::Scope scope(GetScriptState()); ScriptEvaluationResult result = EvaluateScriptModule(R"JS( registerLayout('foo', class { @@ -183,11 +185,10 @@ )JS"); // "Uncaught Error" - EXPECT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kException); + EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty()); } -TEST_F(LayoutWorkletTest, RegisterLayout_BadPropertyGetter) { +TEST_P(LayoutWorkletTest, RegisterLayout_BadPropertyGetter) { ScriptState::Scope scope(GetScriptState()); ScriptEvaluationResult result = EvaluateScriptModule(R"JS( registerLayout('foo', class { @@ -196,11 +197,10 @@ )JS"); // "The provided value cannot be converted to a sequence." - EXPECT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kException); + EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty()); } -TEST_F(LayoutWorkletTest, RegisterLayout_NoPrototype) { +TEST_P(LayoutWorkletTest, RegisterLayout_NoPrototype) { ScriptState::Scope scope(GetScriptState()); ScriptEvaluationResult result = EvaluateScriptModule(R"JS( const foo = function() { }; @@ -209,11 +209,10 @@ )JS"); // "The 'prototype' object on the class does not exist." - EXPECT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kException); + EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty()); } -TEST_F(LayoutWorkletTest, RegisterLayout_BadPrototype) { +TEST_P(LayoutWorkletTest, RegisterLayout_BadPrototype) { ScriptState::Scope scope(GetScriptState()); ScriptEvaluationResult result = EvaluateScriptModule(R"JS( const foo = function() { }; @@ -222,11 +221,10 @@ )JS"); // "The 'prototype' property on the class is not an object." - EXPECT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kException); + EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty()); } -TEST_F(LayoutWorkletTest, RegisterLayout_BadIntrinsicSizes) { +TEST_P(LayoutWorkletTest, RegisterLayout_BadIntrinsicSizes) { ScriptState::Scope scope(GetScriptState()); ScriptEvaluationResult result = EvaluateScriptModule(R"JS( registerLayout('foo', class { @@ -235,11 +233,10 @@ )JS"); // "The 'intrinsicSizes' property on the prototype is not a function." - EXPECT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kException); + EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty()); } -TEST_F(LayoutWorkletTest, RegisterLayout_NoLayout) { +TEST_P(LayoutWorkletTest, RegisterLayout_NoLayout) { ScriptState::Scope scope(GetScriptState()); ScriptEvaluationResult result = EvaluateScriptModule(R"JS( registerLayout('foo', class { @@ -248,11 +245,10 @@ )JS"); // "The 'layout' property on the prototype does not exist." - EXPECT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kException); + EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty()); } -TEST_F(LayoutWorkletTest, RegisterLayout_BadLayout) { +TEST_P(LayoutWorkletTest, RegisterLayout_BadLayout) { ScriptState::Scope scope(GetScriptState()); ScriptEvaluationResult result = EvaluateScriptModule(R"JS( registerLayout('foo', class { @@ -262,8 +258,13 @@ )JS"); // "The 'layout' property on the prototype is not a function." - EXPECT_EQ(result.GetResultType(), - ScriptEvaluationResult::ResultType::kException); + EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty()); } +// Instantiate tests once with TLA and once without: +INSTANTIATE_TEST_SUITE_P(LayoutWorkletTestGroup, + LayoutWorkletTest, + testing::Bool(), + ParametrizedModuleTestParamName()); + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc index 9d9a3fd8..4c681e1 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -101,11 +101,11 @@ const NGConstraintSpace& container_space, NGBoxFragmentBuilder* container_builder, base::Optional<LogicalSize> initial_containing_block_fixed_size) - : container_space_(container_space), - container_builder_(container_builder), + : container_builder_(container_builder), writing_mode_(container_style.GetWritingMode()), is_absolute_container_(is_absolute_container), - is_fixed_container_(is_fixed_container) { + is_fixed_container_(is_fixed_container), + has_block_fragmentation_(container_space.HasBlockFragmentation()) { if (!container_builder->HasOutOfFlowPositionedCandidates() && !To<LayoutBlock>(container_builder_->GetLayoutObject()) ->HasPositionedObjects()) @@ -129,7 +129,7 @@ void NGOutOfFlowLayoutPart::Run(const LayoutBox* only_layout) { if (container_builder_->IsBlockFragmentationContextRoot() && - !container_space_.HasBlockFragmentation() && + !has_block_fragmentation_ && container_builder_->HasOutOfFlowFragmentainerDescendants()) { Vector<NGLogicalOutOfFlowPositionedNode> fragmentainer_descendants; container_builder_->SwapOutOfFlowFragmentainerDescendants( @@ -194,7 +194,7 @@ // every OOF candidate not in placed_objects, and treat them as a legacy // object (even if they aren't one), while in fact it could be an NG object // that we have finished laying out in an earlier fragmentainer. Just bail. - if (container_space_.HasBlockFragmentation()) + if (has_block_fragmentation_) return; wtf_size_t prev_placed_objects_size = placed_objects.size(); @@ -496,7 +496,7 @@ candidate.static_position); if (IsContainingBlockForCandidate(candidate) && (!only_layout || layout_box == only_layout)) { - if (container_space_.HasBlockFragmentation()) { + if (has_block_fragmentation_) { // If the containing block is fragmented, adjust the offset to be from // the first containing block fragment to the fragmentation context // root. Also, adjust the static position to be relative to the
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h index d83971a..fce60a25 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -149,7 +149,6 @@ wtf_size_t* start_index, LogicalOffset* offset) const; - const NGConstraintSpace& container_space_; NGBoxFragmentBuilder* container_builder_; ContainingBlockInfo default_containing_block_; HashMap<const LayoutObject*, ContainingBlockInfo> containing_blocks_map_; @@ -167,6 +166,7 @@ bool is_absolute_container_; bool is_fixed_container_; bool allow_first_tier_oof_cache_; + bool has_block_fragmentation_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc b/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc index c30d3c1..29e0c88 100644 --- a/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc +++ b/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.cc
@@ -84,6 +84,12 @@ return frame->GetPage()->Paused(); } +bool FrameResourceFetcherProperties::IsLoadDeferred() const { + LocalFrame* frame = document_->GetFrame(); + DCHECK(frame); + return frame->IsLoadDeferred(); +} + bool FrameResourceFetcherProperties::IsLoadComplete() const { return document_->LoadEventFinished(); }
diff --git a/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h b/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h index ce8860e..f9c804f 100644 --- a/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h +++ b/third_party/blink/renderer/core/loader/frame_resource_fetcher_properties.h
@@ -36,6 +36,7 @@ int64_t ServiceWorkerId() const override; bool IsPaused() const override; bool IsDetached() const override { return false; } + bool IsLoadDeferred() const override; bool IsLoadComplete() const override; bool ShouldBlockLoadingSubResource() const override; bool IsSubframeDeprioritizationEnabled() const override;
diff --git a/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc b/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc index 470f225..c194c617 100644 --- a/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc +++ b/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.cc
@@ -38,6 +38,10 @@ return global_scope_->IsContextPaused(); } +bool WorkerResourceFetcherProperties::IsLoadDeferred() const { + return global_scope_->IsLoadDeferred(); +} + const KURL& WorkerResourceFetcherProperties::WebBundlePhysicalUrl() const { return NullURL(); }
diff --git a/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h b/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h index 7629561..5944709d 100644 --- a/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h +++ b/third_party/blink/renderer/core/loader/worker_resource_fetcher_properties.h
@@ -43,6 +43,7 @@ } bool IsPaused() const override; bool IsDetached() const override { return false; } + bool IsLoadDeferred() const override; bool IsLoadComplete() const override { return false; } bool ShouldBlockLoadingSubResource() const override { return false; } bool IsSubframeDeprioritizationEnabled() const override { return false; }
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc index f6bc709..7f9fb75 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
@@ -57,9 +57,9 @@ } // Stream channels. - auto& stream_channels = serialized_script_value->GetStreamChannels(); - result.message->GetStreamChannels().AppendRange(stream_channels.begin(), - stream_channels.end()); + for (auto& stream : serialized_script_value->GetStreams()) { + result.message->GetStreams().push_back(std::move(stream)); + } // Array buffer contents array. auto& source_array_buffer_contents_array = serialized_script_value->GetArrayBufferContentsArray(); @@ -149,8 +149,10 @@ message.stack_trace_should_pause); result.locked_agent_cluster_id = message.locked_agent_cluster_id; result.ports.AppendRange(message.ports.begin(), message.ports.end()); - result.message->GetStreamChannels().AppendRange( - message.stream_channels.begin(), message.stream_channels.end()); + for (auto& channel : message.stream_channels) { + result.message->GetStreams().push_back( + SerializedScriptValue::Stream(channel.ReleaseHandle())); + } if (message.user_activation) { result.user_activation = mojom::blink::UserActivationSnapshot::New( message.user_activation->has_been_active,
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc index 431ef9e2..38f7a1c6 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc
@@ -48,9 +48,10 @@ out->ports.ReserveInitialCapacity(ports.size()); out->ports.AppendRange(std::make_move_iterator(ports.begin()), std::make_move_iterator(ports.end())); - out->message->GetStreamChannels().AppendRange( - std::make_move_iterator(stream_channels.begin()), - std::make_move_iterator(stream_channels.end())); + for (auto& channel : stream_channels) { + out->message->GetStreams().push_back( + blink::SerializedScriptValue::Stream(std::move(channel))); + } out->message->SetArrayBufferContentsArray( std::move(array_buffer_contents_array));
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.h b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.h index 9ef5a0a3..c52434c 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.h +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.h
@@ -38,10 +38,10 @@ static Vector<blink::MessagePortDescriptor> stream_channels( blink::BlinkTransferableMessage& input) { Vector<blink::MessagePortDescriptor> result; - auto& stream_channels = input.message->GetStreamChannels(); - result.ReserveInitialCapacity(stream_channels.size()); - for (const auto& port : stream_channels) - result.push_back(port.ReleaseHandle()); + auto& streams = input.message->GetStreams(); + result.ReserveInitialCapacity(streams.size()); + for (const auto& stream : streams) + result.push_back(stream.channel.ReleaseHandle()); return result; }
diff --git a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor_test.cc b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor_test.cc index 7db6a31..1ccd3378 100644 --- a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor_test.cc
@@ -119,4 +119,33 @@ EXPECT_FALSE(target->NeedsCompositingInputsUpdate()); } +TEST_F(PaintLayerCompositorTest, SubframeRebuildGraphicsLayers) { + GetDocument().SetBaseURLOverride(KURL("http://test.com")); + SetBodyInnerHTML("<iframe src='http://test.com'></iframe>"); + SetChildFrameHTML( + "<div id='target' style='will-change: opacity; opacity: 0.5'></div>"); + + UpdateAllLifecyclePhasesForTest(); + auto* child_layout_view = ChildDocument().GetLayoutView(); + auto* child_root_graphics_layer = + child_layout_view->Layer()->GraphicsLayerBacking(child_layout_view); + ASSERT_TRUE(child_root_graphics_layer); + EXPECT_EQ(GetLayoutView().Layer()->GraphicsLayerBacking(), + child_root_graphics_layer->Parent()); + + // This simulates that the subframe rebuilds GraphicsLayer tree, while the + // main frame doesn't have any compositing flags set. The root GraphicsLayer + // of the subframe should be hooked up in the GraphicsLayer tree correctly. + child_root_graphics_layer->RemoveFromParent(); + child_layout_view->Compositor()->SetNeedsCompositingUpdate( + kCompositingUpdateRebuildTree); + GetLayoutView().Compositor()->UpdateAssignmentsIfNeededRecursive( + DocumentLifecycle::kCompositingAssignmentsClean); + ASSERT_EQ( + child_root_graphics_layer, + child_layout_view->Layer()->GraphicsLayerBacking(child_layout_view)); + EXPECT_EQ(GetLayoutView().Layer()->GraphicsLayerBacking(), + child_root_graphics_layer->Parent()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/build.gni b/third_party/blink/renderer/core/streams/build.gni index c917899..504be89 100644 --- a/third_party/blink/renderer/core/streams/build.gni +++ b/third_party/blink/renderer/core/streams/build.gni
@@ -30,6 +30,7 @@ "readable_stream_default_reader.h", "readable_stream_reader.cc", "readable_stream_reader.h", + "readable_stream_transferring_optimizer.h", "stream_algorithms.h", "stream_promise_resolver.cc", "stream_promise_resolver.h", @@ -49,4 +50,5 @@ "writable_stream_default_controller.h", "writable_stream_default_writer.cc", "writable_stream_default_writer.h", + "writable_stream_transferring_optimizer.h", ]
diff --git a/third_party/blink/renderer/core/streams/readable_stream_transferring_optimizer.h b/third_party/blink/renderer/core/streams/readable_stream_transferring_optimizer.h new file mode 100644 index 0000000..fee43c4 --- /dev/null +++ b/third_party/blink/renderer/core/streams/readable_stream_transferring_optimizer.h
@@ -0,0 +1,46 @@ +// Copyright 2020 The Chromium AUthors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_READABLE_STREAM_TRANSFERRING_OPTIMIZER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_READABLE_STREAM_TRANSFERRING_OPTIMIZER_H_ + +#include "third_party/blink/renderer/core/core_export.h" + +namespace blink { + +class UnderlyingSourceBase; +class ScriptState; + +// ReadableStreamTransferringOptimizer is the base class used to optimize +// transferring a ReadableStream. Please see +// https://docs.google.com/document/d/1_KuZzg5c3pncLJPFa8SuVm23AP4tft6mzPCL5at3I9M/. +// +// A ReadableStreamTransferringOptimizer is associated with the source of a +// ReadableStream. When transferring the stream in another realm, the optimizer +// is used to construct the transferred stream in the destination realm. Note +// that two realms can be in different threads (in the same process), in which +// case the optimizer is used across threads. +class CORE_EXPORT ReadableStreamTransferringOptimizer { + USING_FAST_MALLOC(ReadableStreamTransferringOptimizer); + + public: + ReadableStreamTransferringOptimizer() = default; + ReadableStreamTransferringOptimizer( + const ReadableStreamTransferringOptimizer&) = delete; + ReadableStreamTransferringOptimizer& operator=( + const ReadableStreamTransferringOptimizer&) = delete; + virtual ~ReadableStreamTransferringOptimizer() = default; + + // Returns an UnderlyingSourceBase for the associated source. This method may + // return null, in which case it is no-op. + // This method can be called at most once. + virtual UnderlyingSourceBase* PerformInProcessOptimization( + ScriptState* script_state) { + return nullptr; + } +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_READABLE_STREAM_TRANSFERRING_OPTIMIZER_H_
diff --git a/third_party/blink/renderer/core/streams/writable_stream_transferring_optimizer.h b/third_party/blink/renderer/core/streams/writable_stream_transferring_optimizer.h new file mode 100644 index 0000000..a5858b8 --- /dev/null +++ b/third_party/blink/renderer/core/streams/writable_stream_transferring_optimizer.h
@@ -0,0 +1,46 @@ +// Copyright 2020 The Chromium AUthors. All rights reserved. +// Use of this sink code is governed by a BSD-style license that can be found +// in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_WRITABLE_STREAM_TRANSFERRING_OPTIMIZER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_WRITABLE_STREAM_TRANSFERRING_OPTIMIZER_H_ + +#include "third_party/blink/renderer/core/core_export.h" + +namespace blink { + +class UnderlyingSinkBase; +class ScriptState; + +// WritableStreamTransferringOptimizer is the base class used to optimize +// transferring a WritableStream. Please see +// https://docs.google.com/document/d/1_KuZzg5c3pncLJPFa8SuVm23AP4tft6mzPCL5at3I9M/. +// +// A WritableStreamTransferringOptimizer is associated with the sink of a +// WritableStream. When transferring the stream in another realm, the optimizer +// is used to construct the transferred stream in the destination realm. Note +// that two realms can be in different threads (in the same process), in which +// case the optimizer is used across threads. +class CORE_EXPORT WritableStreamTransferringOptimizer { + USING_FAST_MALLOC(WritableStreamTransferringOptimizer); + + public: + WritableStreamTransferringOptimizer() = default; + WritableStreamTransferringOptimizer( + const WritableStreamTransferringOptimizer&) = delete; + WritableStreamTransferringOptimizer& operator=( + const WritableStreamTransferringOptimizer&) = delete; + virtual ~WritableStreamTransferringOptimizer() = default; + + // Returns an UnderlyingSinkBase for the associated sink. This method may + // return null, in which case it is no-op. + // This method can be called at most once. + virtual UnderlyingSinkBase* PerformInProcessOptimization( + ScriptState* script_state) { + return nullptr; + } +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_WRITABLE_STREAM_TRANSFERRING_OPTIMIZER_H_
diff --git a/third_party/blink/renderer/core/testing/module_test_base.cc b/third_party/blink/renderer/core/testing/module_test_base.cc index 2894ed4..9ddbd8d 100644 --- a/third_party/blink/renderer/core/testing/module_test_base.cc +++ b/third_party/blink/renderer/core/testing/module_test_base.cc
@@ -3,24 +3,22 @@ // found in the LICENSE file. #include "third_party/blink/renderer/core/testing/module_test_base.h" +#include "third_party/blink/renderer/bindings/core/v8/script_function.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" namespace blink { -void ParametrizedModuleTest::SetUp() { - if (UseTopLevelAwait()) { +void ParametrizedModuleTestBase::SetUp(bool use_top_level_await) { + if (use_top_level_await) { feature_list_.InitAndEnableFeature(features::kTopLevelAwait); } else { feature_list_.InitAndDisableFeature(features::kTopLevelAwait); } - SetV8Flags(UseTopLevelAwait()); + SetV8Flags(use_top_level_await); } -void ParametrizedModuleTest::TearDown() { - feature_list_.Reset(); - SetV8Flags(base::FeatureList::IsEnabled(features::kTopLevelAwait)); -} - -void ParametrizedModuleTest::SetV8Flags(bool use_top_level_await) { +void ParametrizedModuleTestBase::SetV8Flags(bool use_top_level_await) { if (use_top_level_await) { v8::V8::SetFlagsFromString("--harmony-top-level-await"); } else { @@ -28,4 +26,99 @@ } } +void ParametrizedModuleTest::SetUp() { + ParametrizedModuleTestBase::SetUp(UseTopLevelAwait()); +} + +class SaveResultFunction final : public ScriptFunction { + public: + explicit SaveResultFunction(ScriptState* script_state) + : ScriptFunction(script_state) {} + + v8::Local<v8::Function> Bind() { return BindToV8Function(); } + + v8::Local<v8::Value> GetResult() { + EXPECT_TRUE(result_); + EXPECT_FALSE(result_->IsEmpty()); + return result_->V8Value(); + } + + private: + ScriptValue Call(ScriptValue value) override { + *result_ = value; + return value; + } + + ScriptValue* result_ = nullptr; +}; + +class ExpectNotReached final : public ScriptFunction { + public: + static v8::Local<v8::Function> Create(ScriptState* script_state) { + auto* self = MakeGarbageCollected<ExpectNotReached>(script_state); + return self->BindToV8Function(); + } + explicit ExpectNotReached(ScriptState* script_state) + : ScriptFunction(script_state) {} + + private: + ScriptValue Call(ScriptValue value) override { + ADD_FAILURE() << "ExpectNotReached was reached"; + return value; + } +}; + +v8::Local<v8::Value> ParametrizedModuleTestBase::GetResult( + ScriptState* script_state, + ScriptEvaluationResult result) { + CHECK_EQ(result.GetResultType(), + ScriptEvaluationResult::ResultType::kSuccess); + if (!base::FeatureList::IsEnabled(features::kTopLevelAwait)) { + return result.GetSuccessValue(); + } + + ScriptPromise script_promise = result.GetPromise(script_state); + v8::Local<v8::Promise> promise = script_promise.V8Value().As<v8::Promise>(); + if (promise->State() == v8::Promise::kFulfilled) { + return promise->Result(); + } + + auto* resolve_function = + MakeGarbageCollected<SaveResultFunction>(script_state); + result.GetPromise(script_state) + .Then(resolve_function->Bind(), ExpectNotReached::Create(script_state)); + + v8::MicrotasksScope::PerformCheckpoint(script_state->GetIsolate()); + + return resolve_function->GetResult(); +} + +v8::Local<v8::Value> ParametrizedModuleTestBase::GetException( + ScriptState* script_state, + ScriptEvaluationResult result) { + if (!base::FeatureList::IsEnabled(features::kTopLevelAwait)) { + CHECK_EQ(result.GetResultType(), + ScriptEvaluationResult::ResultType::kException); + return result.GetExceptionForModule(); + } + + CHECK_EQ(result.GetResultType(), + ScriptEvaluationResult::ResultType::kSuccess); + + ScriptPromise script_promise = result.GetPromise(script_state); + v8::Local<v8::Promise> promise = script_promise.V8Value().As<v8::Promise>(); + if (promise->State() == v8::Promise::kRejected) { + return promise->Result(); + } + + auto* reject_function = + MakeGarbageCollected<SaveResultFunction>(script_state); + script_promise.Then(ExpectNotReached::Create(script_state), + reject_function->Bind()); + + v8::MicrotasksScope::PerformCheckpoint(script_state->GetIsolate()); + + return reject_function->GetResult(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/testing/module_test_base.h b/third_party/blink/renderer/core/testing/module_test_base.h index 11c70357..a9762b9 100644 --- a/third_party/blink/renderer/core/testing/module_test_base.h +++ b/third_party/blink/renderer/core/testing/module_test_base.h
@@ -8,21 +8,38 @@ #include <gtest/gtest.h> #include "base/test/scoped_feature_list.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/renderer/bindings/core/v8/script_evaluation_result.h" #include "v8/include/v8.h" namespace blink { // Helper used to enable or disable top-level await in parametrized tests. -class ParametrizedModuleTest : public testing::WithParamInterface<bool> { +class ParametrizedModuleTestBase { protected: - void SetUp(); - void TearDown(); - - bool UseTopLevelAwait() { return GetParam(); } - base::test::ScopedFeatureList feature_list_; + void SetUp(bool use_top_level_await); + void TearDown() {} + // Get the results of a ScriptEvaluationResult from a module. + // If top-level await is enabled, the method will wait for the result + // Promise to be resolved. + v8::Local<v8::Value> GetResult(ScriptState* script_state, + ScriptEvaluationResult result); + // Get the exception of a ScriptEvaluationResult from a module. + // If top-level await is enabled, the method will wait for the result + // Promise to be rejected. + v8::Local<v8::Value> GetException(ScriptState* script_state, + ScriptEvaluationResult result); private: void SetV8Flags(bool use_top_level_await); + base::test::ScopedFeatureList feature_list_; +}; + +class ParametrizedModuleTest : public ParametrizedModuleTestBase, + public testing::WithParamInterface<bool> { + protected: + void SetUp(); + + bool UseTopLevelAwait() { return GetParam(); } }; // Used in INSTANTIATE_TEST_SUITE_P for returning more readable test names.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc b/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc index 6c92712c..badb6d7 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc
@@ -761,8 +761,8 @@ TEST_F(AccessibilitySelectionTest, FromCurrentSelectionInTextareaWithCollapsedSelectionAndAffinity) { - // TODO(crbug.com/1140302): This test fails with LayoutNGTextArea. - ScopedLayoutNGTextAreaForTest scope(false); + // TODO(crbug.com/1140302): This test fails with LayoutNGTextControl. + ScopedLayoutNGTextControlForTest scope(false); SetBodyInnerHTML(R"HTML( <textarea id="textarea"
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc index f34366d..b910fa3 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc
@@ -28,6 +28,7 @@ #include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h" #include "third_party/blink/renderer/core/script/js_module_script.h" #include "third_party/blink/renderer/core/script/script.h" +#include "third_party/blink/renderer/core/testing/module_test_base.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h" #include "third_party/blink/renderer/core/workers/worker_backing_thread.h" @@ -55,14 +56,21 @@ // The test uses OfflineAudioWorkletThread because the test does not have a // strict real-time constraint. -class AudioWorkletGlobalScopeTest : public PageTestBase { +class AudioWorkletGlobalScopeTest : public PageTestBase, + public ParametrizedModuleTest { public: void SetUp() override { + ParametrizedModuleTest::SetUp(); PageTestBase::SetUp(IntSize()); NavigateTo(KURL("https://example.com/")); reporting_proxy_ = std::make_unique<WorkerReportingProxy>(); } + void TearDown() override { + PageTestBase::TearDown(); + ParametrizedModuleTest::TearDown(); + } + std::unique_ptr<OfflineAudioWorkletThread> CreateAudioWorkletThread() { std::unique_ptr<OfflineAudioWorkletThread> thread = std::make_unique<OfflineAudioWorkletThread>(*reporting_proxy_); @@ -133,9 +141,9 @@ } private: - // Returns false when a script evaluation error happens. - bool EvaluateScriptModule(AudioWorkletGlobalScope* global_scope, - const String& source_code) { + void ExpectEvaluateScriptModule(AudioWorkletGlobalScope* global_scope, + const String& source_code, + bool expect_success) { ScriptState* script_state = global_scope->ScriptController()->GetScriptState(); EXPECT_TRUE(script_state); @@ -153,8 +161,11 @@ JSModuleScript::CreateForTest(Modulator::From(script_state), module, js_url) ->RunScriptAndReturnValue(); - return result.GetResultType() == - ScriptEvaluationResult::ResultType::kSuccess; + if (expect_success) { + EXPECT_FALSE(GetResult(script_state, result).IsEmpty()); + } else { + EXPECT_FALSE(GetException(script_state, result).IsEmpty()); + } } // Test if AudioWorkletGlobalScope and V8 components (ScriptState, Isolate) @@ -184,7 +195,7 @@ } registerProcessor('testProcessor', TestProcessor); )JS"; - ASSERT_TRUE(EvaluateScriptModule(global_scope, source_code)); + ExpectEvaluateScriptModule(global_scope, source_code, true); AudioWorkletProcessorDefinition* definition = global_scope->FindDefinition("testProcessor"); @@ -233,7 +244,7 @@ class2.prototype = { process: function () {} }; registerProcessor('class2', class2); )JS"; - ASSERT_TRUE(EvaluateScriptModule(global_scope, source_code)); + ExpectEvaluateScriptModule(global_scope, source_code, true); EXPECT_TRUE(global_scope->FindDefinition("class1")); EXPECT_TRUE(global_scope->FindDefinition("class2")); } @@ -253,7 +264,7 @@ }); registerProcessor('class3', class3); )JS"; - ASSERT_FALSE(EvaluateScriptModule(global_scope, source_code)); + ExpectEvaluateScriptModule(global_scope, source_code, false); EXPECT_FALSE(global_scope->FindDefinition("class3")); } @@ -289,7 +300,7 @@ } registerProcessor('testProcessor', TestProcessor); )JS"; - ASSERT_TRUE(EvaluateScriptModule(global_scope, source_code)); + ExpectEvaluateScriptModule(global_scope, source_code, true); auto* channel = MakeGarbageCollected<MessageChannel>(thread->GlobalScope()); MessagePortChannel dummy_port_channel = channel->port2()->Disentangle(); @@ -354,7 +365,7 @@ } registerProcessor('testProcessor', TestProcessor); )JS"; - ASSERT_TRUE(EvaluateScriptModule(global_scope, source_code)); + ExpectEvaluateScriptModule(global_scope, source_code, true); AudioWorkletProcessorDefinition* definition = global_scope->FindDefinition("testProcessor"); @@ -377,7 +388,7 @@ std::unique_ptr<WorkerReportingProxy> reporting_proxy_; }; -TEST_F(AudioWorkletGlobalScopeTest, Basic) { +TEST_P(AudioWorkletGlobalScopeTest, Basic) { std::unique_ptr<OfflineAudioWorkletThread> thread = CreateAudioWorkletThread(); RunBasicTest(thread.get()); @@ -385,7 +396,7 @@ thread->WaitForShutdownForTesting(); } -TEST_F(AudioWorkletGlobalScopeTest, Parsing) { +TEST_P(AudioWorkletGlobalScopeTest, Parsing) { std::unique_ptr<OfflineAudioWorkletThread> thread = CreateAudioWorkletThread(); RunParsingTest(thread.get()); @@ -393,7 +404,7 @@ thread->WaitForShutdownForTesting(); } -TEST_F(AudioWorkletGlobalScopeTest, BufferProcessing) { +TEST_P(AudioWorkletGlobalScopeTest, BufferProcessing) { std::unique_ptr<OfflineAudioWorkletThread> thread = CreateAudioWorkletThread(); RunSimpleProcessTest(thread.get()); @@ -401,7 +412,7 @@ thread->WaitForShutdownForTesting(); } -TEST_F(AudioWorkletGlobalScopeTest, ParsingParameterDescriptor) { +TEST_P(AudioWorkletGlobalScopeTest, ParsingParameterDescriptor) { std::unique_ptr<OfflineAudioWorkletThread> thread = CreateAudioWorkletThread(); RunParsingParameterDescriptorTest(thread.get()); @@ -409,4 +420,10 @@ thread->WaitForShutdownForTesting(); } +// Instantiate tests once with TLA and once without: +INSTANTIATE_TEST_SUITE_P(AudioWorkletGlobalScopeTestGroup, + AudioWorkletGlobalScopeTest, + testing::Bool(), + ParametrizedModuleTestParamName()); + } // namespace blink
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc index 6314257..040f70d 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc
@@ -30,6 +30,7 @@ #include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h" #include "third_party/blink/renderer/core/script/js_module_script.h" #include "third_party/blink/renderer/core/script/script.h" +#include "third_party/blink/renderer/core/testing/module_test_base.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h" #include "third_party/blink/renderer/core/workers/worker_backing_thread.h" @@ -46,9 +47,14 @@ namespace blink { -class AudioWorkletThreadTest : public PageTestBase { +class AudioWorkletThreadTestBase : public PageTestBase, + public ParametrizedModuleTestBase { public: + explicit AudioWorkletThreadTestBase(bool use_top_level_await) + : use_top_level_await_(use_top_level_await) {} + void SetUp() override { + ParametrizedModuleTestBase::SetUp(use_top_level_await_); PageTestBase::SetUp(IntSize()); NavigateTo(KURL("https://example.com/")); reporting_proxy_ = std::make_unique<WorkerReportingProxy>(); @@ -58,6 +64,7 @@ OfflineAudioWorkletThread::ClearSharedBackingThread(); RealtimeAudioWorkletThread::ClearSharedBackingThread(); SemiRealtimeAudioWorkletThread::ClearSharedBackingThread(); + ParametrizedModuleTestBase::TearDown(); } std::unique_ptr<WorkerThread> CreateAudioWorkletThread( @@ -77,7 +84,7 @@ PostCrossThreadTask( *thread->GetWorkerBackingThread().BackingThread().GetTaskRunner(), FROM_HERE, - CrossThreadBindOnce(&AudioWorkletThreadTest::ExecuteScriptInWorklet, + CrossThreadBindOnce(&AudioWorkletThreadTestBase::ExecuteScriptInWorklet, CrossThreadUnretained(this), CrossThreadUnretained(thread), CrossThreadUnretained(&wait_event))); @@ -131,9 +138,16 @@ } std::unique_ptr<WorkerReportingProxy> reporting_proxy_; + bool use_top_level_await_; }; -TEST_F(AudioWorkletThreadTest, Basic) { +class AudioWorkletThreadTest : public AudioWorkletThreadTestBase, + public testing::WithParamInterface<bool> { + public: + AudioWorkletThreadTest() : AudioWorkletThreadTestBase(GetParam()) {} +}; + +TEST_P(AudioWorkletThreadTest, Basic) { std::unique_ptr<WorkerThread> audio_worklet_thread = CreateAudioWorkletThread(true, true); CheckWorkletCanExecuteScript(audio_worklet_thread.get()); @@ -143,7 +157,7 @@ // Creates 2 different AudioWorkletThreads with different RT constraints. // Checks if they are running on a different thread. -TEST_F(AudioWorkletThreadTest, CreateDifferentWorkletThreadsAndTerminate_1) { +TEST_P(AudioWorkletThreadTest, CreateDifferentWorkletThreadsAndTerminate_1) { // Create RealtimeAudioWorkletThread. std::unique_ptr<WorkerThread> first_worklet_thread = CreateAudioWorkletThread(true, true); @@ -170,7 +184,7 @@ // Creates 2 AudioWorkletThreads with RT constraint from 2 different // originating frames. Checks if they are running on a different thread. -TEST_F(AudioWorkletThreadTest, CreateDifferentWorkletThreadsAndTerminate_2) { +TEST_P(AudioWorkletThreadTest, CreateDifferentWorkletThreadsAndTerminate_2) { // Create an AudioWorkletThread from a main frame with RT constraint. std::unique_ptr<WorkerThread> first_worklet_thread = CreateAudioWorkletThread(true, true); @@ -195,17 +209,24 @@ second_worklet_thread->WaitForShutdownForTesting(); } +// Instantiate tests once with TLA and once without: +INSTANTIATE_TEST_SUITE_P(AudioWorkletThreadTestGroup, + AudioWorkletThreadTest, + testing::Bool(), + ParametrizedModuleTestParamName()); + class AudioWorkletThreadInteractionTest - : public AudioWorkletThreadTest, - public testing::WithParamInterface<std::tuple<bool, bool>> { + : public AudioWorkletThreadTestBase, + public testing::WithParamInterface<std::tuple<bool, bool, bool>> { public: AudioWorkletThreadInteractionTest() - : has_realtime_constraint_(std::get<0>(GetParam())), - is_top_level_frame_(std::get<1>(GetParam())) {} + : AudioWorkletThreadTestBase(std::get<0>(GetParam())), + has_realtime_constraint_(std::get<1>(GetParam())), + is_top_level_frame_(std::get<2>(GetParam())) {} - protected: - const bool has_realtime_constraint_; - const bool is_top_level_frame_; + protected: + const bool has_realtime_constraint_; + const bool is_top_level_frame_; }; TEST_P(AudioWorkletThreadInteractionTest, CreateSecondAndTerminateFirst) { @@ -296,11 +317,14 @@ second_worklet_thread->WaitForShutdownForTesting(); } -INSTANTIATE_TEST_SUITE_P(AudioWorkletThreadInteractionTest, +INSTANTIATE_TEST_SUITE_P(AudioWorkletThreadInteractionTestGroup, AudioWorkletThreadInteractionTest, - testing::Combine(testing::Bool(), testing::Bool())); + testing::Combine(testing::Bool(), + testing::Bool(), + testing::Bool())); struct ThreadPriorityTestParam { + const bool use_top_level_await; const bool has_realtime_constraint; const bool is_top_level_frame; const bool is_flag_enabled; @@ -311,30 +335,43 @@ // A real-time priority thread is guaranteed when the context has real-time // constraint and is spawned from a top-level frame. The flag setting // is ignored. - {true, true, true, base::ThreadPriority::REALTIME_AUDIO}, - {true, true, false, base::ThreadPriority::REALTIME_AUDIO}, + {false, true, true, true, base::ThreadPriority::REALTIME_AUDIO}, + {false, true, true, false, base::ThreadPriority::REALTIME_AUDIO}, + // With top-level-await module: + {true, true, true, true, base::ThreadPriority::REALTIME_AUDIO}, + {true, true, true, false, base::ThreadPriority::REALTIME_AUDIO}, // A DISPLAY priority thread is given when the context has real-time // constraint but is spawned from a sub frame. - {true, false, false, base::ThreadPriority::DISPLAY}, + {false, true, false, false, base::ThreadPriority::DISPLAY}, + // With top-level-await module: + {true, true, false, false, base::ThreadPriority::DISPLAY}, // Enabling the real-time thread flag will override thread priority logic // for a real-time context. - {true, false, true, base::ThreadPriority::REALTIME_AUDIO}, + {false, true, false, true, base::ThreadPriority::REALTIME_AUDIO}, + // With top-level-await module: + {true, true, false, true, base::ThreadPriority::REALTIME_AUDIO}, // OfflineAudioWorkletThread is always a NORMAL priority no matter what // the flag setting or the originating frame level is. - {false, true, true, base::ThreadPriority::NORMAL}, - {false, true, false, base::ThreadPriority::NORMAL}, - {false, false, true, base::ThreadPriority::NORMAL}, - {false, false, false, base::ThreadPriority::NORMAL}, + {false, false, true, true, base::ThreadPriority::NORMAL}, + {false, false, true, false, base::ThreadPriority::NORMAL}, + {false, false, false, true, base::ThreadPriority::NORMAL}, + {false, false, false, false, base::ThreadPriority::NORMAL}, + // With top-level-await module: + {true, false, true, true, base::ThreadPriority::NORMAL}, + {true, false, true, false, base::ThreadPriority::NORMAL}, + {true, false, false, true, base::ThreadPriority::NORMAL}, + {true, false, false, false, base::ThreadPriority::NORMAL}, }; class AudioWorkletThreadPriorityTest - : public AudioWorkletThreadTest, + : public AudioWorkletThreadTestBase, public testing::WithParamInterface<ThreadPriorityTestParam> { public: - AudioWorkletThreadPriorityTest() = default; + AudioWorkletThreadPriorityTest() + : AudioWorkletThreadTestBase(GetParam().use_top_level_await) {} void InitAndSetRealtimePriorityFlag(bool is_flag_enabled) { if (is_flag_enabled) { @@ -394,7 +431,6 @@ wait_event->Signal(); } - base::test::ScopedFeatureList feature_list_; }; @@ -406,7 +442,7 @@ test_param.expected_priority); } -INSTANTIATE_TEST_SUITE_P(AudioWorkletThreadPriorityTest, +INSTANTIATE_TEST_SUITE_P(AudioWorkletThreadPriorityTestGroup, AudioWorkletThreadPriorityTest, testing::ValuesIn(kThreadPriorityTestParams));
diff --git a/third_party/blink/renderer/modules/worklet/animation_and_paint_worklet_thread_test.cc b/third_party/blink/renderer/modules/worklet/animation_and_paint_worklet_thread_test.cc index 84d6002..af9515a 100644 --- a/third_party/blink/renderer/modules/worklet/animation_and_paint_worklet_thread_test.cc +++ b/third_party/blink/renderer/modules/worklet/animation_and_paint_worklet_thread_test.cc
@@ -16,6 +16,7 @@ #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/script/js_module_script.h" #include "third_party/blink/renderer/core/script/script.h" +#include "third_party/blink/renderer/core/testing/module_test_base.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h" #include "third_party/blink/renderer/core/workers/worker_backing_thread.h" @@ -42,14 +43,21 @@ } // namespace -class AnimationAndPaintWorkletThreadTest : public PageTestBase { +class AnimationAndPaintWorkletThreadTest : public PageTestBase, + public ParametrizedModuleTest { public: void SetUp() override { + ParametrizedModuleTest::SetUp(); PageTestBase::SetUp(IntSize()); NavigateTo(KURL("https://example.com/")); reporting_proxy_ = std::make_unique<WorkerReportingProxy>(); } + void TearDown() override { + PageTestBase::TearDown(); + ParametrizedModuleTest::TearDown(); + } + // Attempts to run some simple script for |thread|. void CheckWorkletCanExecuteScript(WorkerThread* thread) { std::unique_ptr<base::WaitableEvent> wait_event = @@ -82,16 +90,16 @@ ScriptValue exception = ModuleRecord::Instantiate(script_state, module, js_url); EXPECT_TRUE(exception.IsEmpty()); - EXPECT_EQ(JSModuleScript::CreateForTest(Modulator::From(script_state), - module, js_url) - ->RunScriptAndReturnValue() - .GetResultType(), - ScriptEvaluationResult::ResultType::kSuccess); + ScriptEvaluationResult result = + JSModuleScript::CreateForTest(Modulator::From(script_state), module, + js_url) + ->RunScriptAndReturnValue(); + EXPECT_FALSE(GetResult(script_state, result).IsEmpty()); wait_event->Signal(); } }; -TEST_F(AnimationAndPaintWorkletThreadTest, Basic) { +TEST_P(AnimationAndPaintWorkletThreadTest, Basic) { std::unique_ptr<AnimationAndPaintWorkletThread> worklet = CreateThreadAndProvideAnimationWorkletProxyClient(&GetDocument(), reporting_proxy_.get()); @@ -102,7 +110,7 @@ // Tests that the same WebThread is used for new worklets if the WebThread is // still alive. -TEST_F(AnimationAndPaintWorkletThreadTest, CreateSecondAndTerminateFirst) { +TEST_P(AnimationAndPaintWorkletThreadTest, CreateSecondAndTerminateFirst) { // Create the first worklet and wait until it is initialized. std::unique_ptr<AnimationAndPaintWorkletThread> first_worklet = CreateThreadAndProvideAnimationWorkletProxyClient(&GetDocument(), @@ -140,7 +148,7 @@ // Tests that the WebThread is reused if all existing worklets are terminated // before a new worklet is created, as long as the worklets are not destructed. -TEST_F(AnimationAndPaintWorkletThreadTest, TerminateFirstAndCreateSecond) { +TEST_P(AnimationAndPaintWorkletThreadTest, TerminateFirstAndCreateSecond) { // Create the first worklet, wait until it is initialized, and terminate it. std::unique_ptr<AnimationAndPaintWorkletThread> worklet = CreateThreadAndProvideAnimationWorkletProxyClient(&GetDocument(), @@ -165,7 +173,7 @@ // Tests that v8::Isolate and WebThread are correctly set-up if a worklet is // created while another is terminating. -TEST_F(AnimationAndPaintWorkletThreadTest, +TEST_P(AnimationAndPaintWorkletThreadTest, CreatingSecondDuringTerminationOfFirst) { std::unique_ptr<AnimationAndPaintWorkletThread> first_worklet = CreateThreadAndProvideAnimationWorkletProxyClient(&GetDocument(), @@ -198,7 +206,7 @@ // Tests that the backing thread is correctly created, torn down, and recreated // as AnimationWorkletThreads are created and destroyed. -TEST_F(AnimationAndPaintWorkletThreadTest, +TEST_P(AnimationAndPaintWorkletThreadTest, WorkletThreadHolderIsRefCountedProperly) { EXPECT_FALSE( AnimationAndPaintWorkletThread::GetWorkletThreadHolderForTesting()); @@ -242,4 +250,9 @@ worklet3->WaitForShutdownForTesting(); } +// Instantiate tests once with TLA and once without: +INSTANTIATE_TEST_SUITE_P(AnimationAndPaintWorkletThreadTestGroup, + AnimationAndPaintWorkletThreadTest, + testing::Bool(), + ParametrizedModuleTestParamName()); } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc index c6ecaa7..1e23b59 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -1155,14 +1155,9 @@ } void CanvasResourceProvider::OnContextDestroyed() { - if (canvas_image_provider_) { - if (!UseOopRasterization()) { - DCHECK(skia_canvas_); - skia_canvas_->reset_image_provider(); - } - - canvas_image_provider_.reset(); - } + if (skia_canvas_) + skia_canvas_->reset_image_provider(); + canvas_image_provider_.reset(); } void CanvasResourceProvider::OnFlushForImage(PaintImage::ContentId content_id) {
diff --git a/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h b/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h index 893e4b2..98e2295 100644 --- a/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h +++ b/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h
@@ -37,6 +37,7 @@ } bool IsPaused() const override { return false; } bool IsDetached() const override { return true; } + bool IsLoadDeferred() const override { return false; } bool IsLoadComplete() const override { return true; } bool ShouldBlockLoadingSubResource() const override { return true; } bool IsSubframeDeprioritizationEnabled() const override { return false; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h index cbb33a1..0fbb2d13 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h
@@ -69,6 +69,11 @@ // operations with "keepalive" specified). virtual bool IsDetached() const = 0; + // Returns whether the loading is deferred. When true, loading tasks keep + // running but the data is queued in the loading pipeline on the renderer. + // Upon resume the data is given to client modules such as scripts. + virtual bool IsLoadDeferred() const = 0; + // Returns whether the main resource for this global context is loaded. virtual bool IsLoadComplete() const = 0; @@ -131,6 +136,9 @@ bool IsDetached() const override { return properties_ ? properties_->IsDetached() : true; } + bool IsLoadDeferred() const override { + return properties_ ? properties_->IsLoadDeferred() : false; + } bool IsLoadComplete() const override { return properties_ ? properties_->IsLoadComplete() : load_complete_; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 4e9bde5..03469fa1 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -414,10 +414,15 @@ if (!RequestContextObserveResponse(request_context)) { if (auto* frame_or_worker_scheduler = fetcher->GetFrameOrWorkerScheduler()) { - feature_handle_for_scheduler_ = - frame_or_worker_scheduler->RegisterFeature( - GetFeatureFromRequestContextType(request_context), - {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + // Only when this feature is turned on and the loading tasks keep being + // processed and the data is queued up on the renderer, a page can stay in + // BackForwardCache with network requests. + if (!base::FeatureList::IsEnabled(features::kLoadingTasksUnfreezable)) { + feature_handle_for_scheduler_ = + frame_or_worker_scheduler->RegisterFeature( + GetFeatureFromRequestContextType(request_context), + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + } } } @@ -565,19 +570,20 @@ DCHECK(loader_); if (resource_->Options().synchronous_policy == kRequestSynchronously && - fetcher_->GetProperties().IsPaused()) { + fetcher_->GetProperties().IsLoadDeferred()) { + // TODO(yuzus): Evict bfcache if necessary. Cancel(); return; } is_downloading_to_blob_ = request.DownloadToBlob(); - SetDefersLoading(fetcher_->GetProperties().IsPaused()); + SetDefersLoading(fetcher_->GetProperties().IsLoadDeferred()); if (ShouldFetchCodeCache()) { code_cache_request_ = std::make_unique<CodeCacheRequest>( fetcher_->CreateCodeCacheLoader(), request.Url(), - fetcher_->GetProperties().IsPaused()); + fetcher_->GetProperties().IsLoadDeferred()); } if (is_cache_aware_loading_activated_) {
diff --git a/third_party/blink/renderer/platform/loader/frame_request_blocker.cc b/third_party/blink/renderer/platform/loader/frame_request_blocker.cc index ad412da..857143f 100644 --- a/third_party/blink/renderer/platform/loader/frame_request_blocker.cc +++ b/third_party/blink/renderer/platform/loader/frame_request_blocker.cc
@@ -41,12 +41,6 @@ delegate_->Resume(); } - void Cancel() override { - frame_request_blocker_->RemoveObserver(this); - frame_request_blocker_ = nullptr; - delegate_->CancelWithError(net::ERR_FAILED); - } - private: scoped_refptr<FrameRequestBlocker> frame_request_blocker_; }; @@ -68,12 +62,6 @@ clients_->Notify(FROM_HERE, &Client::Resume); } -void FrameRequestBlocker::Cancel() { - DCHECK(blocked_.IsOne()); - blocked_.Decrement(); - clients_->Notify(FROM_HERE, &Client::Cancel); -} - std::unique_ptr<URLLoaderThrottle> FrameRequestBlocker::GetThrottleIfRequestsBlocked() { if (blocked_.IsZero())
diff --git a/third_party/blink/renderer/platform/loader/frame_request_blocker.h b/third_party/blink/renderer/platform/loader/frame_request_blocker.h index 42803e5..f362a9b 100644 --- a/third_party/blink/renderer/platform/loader/frame_request_blocker.h +++ b/third_party/blink/renderer/platform/loader/frame_request_blocker.h
@@ -25,16 +25,12 @@ // Resumes any blocked subresource requests. void Resume() override; - // Cancels any blocked subresource requests. - void Cancel() override; - std::unique_ptr<URLLoaderThrottle> GetThrottleIfRequestsBlocked() override; private: class Client { public: virtual void Resume() = 0; - virtual void Cancel() = 0; }; friend class base::RefCountedThreadSafe<FrameRequestBlocker>;
diff --git a/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h b/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h index 8095add..6245044 100644 --- a/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h +++ b/third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h
@@ -45,6 +45,7 @@ } bool IsPaused() const override { return paused_; } bool IsDetached() const override { return false; } + bool IsLoadDeferred() const override { return false; } bool IsLoadComplete() const override { return load_complete_; } bool ShouldBlockLoadingSubResource() const override { return should_block_loading_sub_resource_;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index e6f4742f..4195750 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1082,12 +1082,7 @@ name: "LayoutNGTable", }, { - name: "LayoutNGTextArea", - depends_on: ["EditingNG"], - status: "experimental", - }, - { - name: "LayoutNGTextField", + name: "LayoutNGTextControl", depends_on: ["EditingNG"], status: "experimental", },
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index ae3c235..b13d5022 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -88,6 +88,8 @@ crbug.com/901056 virtual/synchronous_html_parser/http/tests/inspector-protocol/network/initiator-minified.js [ Failure ] crbug.com/901056 virtual/synchronous_html_parser/external/wpt/signed-exchange/subresource/sxg-subresource.tentative.html [ Failure Timeout ] +# Temporarily disable until linear memory inspector module is landed +crbug.com/1110202 http/tests/devtools/modules-load-source.js [ Pass Failure ] # ====== Site Isolation failures from here ====== # See also third_party/blink/web_tests/virtual/not-site-per-process/README.md @@ -5666,9 +5668,6 @@ crbug.com/1006759 http/tests/devtools/profiler/cpu-profiler-save-load.js [ Pass Failure Timeout ] crbug.com/1006759 http/tests/devtools/profiler/heap-snapshot-loader.js [ Pass Failure ] -# Disabled for DevTools change -crbug.com/1057090 http/tests/devtools/console/console-format-table.js [ Pass Failure ] - # Temporarily disabled to land changes in DevTools, multiple dependent CLs # [1] https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2049183 # [2] https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2119670
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content-crash.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content-crash.html new file mode 100644 index 0000000..a6e8fa7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content-crash.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<link rel="help" href="http://crbug.com/1146872"> +<body> +<fieldset><span><span></span></span></fieldset> +<div id="host"><span></span></div> +<script> +const host = document.querySelector('#host'); +const shadowRoot = host.attachShadow({mode: 'closed'}); +const fieldset = shadowRoot.appendChild(document.createElement('fieldset')); +fieldset.setAttribute('style', 'overflow: scroll'); +fieldset.innerHTML = '<slot></slot>'; +</script> +<style> +*:not(fieldset, div) { + position: sticky; + bottom: 72pc; +} +fieldset { + overflow: visible scroll; +} +</style> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/OWNERS b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/OWNERS new file mode 100644 index 0000000..9b2e5be --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/OWNERS
@@ -0,0 +1,3 @@ +# TEAM: layout-dev@chromium.org +# COMPONENT: Blink>Layout +# WPT-NOTIFY: true
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-abssize.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-abssize.html new file mode 100644 index 0000000..ba55da868 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-abssize.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1116832"> +<link rel="match" href="reference/green-ref.html"> +<frameset cols="4294967227%,*" frameborder="0"> + <frame src="resources/green.html"> + <frame src="resources/red.html"> +</frameset>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-percentage.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-percentage.html new file mode 100644 index 0000000..ba55da868 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-percentage.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1116832"> +<link rel="match" href="reference/green-ref.html"> +<frameset cols="4294967227%,*" frameborder="0"> + <frame src="resources/green.html"> + <frame src="resources/red.html"> +</frameset>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-relsize.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-relsize.html new file mode 100644 index 0000000..1bfb2b5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-relsize.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1116832"> +<link rel="match" href="reference/green-ref.html"> +<frameset cols="4294967227*,*" frameborder="0"> + <frame src="resources/green.html"> + <frame src="resources/red.html"> +</frameset>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-abssize.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-abssize.html new file mode 100644 index 0000000..7cd86b9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-abssize.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1116832"> +<link rel="match" href="reference/green-ref.html"> +<frameset rows="4294967227%,*" frameborder="0"> + <frame src="resources/green.html"> + <frame src="resources/red.html"> +</frameset>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-percentage.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-percentage.html new file mode 100644 index 0000000..7cd86b9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-percentage.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1116832"> +<link rel="match" href="reference/green-ref.html"> +<frameset rows="4294967227%,*" frameborder="0"> + <frame src="resources/green.html"> + <frame src="resources/red.html"> +</frameset>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-relsize.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-relsize.html new file mode 100644 index 0000000..7fd29f6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-relsize.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1116832"> +<link rel="match" href="reference/green-ref.html"> +<frameset rows="4294967227*,*" frameborder="0"> + <frame src="resources/green.html"> + <frame src="resources/red.html"> +</frameset>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/green-ref.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/green-ref.html new file mode 100644 index 0000000..62208d72 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/green-ref.html
@@ -0,0 +1,5 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<style> + body { background: green; } +</style>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/green.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/green.html new file mode 100644 index 0000000..62208d72 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/green.html
@@ -0,0 +1,5 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<style> + body { background: green; } +</style>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/red.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/red.html new file mode 100644 index 0000000..b5e7f796 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/red.html
@@ -0,0 +1,5 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<style> + body { background: red; } +</style>
diff --git a/third_party/blink/web_tests/fast/forms/file/file-appearance-basic.html b/third_party/blink/web_tests/fast/forms/file/file-appearance-basic.html index 9543c41a..11d60b6 100644 --- a/third_party/blink/web_tests/fast/forms/file/file-appearance-basic.html +++ b/third_party/blink/web_tests/fast/forms/file/file-appearance-basic.html
@@ -71,4 +71,15 @@ <input type=file class="button-shadow"> <div> +<div> +<style> +.overflow { + overflow: visible; + width: 10px; +} +</style> +'overflow: visible' should not work: +<input type=file class=overflow> +</div> + </body>
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/forms/file/file-appearance-basic-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/forms/file/file-appearance-basic-expected.png index 493fb74..4bd2811b 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/forms/file/file-appearance-basic-expected.png +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/forms/file/file-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-display-locked-grid-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-display-locked-grid-expected.txt new file mode 100644 index 0000000..a6a1c7c --- /dev/null +++ b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-display-locked-grid-expected.txt
@@ -0,0 +1,196 @@ +Tests highlights for display locking. + +container{ + "paths": [ + { + "path": [ + "M", + 8, + 8, + "L", + 792, + 8, + "L", + 792, + 18, + "L", + 8, + 18, + "Z" + ], + "fillColor": "rgba(255, 0, 0, 0)", + "outlineColor": "rgba(128, 0, 0, 0)", + "name": "content" + }, + { + "path": [ + "M", + 8, + 8, + "L", + 792, + 8, + "L", + 792, + 18, + "L", + 8, + 18, + "Z" + ], + "fillColor": "rgba(0, 255, 0, 0)", + "name": "padding" + }, + { + "path": [ + "M", + 8, + 8, + "L", + 792, + 8, + "L", + 792, + 18, + "L", + 8, + 18, + "Z" + ], + "fillColor": "rgba(0, 0, 255, 0)", + "name": "border" + }, + { + "path": [ + "M", + 8, + 8, + "L", + 792, + 8, + "L", + 792, + 18, + "L", + 8, + 18, + "Z" + ], + "fillColor": "rgba(255, 255, 255, 0)", + "name": "margin" + } + ], + "showRulers": true, + "showExtensionLines": true, + "showAccessibilityInfo": true, + "colorFormat": "hex", + "elementInfo": { + "tagName": "div", + "idValue": "container", + "nodeWidth": "784", + "nodeHeight": "10", + "isKeyboardFocusable": false, + "accessibleName": "", + "accessibleRole": "generic", + "layoutObjectName": "LayoutGrid", + "showAccessibilityInfo": true + } +} +child{ + "paths": [ + { + "path": [ + "M", + 8, + 8, + "L", + 792, + 8, + "L", + 792, + 18, + "L", + 8, + 18, + "Z" + ], + "fillColor": "rgba(255, 0, 0, 0)", + "outlineColor": "rgba(128, 0, 0, 0)", + "name": "content" + }, + { + "path": [ + "M", + 8, + 8, + "L", + 792, + 8, + "L", + 792, + 18, + "L", + 8, + 18, + "Z" + ], + "fillColor": "rgba(0, 255, 0, 0)", + "name": "padding" + }, + { + "path": [ + "M", + 8, + 8, + "L", + 792, + 8, + "L", + 792, + 18, + "L", + 8, + 18, + "Z" + ], + "fillColor": "rgba(0, 0, 255, 0)", + "name": "border" + }, + { + "path": [ + "M", + 8, + 8, + "L", + 792, + 8, + "L", + 792, + 18, + "L", + 8, + 18, + "Z" + ], + "fillColor": "rgba(255, 255, 255, 0)", + "name": "margin" + } + ], + "showRulers": true, + "showExtensionLines": true, + "showAccessibilityInfo": true, + "colorFormat": "hex", + "elementInfo": { + "tagName": "div", + "idValue": "container", + "nodeWidth": "784", + "nodeHeight": "10", + "isKeyboardFocusable": false, + "accessibleName": "", + "accessibleRole": "generic", + "layoutObjectName": "LayoutGrid", + "isLockedAncestor": "true", + "showAccessibilityInfo": true + } +} +
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-display-locked-grid.js b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-display-locked-grid.js new file mode 100644 index 0000000..1fccc22 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-display-locked-grid.js
@@ -0,0 +1,32 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`Tests highlights for display locking.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.loadModule('console_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <style> + #container { + display: grid; + grid-template-rows: 1fr 1fr; + grid-template-columns: 1fr 1fr; + } + </style> + <div id="container" style="content-visibility: hidden; contain-intrinsic-size: 10px;"> + <div id="child" style="width: 50px; height: 50px; background: blue">Text</div> + </div> + `); + + function dumpChild() { + ElementsTestRunner.dumpInspectorHighlightJSON('child', TestRunner.completeTest.bind(TestRunner)); + } + + function dumpContainerAndChild() { + ElementsTestRunner.dumpInspectorHighlightJSON('container', dumpChild); + } + + dumpContainerAndChild(); +})();
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/file/file-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/file/file-appearance-basic-expected.png index a0a18f7..56ff0c99 100644 --- a/third_party/blink/web_tests/platform/linux/fast/forms/file/file-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/forms/file/file-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac-arm11.0/fast/forms/file/file-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac-arm11.0/fast/forms/file/file-appearance-basic-expected.png new file mode 100644 index 0000000..6114e9e --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac-arm11.0/fast/forms/file/file-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/file/file-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/file/file-appearance-basic-expected.png index 6114e9e..0fb310c4 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/file/file-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/forms/file/file-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/file/file-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/file/file-appearance-basic-expected.png index a183c13..b789a00 100644 --- a/third_party/blink/web_tests/platform/win/fast/forms/file/file-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/forms/file/file-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/file/file-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/file/file-appearance-basic-expected.png new file mode 100644 index 0000000..a183c13 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/fast/forms/file/file-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt b/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt index c7fc4ea..6d253e6 100644 --- a/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt +++ b/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt
@@ -2,7 +2,7 @@ FAIL Same-origin blob URL iframe should inherit service worker controller. assert_equals: blob URL iframe should inherit controller expected (string) "https://web-platform.test:8444/service-workers/service-worker/resources/local-url-inherit-controller-worker.js" but got (object) null FAIL Same-origin blob URL iframe should intercept fetch(). assert_equals: blob URL iframe should intercept fetch expected "intercepted" but got "Hello world\n" FAIL Same-origin blob URL worker should inherit service worker controller. promise_test: Unhandled rejection with value: "Uncaught TypeError: Cannot read property 'controller' of undefined" -FAIL Same-origin blob URL worker should intercept fetch(). assert_equals: blob URL worker should intercept fetch expected "intercepted" but got "Hello world\n" +PASS Same-origin blob URL worker should intercept fetch(). PASS Data URL iframe should not intercept fetch(). FAIL Data URL worker should not inherit service worker controller. promise_test: Unhandled rejection with value: "Uncaught TypeError: Cannot read property 'controller' of undefined" PASS Data URL worker should not intercept fetch().
diff --git a/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/sandboxed-iframe-fetch-event.https-expected.txt b/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/sandboxed-iframe-fetch-event.https-expected.txt deleted file mode 100644 index 7eaa466..0000000 --- a/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/sandboxed-iframe-fetch-event.https-expected.txt +++ /dev/null
@@ -1,32 +0,0 @@ -This is a testharness.js-based test. -PASS Prepare a service worker. -PASS Prepare a normal iframe. -PASS Prepare an iframe sandboxed by <iframe sandbox="allow-scripts">. -PASS Prepare an iframe sandboxed by <iframe sandbox="allow-scripts allow-same-origin">. -PASS Prepare an iframe sandboxed by CSP HTTP header with allow-scripts. -PASS Prepare an iframe sandboxed by CSP HTTP header with allow-scripts and allow-same-origin. -PASS Fetch request from a normal iframe -FAIL Fetch request from a worker in a normal iframe assert_equals: The fetch request should be handled by SW. expected 1 but got 0 -PASS Request for an iframe in the normal iframe -PASS Request for an sandboxed iframe with allow-scripts flag in the normal iframe -PASS Request for an sandboxed iframe with allow-scripts and allow-same-origin flag in the normal iframe -PASS Fetch request from iframe sandboxed by an attribute with allow-scripts flag -PASS Fetch request from a worker in iframe sandboxed by an attribute with allow-scripts flag -PASS Request for an iframe in the iframe sandboxed by an attribute with allow-scripts flag -PASS Request for an sandboxed iframe with allow-scripts flag in the iframe sandboxed by an attribute with allow-scripts flag -PASS Request for an sandboxed iframe with allow-scripts and allow-same-origin flag in the iframe sandboxed by an attribute with allow-scripts flag -PASS Fetch request from iframe sandboxed by an attribute with allow-scripts and allow-same-origin flag -FAIL Fetch request from a worker in iframe sandboxed by an attribute with allow-scripts and allow-same-origin flag assert_equals: The fetch request should be handled by SW. expected 1 but got 0 -PASS Request for an iframe in the iframe sandboxed by an attribute with allow-scripts and allow-same-origin flag -PASS Request for an sandboxed iframe with allow-scripts flag in the iframe sandboxed by attribute with allow-scripts and allow-same-origin flag -PASS Request for an sandboxed iframe with allow-scripts and allow-same-origin flag in the iframe sandboxed by attribute with allow-scripts and allow-same-origin flag -PASS Fetch request from iframe sandboxed by CSP HTTP header with allow-scripts flag -PASS Request for an iframe in the iframe sandboxed by CSP HTTP header with allow-scripts flag -PASS Request for an sandboxed iframe with allow-scripts flag in the iframe sandboxed by CSP HTTP header with allow-scripts flag -PASS Request for an sandboxed iframe with allow-scripts and allow-same-origin flag in the iframe sandboxed by CSP HTTP header with allow-scripts flag -PASS Fetch request from iframe sandboxed by CSP HTTP header with allow-scripts and allow-same-origin flag -PASS Request for an iframe in the iframe sandboxed by CSP HTTP header with allow-scripts and allow-same-origin flag -PASS Request for an sandboxed iframe with allow-scripts flag in the iframe sandboxed by CSP HTTP header with allow-scripts and allow-same-origin flag -PASS Request for an sandboxed iframe with allow-scripts and allow-same-origin flag in the iframe sandboxed by CSP HTTP header with allow-scripts and allow-same-origin flag -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https-expected.txt b/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https-expected.txt deleted file mode 100644 index 1150895f..0000000 --- a/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS Prepare a service worker. -PASS Prepare an iframe sandboxed by CSP HTTP header with allow-scripts. -PASS Prepare an iframe sandboxed by CSP HTTP header with allow-scripts and allow-same-origin. -PASS Fetch request from a worker in iframe sandboxed by CSP HTTP header allow-scripts flag -FAIL Fetch request from a worker in iframe sandboxed by CSP HTTP header with allow-scripts and allow-same-origin flag assert_equals: The request should be handled by SW. expected 1 but got 0 -Harness: the test ran to completion. -
diff --git a/third_party/closure_compiler/externs/terminal_private.js b/third_party/closure_compiler/externs/terminal_private.js index 709db0b1..d57249b6 100644 --- a/third_party/closure_compiler/externs/terminal_private.js +++ b/third_party/closure_compiler/externs/terminal_private.js
@@ -77,11 +77,10 @@ * Called from |onProcessOutput| when the event is dispatched to terminal * extension. Observing the terminal process output will be paused after * |onProcessOutput| is dispatched until this method is called. - * @param {number} tabId Tab ID from |onProcessOutput| event. * @param {string} id The id of the process to which |onProcessOutput| was * dispatched. */ -chrome.terminalPrivate.ackOutput = function(tabId, id) {}; +chrome.terminalPrivate.ackOutput = function(id) {}; /** * Open the Terminal tabbed window.
diff --git a/tools/json_schema_compiler/cpp_bundle_generator.py b/tools/json_schema_compiler/cpp_bundle_generator.py index 494efd60..1f35fd9 100644 --- a/tools/json_schema_compiler/cpp_bundle_generator.py +++ b/tools/json_schema_compiler/cpp_bundle_generator.py
@@ -347,7 +347,7 @@ c.Append('#include <algorithm>') c.Append('#include <iterator>') c.Append() - c.Append('#include "base/stl_util.h"') + c.Append('#include "base/ranges/algorithm.h"') c.Append() c.Append('namespace {') for api in self._bundle._api_defs: @@ -393,8 +393,8 @@ schema_constant_name = _FormatNameAsConstant(namespace) c.Append('{"%s", %s},' % (namespace, schema_constant_name)) c.Eblock('};') - c.Append('static_assert(base::STLIsSorted(kSchemas), "|kSchemas| should be ' - 'sorted.");') + c.Append('static_assert(base::ranges::is_sorted(kSchemas), "|kSchemas| ' + 'should be sorted.");') c.Sblock('auto it = std::lower_bound(std::begin(kSchemas), ' 'std::end(kSchemas),')
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 3132407..e2ad6c0 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -12443,6 +12443,7 @@ <int value="30" label="Shop Similar Products"/> <int value="31" label="Shop image with Google Lens"/> <int value="32" label="Search Similar Products"/> + <int value="33" label="Read later"/> </enum> <enum name="ContextMenuOptionDesktop"> @@ -42495,7 +42496,6 @@ <int value="-1417642561" label="AutofillCreditCardUploadFeedback:enabled"/> <int value="-1417122729" label="AutofillCreditCardAblationExperiment:disabled"/> - <int value="-1416758392" label="migrate-linux-to-logindb:disabled"/> <int value="-1416754663" label="enable-mac-views-native-app-windows"/> <int value="-1416184931" label="TranslateRankerEnforcement:enabled"/> <int value="-1412230070" label="query-tiles-instant-background-task"/> @@ -42983,7 +42983,6 @@ <int value="-972737445" label="ArcUseAuthEndpoint:disabled"/> <int value="-972425050" label="gesture-editing"/> <int value="-970067535" label="BackgroundTaskComponentUpdate:disabled"/> - <int value="-969815853" label="migrate-linux-to-logindb:enabled"/> <int value="-969332901" label="stop-non-timers-in-background:disabled"/> <int value="-969028093" label="FullRestore:disabled"/> <int value="-968675274" label="Rar2Fs:enabled"/> @@ -43286,6 +43285,8 @@ <int value="-665514294" label="FontAccess:disabled"/> <int value="-663476391" label="enable-pixel-canvas-recording:enabled"/> <int value="-662720891" label="PreviewsCoinFlipHoldback_UKMOnly:enabled"/> + <int value="-662314979" + label="AutofillEnableSaveCardInfoBarAccountIndicationFooter:disabled"/> <int value="-662064703" label="MediaSessionService:enabled"/> <int value="-661978438" label="enable-data-reduction-proxy-lo-fi"/> <int value="-660160292" label="enable-apps-show-on-first-paint"/> @@ -43555,6 +43556,8 @@ <int value="-385337473" label="enable-fast-unload"/> <int value="-384589459" label="disable-supervised-user-safesites"/> <int value="-381181808" label="DragAppsInTabletMode:enabled"/> + <int value="-380992110" + label="AutofillEnableSaveCardInfoBarAccountIndicationFooter:enabled"/> <int value="-379809954" label="AutofillDoNotMigrateUnsupportedLocalCards:disabled"/> <int value="-378218969" label="VaapiJpegImageDecodeAcceleration:disabled"/> @@ -44959,6 +44962,7 @@ <int value="1027252926" label="SyncSupportSecondaryAccount:enabled"/> <int value="1028817487" label="OmniboxOnFocusSuggestionsContextualWeb:disabled"/> + <int value="1030608602" label="AutofillAssistantProactiveHelp:enabled"/> <int value="1033148287" label="NTPShortcuts:disabled"/> <int value="1033412163" label="OmniboxDisplayTitleForCurrentUrl:enabled"/> <int value="1033597574" label="disable-layer-squashing"/> @@ -45804,6 +45808,7 @@ <int value="1854226565" label="AutofillNoLocalSaveOnUnmaskSuccess:enabled"/> <int value="1854646491" label="DetailedLanguageSettings:disabled"/> <int value="1855524566" label="allow-insecure-websocket-from-https-origin"/> + <int value="1856270952" label="AutofillAssistantProactiveHelp:disabled"/> <int value="1857000695" label="SendWebUIJavaScriptErrorReports:disabled"/> <int value="1858385315" label="ChromeHomeBottomNavLabels:enabled"/> <int value="1858919054" label="SplitSettingsSync:disabled"/> @@ -73606,6 +73611,12 @@ <int value="14" label="I/O device error."/> </enum> +<enum name="UnsolicitedHttpsRecordStatus"> + <int value="0" label="Malformed"/> + <int value="1" label="Alias"/> + <int value="2" label="Service"/> +</enum> + <enum name="UnsupportedContainers"> <int value="0" label="3GP"/> <int value="1" label="TS"/>
diff --git a/tools/metrics/histograms/histograms_xml/blink/histograms.xml b/tools/metrics/histograms/histograms_xml/blink/histograms.xml index 415e456..b473382 100644 --- a/tools/metrics/histograms/histograms_xml/blink/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
@@ -1157,6 +1157,9 @@ <histogram base="true" name="Blink.MainFrame.AnimateRatio" units="%" expires_after="2020-11-08"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1169,6 +1172,9 @@ <histogram base="true" name="Blink.MainFrame.CompositingAssignmentsRatio" units="%" expires_after="2020-11-08"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1181,6 +1187,9 @@ <histogram base="true" name="Blink.MainFrame.CompositingCommitRatio" units="%" expires_after="2020-11-08"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1193,6 +1202,9 @@ <histogram base="true" name="Blink.MainFrame.CompositingInputsRatio" units="%" expires_after="2020-11-08"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1205,6 +1217,9 @@ <histogram base="true" name="Blink.MainFrame.CompositingRatio" units="%" expires_after="2020-11-08"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1217,6 +1232,9 @@ <histogram base="true" name="Blink.MainFrame.ForcedStyleAndLayoutRatio" units="%" expires_after="2021-01-10"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1230,6 +1248,9 @@ <histogram base="true" name="Blink.MainFrame.HandleInputEventsRatio" units="%" expires_after="2020-11-08"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1242,6 +1263,9 @@ <histogram base="true" name="Blink.MainFrame.HitTestDocumentUpdateRatio" units="%" expires_after="2020-11-08"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1254,6 +1278,9 @@ <histogram base="true" name="Blink.MainFrame.ImplCompositorCommitRatio" units="%" expires_after="2020-11-08"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1267,6 +1294,9 @@ <histogram base="true" name="Blink.MainFrame.IntersectionObservationRatio" units="%" expires_after="2020-11-08"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1279,6 +1309,9 @@ <histogram base="true" name="Blink.MainFrame.LayoutRatio" units="%" expires_after="2021-03-21"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1291,6 +1324,9 @@ <histogram base="true" name="Blink.MainFrame.PaintRatio" units="%" expires_after="2021-03-21"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1303,6 +1339,9 @@ <histogram base="true" name="Blink.MainFrame.PrePaintRatio" units="%" expires_after="2020-11-08"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1332,6 +1371,9 @@ <histogram base="true" name="Blink.MainFrame.StyleRatio" units="%" expires_after="2020-11-08"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1344,6 +1386,9 @@ <histogram base="true" name="Blink.MainFrame.UpdateLayersRatio" units="%" expires_after="2021-03-21"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" --> @@ -1374,6 +1419,9 @@ <histogram name="Blink.MainFrame.WaitForCommitRatio" units="%" expires_after="2020-11-08"> + <obsolete> + Removed M88 due to lack of use. + </obsolete> <owner>schenney@chromium.org</owner> <owner>paint-dev@chromium.org</owner> <!-- Name completed by histogram_suffixes name="BlinkMainFrameUpdateTimeSuffixes" -->
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml index 1bd5a62f..e6563a9d 100644 --- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -5087,6 +5087,9 @@ </histogram_suffixes> <histogram_suffixes name="DiscardReason" separator="."> + <obsolete> + Removed 11/2020. All affected histograms were removed. + </obsolete> <suffix name="Extension" label="An extension discarded a tab."/> <suffix name="Proactive" label="The browser proactively discarded a tab to avoid entering a
diff --git a/tools/metrics/histograms/histograms_xml/net/histograms.xml b/tools/metrics/histograms/histograms_xml/net/histograms.xml index 356eed7..3a2bb72 100644 --- a/tools/metrics/histograms/histograms_xml/net/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/net/histograms.xml
@@ -536,6 +536,28 @@ </summary> </histogram> +<histogram name="Net.DNS.DnsTask.AdditionalHttps.Requested" + enum="UnsolicitedHttpsRecordStatus" expires_after="2021-08-06"> + <owner>ericorth@chromium.org</owner> + <owner>dmcardle@chromium.org</owner> + <summary> + Status of HTTPS DNS records received as additional records in a DnsTask + querying for HTTPS. This would represent a recurssive resolver that is + HTTPS-aware and performing followup queries on behalf of the client. + Recorded as DNS responses are parsed. + </summary> +</histogram> + +<histogram name="Net.DNS.DnsTask.AdditionalHttps.Unsolicited" + enum="UnsolicitedHttpsRecordStatus" expires_after="2021-08-06"> + <owner>ericorth@chromium.org</owner> + <owner>dmcardle@chromium.org</owner> + <summary> + Status of HTTPS DNS records received as additional records in a DnsTask + querying for a type other than HTTPS. Recorded as DNS responses are parsed. + </summary> +</histogram> + <histogram name="Net.DNS.DnsTask.ErrorBeforeFallback.Fast" enum="NetErrorCodes" expires_after="M77"> <owner>pauljensen@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index ea4fa1c..86627640 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -3802,6 +3802,9 @@ </histogram> <histogram name="Discarding.OnlineOnReload" enum="Boolean" expires_after="M85"> + <obsolete> + Removed 11/2020. + </obsolete> <!-- Name completed by histogram_suffixes name="DiscardReason" --> <owner>fdoray@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/password/histograms.xml b/tools/metrics/histograms/histograms_xml/password/histograms.xml index ee5fc76..68fc0983 100644 --- a/tools/metrics/histograms/histograms_xml/password/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/password/histograms.xml
@@ -176,20 +176,22 @@ </histogram> <histogram name="PasswordManager.AccountChooserDialogMultipleAccounts" - enum="AccountChooserDismissalReason" expires_after="2020-12-12"> + enum="AccountChooserDismissalReason" expires_after="2021-06-01"> <owner>vasilii@chromium.org</owner> <owner>jdoerrie@chromium.org</owner> <summary> - The dismissal reason of the account chooser with multiple accounts. + The dismissal reason of the account chooser with multiple accounts. Recorded + when the account chooser is dismissed. </summary> </histogram> <histogram name="PasswordManager.AccountChooserDialogOneAccount" - enum="AccountChooserDismissalReason" expires_after="2020-12-12"> + enum="AccountChooserDismissalReason" expires_after="2021-06-01"> <owner>vasilii@chromium.org</owner> <owner>jdoerrie@chromium.org</owner> <summary> - The dismissal reason of the account chooser with one account. + The dismissal reason of the account chooser with one account. Recorded when + the account chooser is dismissed. </summary> </histogram> @@ -445,49 +447,59 @@ </summary> </histogram> -<histogram name="PasswordManager.AccountStoreVsProfileStore.Additional" +<histogram name="PasswordManager.AccountStoreVsProfileStore.{DifferenceType}" units="accounts" expires_after="M90"> <owner>mamir@chromium.org</owner> <owner>treib@chromium.org</owner> <summary> - The number of accounts stored in the password manager's account-scoped store - that don't exist in the profile-scoped store. Recorded once per run of - Chrome, soon after startup. + The number of accounts {DifferenceType}. Recorded once per run of Chrome, + soon after startup. Recorded independent of whether the user is opted in to + the account-scoped storage or not, i.e. will contain a lot of useless + entries - you might want to look at AccountStoreVsProfileStore2 instead. </summary> + <token key="DifferenceType"> + <variant name="Additional" + summary="stored in the password manager's account-scoped store that + don't exist in the profile-scoped store"/> + <variant name="Conflicting" + summary="stored in the password manager with a conflicting password + between the account-scoped store and profile-scoped store + (i.e. the signon realm and username match, but the password + does not)"/> + <variant name="Identical" + summary="stored in both the password manager's account-scoped store + and profile-scoped store"/> + <variant name="Missing" + summary="stored in the password manager's profile-scoped store that + don't exist in the account-scoped store"/> + </token> </histogram> -<histogram name="PasswordManager.AccountStoreVsProfileStore.Conflicting" +<histogram name="PasswordManager.AccountStoreVsProfileStore2.{DifferenceType}" units="accounts" expires_after="M90"> <owner>mamir@chromium.org</owner> <owner>treib@chromium.org</owner> <summary> - The number of accounts stored in the password manager with a conflicting - password between the account-scoped store and profile-scoped store (i.e. the - signon realm and username match, but the password does not). Recorded once - per run of Chrome, soon after startup. + The number of accounts {DifferenceType}. Recorded once per run of Chrome, + soon after startup, only for users who are opted in to the account-scoped + storage. </summary> -</histogram> - -<histogram name="PasswordManager.AccountStoreVsProfileStore.Identical" - units="accounts" expires_after="M90"> - <owner>mamir@chromium.org</owner> - <owner>treib@chromium.org</owner> - <summary> - The number of accounts stored in both the password manager's account-scoped - store and profile-scoped store. Recorded once per run of Chrome, soon after - startup. - </summary> -</histogram> - -<histogram name="PasswordManager.AccountStoreVsProfileStore.Missing" - units="accounts" expires_after="M90"> - <owner>mamir@chromium.org</owner> - <owner>treib@chromium.org</owner> - <summary> - The number of accounts stored in the password manager's profile-scoped store - that don't exist in the account-scoped store. Recorded once per run of - Chrome, soon after startup. - </summary> + <token key="DifferenceType"> + <variant name="Additional" + summary="stored in the password manager's account-scoped store that + don't exist in the profile-scoped store"/> + <variant name="Conflicting" + summary="stored in the password manager with a conflicting password + between the account-scoped store and profile-scoped store + (i.e. the signon realm and username match, but the password + does not)"/> + <variant name="Identical" + summary="stored in both the password manager's account-scoped store + and profile-scoped store"/> + <variant name="Missing" + summary="stored in the password manager's profile-scoped store that + don't exist in the account-scoped store"/> + </token> </histogram> <histogram name="PasswordManager.AffiliationBackend.FetchSize" units="facets"
diff --git a/tools/metrics/histograms/histograms_xml/subresource/histograms.xml b/tools/metrics/histograms/histograms_xml/subresource/histograms.xml index 450a253..f80599d 100644 --- a/tools/metrics/histograms/histograms_xml/subresource/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/subresource/histograms.xml
@@ -254,9 +254,23 @@ <histogram name="SubresourceFilter.PageLoad.ActivationState" enum="SubresourceFilterActivationState" expires_after="2021-03-07"> <owner>csharrison@chromium.org</owner> + <owner>chrome-ads-uma@google.com</owner> <summary> Whenever a document load is committed in a main frame, records whether - subresource filtering should be activated for that load. + subresource filtering should be activated for that load. Also records the + same for the initial document load, even if it was not committed. + </summary> +</histogram> + +<histogram name="SubresourceFilter.PageLoad.ActivationState.DidInherit" + enum="SubresourceFilterActivationState" expires_after="2021-11-02"> + <owner>alexmt@chromium.org</owner> + <owner>chrome-ads-uma@google.com</owner> + <summary> + Whenever a document load is committed in a main frame that inherits from its + same-origin opener, records whether subresource filtering should be + activated for that load. Also records the same for the initial document load + (if it inherits its activation) even if it was not committed. </summary> </histogram>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 8271d94d..9876c89 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -2140,8 +2140,11 @@ <owner>paint-dev@chromium.org</owner> <summary> Metrics that measure various update times in Blink. This includes paint, - compositing, and layout update times. The metrics are recorded at first - lifecycle update and then a random frame with mean interval of 2000 frames. + compositing, and layout update times. This event is reported once in the + first main frame update after First Contentful Paint, with data from a + randomly chosen frame up to and including First Contentful Paint, and once + on LocalFrameView destruction with data from a random frame between + FirstContentfulPaint and shutdown. This event is not recorded on machines with low-resolution clocks. </summary> @@ -2204,7 +2207,16 @@ within the sample window. An int in the range [0,100]. </summary> </metric> + <metric name="AnimateBeginMainFrame"> + <summary> + The total main frame time used by by main thread animations, in + microseconds. + </summary> + </metric> <metric name="AnimatePercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with AnimateBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time used by main thread animations. An int in the range [0,100]. @@ -2286,7 +2298,17 @@ </history> </aggregation> </metric> + <metric name="CompositingAssignmentsBeginMainFrame"> + <summary> + The total main frame time used by the compositing assignments phase, in + microseconds. + </summary> + </metric> <metric name="CompositingAssignmentsPercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with + CompositingAssignmentsBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time used by the compositing assignments phase. An int in the range [0,100]. @@ -2352,7 +2374,15 @@ int in the range [0,100]. </summary> </metric> + <metric name="CompositingCommitBeginMainFrame"> + <summary> + The total main frame time used by the compositing commit, in microseconds. + </summary> + </metric> <metric name="CompositingCommitPercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with CompositingCommitBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time used by the compositing commit. An int in the range [0,100]. @@ -2372,17 +2402,28 @@ </history> </aggregation> </metric> + <metric name="CompositingInputsBeginMainFrame"> + <summary> + The total main frame time used by the compositing inputs phase, in + microseconds. + </summary> + </metric> <metric name="CompositingInputsPercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with CompositingInputsBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time used by the compositing inputs phase. An int in the range [0,100]. </summary> </metric> <metric name="CompositingPercentage"> + <obsolete> + Obsolete as of http://crrev.com/794384. + </obsolete> <summary> The percentage of the main frame time used by the compositing phase. An - int in the range [0,100]. This is being replaced soon by - CompositingInputsPercentage and CompositingAssignmentsPercentage. + int in the range [0,100]. </summary> </metric> <metric name="ForcedStyleAndLayout"> @@ -2446,7 +2487,18 @@ frame. An int in the range [0,100]. </summary> </metric> + <metric name="ForcedStyleAndLayoutBeginMainFrame"> + <summary> + The total main frame time used by forced style updates and layouts, in + microseconds. This metric may include time that is also included in the + AnimateBeginMainFrame metric. + </summary> + </metric> <metric name="ForcedStyleAndLayoutPercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with + ForcedStyleAndLayoutBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time used by forced style updates and layouts during the main frame update (not including time outside of the @@ -2514,7 +2566,16 @@ range [0,100]. </summary> </metric> + <metric name="HandleInputEventsBeginMainFrame"> + <summary> + The total main frame time used in processing rAF-aligned input, in + microseconds. + </summary> + </metric> <metric name="HandleInputEventsPercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with HandleInputEventsBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time used in processing rAF-aligned input. An int in the range [0,100]. @@ -2536,7 +2597,17 @@ </history> </aggregation> </metric> + <metric name="HitTestDocumentUpdateBeginMainFrame"> + <summary> + The total main frame time used in performing hit test document updates, in + microseconds. + </summary> + </metric> <metric name="HitTestDocumentUpdatePercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with + HitTestDocumentUpdateBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time used in performing hit test document updates. An int in the range [0,100]. @@ -2556,7 +2627,18 @@ </history> </aggregation> </metric> + <metric name="ImplCompositorCommitBeginMainFrame"> + <summary> + The total main frame time spent committing layer tree impl data in the + compositor thread, in microseconds. This should always match + ImplCompositorCommit and serves as a check. + </summary> + </metric> <metric name="ImplCompositorCommitPercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with + ImplCompositorCommitBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time spent committing layer tree impl data in the compositor thread. An int in the range [0,100]. @@ -2622,7 +2704,17 @@ range [0,100]. </summary> </metric> + <metric name="IntersectionObservationBeginMainFrame"> + <summary> + The total main frame time used to compute IntersectionObserver + observations, in microseconds. + </summary> + </metric> <metric name="IntersectionObservationPercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with + IntersectionObservationBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time used in computing intersection observer state. An int in the range [0,100]. @@ -2642,7 +2734,15 @@ </history> </aggregation> </metric> + <metric name="LayoutBeginMainFrame"> + <summary> + The total main frame time used in layout, in microseconds. + </summary> + </metric> <metric name="LayoutPercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with LayoutBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time used in layout work. An int in the range [0,100]. @@ -2762,7 +2862,15 @@ sample window. An int in the range [0,100]. </summary> </metric> + <metric name="PaintBeginMainFrame"> + <summary> + The total main frame time used in paint, in microseconds. + </summary> + </metric> <metric name="PaintPercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with PaintBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time used in paint. An int in the range [0,100]. @@ -2827,7 +2935,15 @@ the sample window. An int in the range [0,100]. </summary> </metric> + <metric name="PrePaintBeginMainFrame"> + <summary> + The total main frame time used in pre-paint, in microseconds. + </summary> + </metric> <metric name="PrePaintPercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with PrePaintBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time used in pre-paint. An int in the range [0,100]. @@ -2863,7 +2979,8 @@ </metric> <metric name="ScrollingCoordinator"> <obsolete> - Merged into CompositingCommit in http://crrev.com/815947 in M88. + Merged into Blink.MainFrame.CompositingCommitRatio in + http://crrev.com/815947 in M88. </obsolete> <summary> The time taken for scrolling coordinator for the main frame in @@ -2926,7 +3043,8 @@ </metric> <metric name="ScrollingCoordinatorPercentage"> <obsolete> - Merged into CompositingCommitPercentage in http://crrev.com/815947 in M88. + Merged into Blink.MainFrame.CompositingCommitRatio in + http://crrev.com/815947 in M88. </obsolete> <summary> The percentage of the main frame time used in scrolling coordinator. An @@ -3018,6 +3136,12 @@ int in the range [0,100]. </summary> </metric> + <metric name="StyleBeginMainFrame"> + <summary> + The total main frame time spent updating style information and and + building the layout tree, in microseconds. + </summary> + </metric> <metric name="StylePercentage"> <summary> The percentage of the main frame time used in style work. An int in the @@ -3038,7 +3162,16 @@ </history> </aggregation> </metric> + <metric name="UpdateLayersBeginMainFrame"> + <summary> + The total main frame time spent in LayerTreeHost::UpdateLayer, in + microseconds. This should always match UpdateLayers and serves as a check. + </summary> + </metric> <metric name="UpdateLayersPercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with UpdateLayersBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time used by LayerTreeHost::UpdateLayers. An int in the range [0,100]. @@ -3058,7 +3191,17 @@ </history> </aggregation> </metric> + <metric name="WaitForCommitBeginMainFrame"> + <summary> + The total main frame time spent waiting for the compositor thread to begin + processing a commit, in microseconds. This should always match + WaitForCommit and serves as a check. + </summary> + </metric> <metric name="WaitForCommitPercentage"> + <obsolete> + Deprecated as of 11/2020. Replaced with WaitForCommitBeginMainFrame. + </obsolete> <summary> The percentage of the main frame time spent waiting for the compositor thread to begin processing a commit. An int in the range [0,100].
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index acf31d62b..61b235fa 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,12 +5,12 @@ "remote_path": "perfetto_binaries/trace_processor_shell/win/4cd11945c5a1810252d00d9f91147f22872ddd4b/trace_processor_shell.exe" }, "mac": { - "hash": "ba60da70f408bcd300db0fdf912a68be9ad38a35", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/1d532cbd0baab400b5de485f87fb68236ea0ea0f/trace_processor_shell" + "hash": "3b6b071856c7ab7ec325a42a5c644574f2d8273f", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/952ef3e0647215edbae15a45fe4cabc4b33ddd69/trace_processor_shell" }, "linux": { - "hash": "f8fda3da02ad05fa1a2f5af2c6cf3cbbb481b37a", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/eba8b028ddbca3fa0c4f31841d5f88524413e17e/trace_processor_shell" + "hash": "48e43ef4bcbfabbc6279972f075b3be960f84e71", + "remote_path": "perfetto_binaries/trace_processor_shell/linux/952ef3e0647215edbae15a45fe4cabc4b33ddd69/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/polymer/polymer.py b/tools/polymer/polymer.py index 2bc049f0..793ee7f 100644 --- a/tools/polymer/polymer.py +++ b/tools/polymer/polymer.py
@@ -86,8 +86,6 @@ # Use an OrderedDict, since the order these redirects are applied matters. _chrome_redirects = OrderedDict([ - ('chrome://resources/polymer/v1_0/', POLYMER_V1_DIR), - ('chrome://resources/', 'ui/webui/resources/'), ('//resources/polymer/v1_0/', POLYMER_V1_DIR), ('//resources/', 'ui/webui/resources/'), ]) @@ -105,7 +103,7 @@ # 1) normalized, meaning converted from a chrome or scheme-relative or relative # URL to to an absolute path starting at the repo's root # 2) converted to an equivalent JS normalized path -# 3) de-normalized, meaning converted back to a chrome or scheme-relative or +# 3) de-normalized, meaning converted back to a scheme or scheme-relative or # relative URL # 4) converted to a JS import statement class Dependency: @@ -114,7 +112,11 @@ self.html_path = dst if self.html_path.startswith('chrome://'): - self.input_format = 'chrome' + self.input_format = 'scheme' + self.input_scheme = 'chrome' + elif self.html_path.startswith('chrome-extension://'): + self.input_format = 'scheme' + self.input_scheme = 'chrome-extension' elif self.html_path.startswith('//'): self.input_format = 'scheme-relative' else: @@ -126,12 +128,18 @@ self.js_path = self._to_js() def _to_html_normalized(self): - if self.input_format == 'chrome' or self.input_format == 'scheme-relative': + if self.input_format == 'scheme' or self.input_format == 'scheme-relative': self.html_path_normalized = self.html_path + + if self.input_format == 'scheme': + # Strip the URL scheme. + colon_index = self.html_path_normalized.find(':') + self.html_path_normalized = self.html_path_normalized[colon_index + 1:] + for r in _chrome_redirects: - if self.html_path.startswith(r): - self.html_path_normalized = ( - self.html_path.replace(r, _chrome_redirects[r])) + if self.html_path_normalized.startswith(r): + self.html_path_normalized = (self.html_path_normalized.replace( + r, _chrome_redirects[r])) break return self.html_path_normalized @@ -147,7 +155,8 @@ if self.html_path_normalized == 'ui/webui/resources/html/polymer.html': if self.output_format == 'relative': - self.output_format = 'chrome' + self.output_format = 'scheme' + self.input_scheme = 'chrome' return POLYMER_V3_DIR + 'polymer/polymer_bundled.min.js' if re.match(r'ui/webui/resources/html/', self.html_path_normalized): @@ -162,16 +171,16 @@ def _to_js(self): js_path = self.js_path_normalized - if self.output_format == 'chrome' or self.output_format == 'scheme-relative': + if self.output_format == 'scheme' or self.output_format == 'scheme-relative': for r in _chrome_reverse_redirects: if self.js_path_normalized.startswith(r): js_path = self.js_path_normalized.replace( r, _chrome_reverse_redirects[r]) break - # Restore the chrome:// scheme if |preserve_url_scheme| is enabled. - if _preserve_url_scheme and self.output_format == 'chrome': - js_path = "chrome:" + js_path + # Restore the original scheme if |preserve_url_scheme| is enabled. + if _preserve_url_scheme and self.output_format == 'scheme': + js_path = self.input_scheme + ":" + js_path return js_path assert self.output_format == 'relative'
diff --git a/tools/polymer/polymer_test.py b/tools/polymer/polymer_test.py index 33b1c64..e220402 100755 --- a/tools/polymer/polymer_test.py +++ b/tools/polymer/polymer_test.py
@@ -208,6 +208,13 @@ 'import \'chrome://resources/js/bar.m.js\';', ], + # chrome-extension:// paths cases. + [ + 'chrome-extension://path/to/folder/foo.html', + 'import \'//path/to/folder/foo.m.js\';', + 'import \'chrome-extension://path/to/folder/foo.m.js\';', + ], + # Scheme-relative paths cases. # Case where absolute path to a Polymer UI element is used. [
diff --git a/ui/accessibility/platform/inspect/tree_formatter.h b/ui/accessibility/platform/inspect/tree_formatter.h index 427a5e2..4d629ece 100644 --- a/ui/accessibility/platform/inspect/tree_formatter.h +++ b/ui/accessibility/platform/inspect/tree_formatter.h
@@ -80,37 +80,6 @@ // If true, the internal accessibility id of each node will be included // in its output. virtual void set_show_ids(bool show_ids) = 0; - - // A string that indicates a given line in a file is an allow-empty, - // allow or deny filter. Overridden by each platform subclass. Example: - // Mac values: - // GetAllowEmptyString() -> "@MAC-ALLOW-EMPTY:" - // GetAllowString() -> "@MAC-ALLOW:" - // GetDenyString() -> "@MAC-DENY:" - // GetDenyNodeString() -> "@MAC-DENY-NODE:" - // Example html: - // <!-- - // @MAC-ALLOW-EMPTY:description* - // @MAC-ALLOW:roleDescription* - // @MAC-DENY:subrole* - // @BLINK-DENY-NODE:internalRole=inlineTextBox - // --> - // <p>Text</p> - virtual const std::string GetAllowEmptyString() = 0; - virtual const std::string GetAllowString() = 0; - virtual const std::string GetDenyString() = 0; - virtual const std::string GetDenyNodeString() = 0; - - // A string that indicates event recording should continue at least until a - // specific event has been received. - // Overridden by each platform subclass. - // Example win value: - // GetRunUntilEventString() -> "@WIN-RUN-UNTIL-EVENT" - // Example html: - // <!-- - // @WIN-RUN-UNTIL-EVENT:IA2_EVENT_TEXT_CARET_MOVED - // --> - virtual const std::string GetRunUntilEventString() = 0; }; } // namespace ui
diff --git a/ui/file_manager/audio_player/elements/BUILD.gn b/ui/file_manager/audio_player/elements/BUILD.gn index 183defe8a..fd9ade9 100644 --- a/ui/file_manager/audio_player/elements/BUILD.gn +++ b/ui/file_manager/audio_player/elements/BUILD.gn
@@ -172,6 +172,7 @@ js_type_check("closure_compile_jsmodules") { is_polymer3 = true + closure_flags = default_closure_args + [ "browser_resolver_prefix_replacements=\"chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/=../../ui/file_manager/file_manager/\"" ] deps = [ ":audio_player.m", ":control_panel.m",
diff --git a/ui/gfx/x/connection.cc b/ui/gfx/x/connection.cc index 8dff5903..4f3ce77a 100644 --- a/ui/gfx/x/connection.cc +++ b/ui/gfx/x/connection.cc
@@ -189,7 +189,8 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!xlib_display_) xlib_display_ = base::WrapUnique(new XlibDisplay(display_string_)); - return XlibDisplayWrapper(xlib_display_->display_, type); + return XlibDisplayWrapper(xlib_display_->xlib_loader_.get(), + xlib_display_->display_, type); } Connection::Request::Request(unsigned int sequence,
diff --git a/ui/gfx/x/xlib_support.cc b/ui/gfx/x/xlib_support.cc index d6aedbb6..de9f8b9 100644 --- a/ui/gfx/x/xlib_support.cc +++ b/ui/gfx/x/xlib_support.cc
@@ -7,7 +7,6 @@ #include "base/check.h" #include "base/compiler_specific.h" #include "base/logging.h" -#include "base/no_destructor.h" #include "library_loaders/xlib_loader.h" namespace x11 { @@ -19,56 +18,41 @@ return 0; } -XlibLoader* GetXlibLoader() { - static base::NoDestructor<XlibLoader> xlib_loader; - return xlib_loader.get(); -} - } // namespace -void InitXlib() { - auto* xlib_loader = GetXlibLoader(); - if (xlib_loader->loaded()) - return; +DISABLE_CFI_ICALL +XlibDisplay::XlibDisplay(const std::string& address) { + xlib_loader_ = std::make_unique<XlibLoader>(); + CHECK(xlib_loader_->Load("libX11.so.6")); - CHECK(xlib_loader->Load("libX11.so.6")); - - CHECK(xlib_loader->XInitThreads()); + CHECK(xlib_loader_->XInitThreads()); // The default Xlib error handler calls exit(1), which we don't want. This // shouldn't happen in the browser process since only XProto requests are // made, but in the GPU process, GLX can make Xlib requests, so setting an // error handler is necessary. Importantly, there's also an IO error handler, // and Xlib always calls exit(1) with no way to change this behavior. - SetXlibErrorHandler(); -} + xlib_loader_->XSetErrorHandler(XlibErrorHandler); -void SetXlibErrorHandler() { - GetXlibLoader()->XSetErrorHandler(XlibErrorHandler); -} - -DISABLE_CFI_ICALL -XlibDisplay::XlibDisplay(const std::string& address) { - InitXlib(); - - display_ = GetXlibLoader()->XOpenDisplay(address.empty() ? nullptr - : address.c_str()); + display_ = + xlib_loader_->XOpenDisplay(address.empty() ? nullptr : address.c_str()); } DISABLE_CFI_ICALL XlibDisplay::~XlibDisplay() { if (display_) - GetXlibLoader()->XCloseDisplay(display_); + xlib_loader_->XCloseDisplay(display_); } DISABLE_CFI_ICALL -XlibDisplayWrapper::XlibDisplayWrapper(struct _XDisplay* display, +XlibDisplayWrapper::XlibDisplayWrapper(XlibLoader* xlib_loader, + struct _XDisplay* display, XlibDisplayType type) - : display_(display), type_(type) { + : xlib_loader_(xlib_loader), display_(display), type_(type) { if (!display_) return; if (type == XlibDisplayType::kSyncing) - GetXlibLoader()->XSynchronize(display_, true); + xlib_loader_->XSynchronize(display_, true); } DISABLE_CFI_ICALL @@ -76,21 +60,25 @@ if (!display_) return; if (type_ == XlibDisplayType::kFlushing) - GetXlibLoader()->XFlush(display_); + xlib_loader_->XFlush(display_); else if (type_ == XlibDisplayType::kSyncing) - GetXlibLoader()->XSynchronize(display_, false); + xlib_loader_->XSynchronize(display_, false); } XlibDisplayWrapper::XlibDisplayWrapper(XlibDisplayWrapper&& other) { + xlib_loader_ = other.xlib_loader_; display_ = other.display_; type_ = other.type_; + other.xlib_loader_ = nullptr; other.display_ = nullptr; other.type_ = XlibDisplayType::kNormal; } XlibDisplayWrapper& XlibDisplayWrapper::operator=(XlibDisplayWrapper&& other) { + xlib_loader_ = other.xlib_loader_; display_ = other.display_; type_ = other.type_; + other.xlib_loader_ = nullptr; other.display_ = nullptr; other.type_ = XlibDisplayType::kNormal; return *this;
diff --git a/ui/gfx/x/xlib_support.h b/ui/gfx/x/xlib_support.h index 37ea34a..5450471 100644 --- a/ui/gfx/x/xlib_support.h +++ b/ui/gfx/x/xlib_support.h
@@ -10,6 +10,7 @@ #include "base/component_export.h" struct _XDisplay; +class XlibLoader; namespace x11 { @@ -25,12 +26,6 @@ kSyncing, }; -// Loads Xlib, initializes threads, and sets a default error handler. -COMPONENT_EXPORT(X11) void InitXlib(); - -// Sets an async error handler which only logs an error message. -COMPONENT_EXPORT(X11) void SetXlibErrorHandler(); - // A scoped Xlib display. class COMPONENT_EXPORT(X11) XlibDisplay { public: @@ -43,6 +38,7 @@ explicit XlibDisplay(const std::string& address); struct _XDisplay* display_ = nullptr; + std::unique_ptr<XlibLoader> xlib_loader_; }; // A temporary wrapper around an unowned Xlib display that adds behavior @@ -60,10 +56,13 @@ XlibDisplayWrapper& operator=(XlibDisplayWrapper&& other); private: - XlibDisplayWrapper(struct _XDisplay* display, XlibDisplayType type); + XlibDisplayWrapper(XlibLoader* xlib_loader, + struct _XDisplay* display, + XlibDisplayType type); friend class Connection; + XlibLoader* xlib_loader_; struct _XDisplay* display_; XlibDisplayType type_; };
diff --git a/ui/gtk/x/gtk_ui_delegate_x11.cc b/ui/gtk/x/gtk_ui_delegate_x11.cc index 7aa7e78..b9a2f3b4 100644 --- a/ui/gtk/x/gtk_ui_delegate_x11.cc +++ b/ui/gtk/x/gtk_ui_delegate_x11.cc
@@ -10,7 +10,6 @@ #include "ui/base/x/x11_util.h" #include "ui/events/platform/x11/x11_event_source.h" #include "ui/gfx/native_widget_types.h" -#include "ui/gfx/x/xlib_support.h" #include "ui/gfx/x/xproto.h" #include "ui/gtk/x/gtk_event_loop_x11.h" #include "ui/platform_window/x11/x11_window.h" @@ -32,7 +31,6 @@ : connection_(connection) { DCHECK(connection_); gdk_set_allowed_backends("x11"); - x11::InitXlib(); } GtkUiDelegateX11::~GtkUiDelegateX11() = default; @@ -40,11 +38,6 @@ void GtkUiDelegateX11::OnInitialized() { // Ensure the singleton instance of GtkEventLoopX11 is created and started. GtkEventLoopX11::EnsureInstance(); - - // GTK sets an Xlib error handler that exits the process on any async errors. - // We don't want this behavior, so reset the error handler to something that - // just logs the error. - x11::SetXlibErrorHandler(); } GdkKeymap* GtkUiDelegateX11::GetGdkKeymap() {
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_list.html b/ui/webui/resources/cr_components/chromeos/network/network_list.html index 99152041..67c933d 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_list.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_list.html
@@ -11,9 +11,6 @@ <dom-module id="network-list"> <template> <style include="cr-shared-style iron-flex"> - :host { - display: inline-flex; - } network-list-item { align-items: center;