diff --git a/DEPS b/DEPS index 98e35bd..1bc1b664 100644 --- a/DEPS +++ b/DEPS
@@ -138,11 +138,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': '91032f8cd7eaf5ab5d562b6bf8b726000ae33709', + 'skia_revision': '1ae6ac81e68a98067d82b64a22af141a3c06f288', # 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': 'd32b1ad164ec906d80c8d637611852347b8f812a', + 'v8_revision': 'd3a6eb96bc8dcd4526cfff4bf7cd841ca1ff9578', # 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. @@ -150,7 +150,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': 'dd3ef1e788191b55260650c13a2a516ac3b4dcfa', + 'angle_revision': 'eb66fe4e15e8ad4d11eabcdac3ee1e012b06697a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -158,7 +158,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'ad6de6a08a66b6310630abd09ecd6f9687c17234', + 'pdfium_revision': 'd1fb2c5fcaa3c381b519651df72ef08b64bc2e87', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -201,7 +201,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '304e5101f38227ea858688612e7bef77a9a35aae', + 'catapult_revision': '8db999ee35fffb101c48baf7713006991ef1960e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -273,7 +273,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '5dee3e826bed25ea7893de29bfe612c864f81604', + 'dawn_revision': '99b76d1b8fddadd1696dd39fdeee5b074ae45101', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -477,7 +477,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'e90aa11c4be39bce72ea4a05709f7ed3d5c7a438', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'dc0267693ad4813d4216424bdf20def3ae21bfac', 'condition': 'checkout_ios', }, @@ -807,7 +807,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f2482cb0559075fe480ba2573a17c6d0066eb041', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'ce76d1e960eb22a2f6de4d2bd8f43bbebf8f0feb', 'condition': 'checkout_linux', }, @@ -822,7 +822,7 @@ # For Linux and Chromium OS. 'src/third_party/cros_system_api': { - 'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + 'ed5a30c1446a23a0c98cc4623b260c03f9202aa8', + 'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '33a144a0bdb93f1440c7298b4a0fd7755dccc7b4', 'condition': 'checkout_linux', }, @@ -832,7 +832,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'dd2737e2b5727d836f2442d9a6d960ad978fed66', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '8812b932c914d4b114bd8c5a2dd5c96e3d38fa9c', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1136,7 +1136,7 @@ 'src/third_party/nasm': { 'url': Var('chromium_git') + '/chromium/deps/nasm.git' + '@' + - 'c8b248039ec1f75a7c5733bbe76d7fa416ce097a' + 'f564874f49556d930882645a348fcd6ddc6847b0' }, 'src/third_party/netty-tcnative/src': { @@ -1187,7 +1187,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '79519d67783bc8e59cca6a70848c153363883221', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '967947db0661a8dc47979a59ba886ae9e872d830', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1396,7 +1396,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@e3905cd79dbe3503c306ce0fd851c120220347d1', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c0cc2343f646de73801b174b3737b4400b8ff42e', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index 4976a62e..5869691 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -635,7 +635,7 @@ callback.Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY); } -void AwContentBrowserClient::SelectClientCertificate( +base::OnceClosure AwContentBrowserClient::SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs, @@ -644,6 +644,7 @@ AwContentsClientBridge::FromWebContents(web_contents); if (client) client->SelectClientCertificate(cert_request_info, std::move(delegate)); + return base::OnceClosure(); } bool AwContentBrowserClient::CanCreateWindow(
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index abd9ca5..600cb9d5 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -121,7 +121,7 @@ bool expired_previous_decision, const base::Callback<void(content::CertificateRequestResultType)>& callback) override; - void SelectClientCertificate( + base::OnceClosure SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs,
diff --git a/ash/app_list/BUILD.gn b/ash/app_list/BUILD.gn index be73921..ce03082 100644 --- a/ash/app_list/BUILD.gn +++ b/ash/app_list/BUILD.gn
@@ -66,6 +66,8 @@ "views/pulsing_block_view.h", "views/remove_query_confirmation_dialog.cc", "views/remove_query_confirmation_dialog.h", + "views/result_selection_controller.cc", + "views/result_selection_controller.h", "views/search_box_view.cc", "views/search_box_view.h", "views/search_result_actions_view.cc", @@ -206,6 +208,7 @@ "views/app_list_view_unittest.cc", "views/apps_grid_view_unittest.cc", "views/folder_header_view_unittest.cc", + "views/result_selection_controller_unittest.cc", "views/search_box_view_unittest.cc", "views/search_result_answer_card_view_unittest.cc", "views/search_result_list_view_unittest.cc",
diff --git a/ash/app_list/app_list_util.cc b/ash/app_list/app_list_util.cc index 63abb3c..e3797b7d 100644 --- a/ash/app_list/app_list_util.cc +++ b/ash/app_list/app_list_util.cc
@@ -42,9 +42,12 @@ } bool IsArrowKeyEvent(const ui::KeyEvent& event) { - return event.key_code() == ui::VKEY_DOWN || - event.key_code() == ui::VKEY_RIGHT || - event.key_code() == ui::VKEY_LEFT || event.key_code() == ui::VKEY_UP; + return IsArrowKey(event.key_code()); +} + +bool IsArrowKey(const ui::KeyboardCode& key_code) { + return key_code == ui::VKEY_DOWN || key_code == ui::VKEY_RIGHT || + key_code == ui::VKEY_LEFT || key_code == ui::VKEY_UP; } bool LeftRightKeyEventShouldExitText(views::Textfield* textfield,
diff --git a/ash/app_list/app_list_util.h b/ash/app_list/app_list_util.h index 8ed3e10..d2475b1 100644 --- a/ash/app_list/app_list_util.h +++ b/ash/app_list/app_list_util.h
@@ -29,6 +29,10 @@ // Returns whether the event is an arrow key event. APP_LIST_EXPORT bool IsArrowKeyEvent(const ui::KeyEvent& event); +// Returns true if the keyboard code is one of: |VKEY_UP|, |VKEY_LEFT|, +// |VKEY_RIGHT|, |VKEY_DOWN| +APP_LIST_EXPORT bool IsArrowKey(const ui::KeyboardCode& key_code); + // Returns true if the arrow key event should move focus away from the // |textfield|. This is usually when the insertion point would move away from // text.
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index b9b06a4..e15df455 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -1935,10 +1935,17 @@ if (is_search_box_focused || is_folder_header_view_focused) return; - // Do not redirect the arrow keys as they are are used for focus traversal and - // app movement. - if (IsArrowKeyEvent(*event)) + // Do not redirect the arrow keys in app list as they are are used for focus + // traversal and app movement. + if (app_list_features::IsSearchBoxSelectionEnabled() && + IsArrowKeyEvent(*event) && !search_box_view_->is_search_box_active()) { return; + } + + if (!app_list_features::IsSearchBoxSelectionEnabled() && + IsArrowKeyEvent(*event)) { + return; + } // Redirect key event to |search_box_|. search_box->OnKeyEvent(event);
diff --git a/ash/app_list/views/app_list_view_unittest.cc b/ash/app_list/views/app_list_view_unittest.cc index 48554dce..6cfb041 100644 --- a/ash/app_list/views/app_list_view_unittest.cc +++ b/ash/app_list/views/app_list_view_unittest.cc
@@ -25,6 +25,7 @@ #include "ash/app_list/views/contents_view.h" #include "ash/app_list/views/expand_arrow_view.h" #include "ash/app_list/views/folder_header_view.h" +#include "ash/app_list/views/result_selection_controller.h" #include "ash/app_list/views/search_box_view.h" #include "ash/app_list/views/search_result_answer_card_view.h" #include "ash/app_list/views/search_result_container_view.h" @@ -425,6 +426,20 @@ } } + void TestSelectionTraversal(const std::vector<views::View*>& view_list, + ui::KeyboardCode key_code, + bool shift_down) { + ResultSelectionController* selection_controller = + contents_view() + ->search_results_page_view() + ->result_selection_controller(); + EXPECT_EQ(view_list[0], selection_controller->selected_result()); + for (size_t i = 1; i < view_list.size(); ++i) { + SimulateKeyPress(key_code, shift_down); + EXPECT_EQ(view_list[i], selection_controller->selected_result()); + } + } + // Test the behavior triggered by left and right key when focus is on the // |textfield|. Does not insert text. void TestLeftAndRightKeyTraversalOnTextfield(views::Textfield* textfield) { @@ -692,8 +707,14 @@ SetUpSearchResults(kTileResults, kListResults, true); std::vector<views::View*> forward_view_list; - forward_view_list.push_back(search_box_view()->search_box()); - forward_view_list.push_back(search_box_view()->close_button()); + + // Traversal using the ResultSelectionController stays within the results, as + // such, this should be removed with the flag. + if (!app_list_features::IsSearchBoxSelectionEnabled()) { + forward_view_list.push_back(search_box_view()->search_box()); + forward_view_list.push_back(search_box_view()->close_button()); + } + const std::vector<SearchResultTileItemView*>& tile_views = contents_view() ->search_result_tile_item_list_view_for_test() @@ -707,15 +728,30 @@ contents_view()->search_result_list_view_for_test(); for (int i = 0; i < kListResults; ++i) forward_view_list.push_back(list_view->GetResultViewAt(i)); - forward_view_list.push_back(search_box_view()->search_box()); + + // The selected view will always be a result when using + // |result_selection_controller| + if (app_list_features::IsSearchBoxSelectionEnabled()) + forward_view_list.push_back(tile_views[0]); + else + forward_view_list.push_back(search_box_view()->search_box()); + std::vector<views::View*> backward_view_list = forward_view_list; std::reverse(backward_view_list.begin(), backward_view_list.end()); - // Test traversal triggered by tab. - TestFocusTraversal(forward_view_list, ui::VKEY_TAB, false); + if (app_list_features::IsSearchBoxSelectionEnabled()) { + // Test traversal triggered by tab. + TestSelectionTraversal(forward_view_list, ui::VKEY_TAB, false); - // Test traversal triggered by shift+tab. - TestFocusTraversal(backward_view_list, ui::VKEY_TAB, true); + // Test traversal triggered by shift+tab. + TestSelectionTraversal(backward_view_list, ui::VKEY_TAB, true); + } else { + // Test traversal triggered by tab. + TestFocusTraversal(forward_view_list, ui::VKEY_TAB, false); + + // Test traversal triggered by shift+tab. + TestFocusTraversal(backward_view_list, ui::VKEY_TAB, true); + } } // Tests focus traversal in HALF state with opened search box using |VKEY_LEFT| @@ -739,38 +775,61 @@ SetUpSearchResults(kTileResults, 0, false); std::vector<views::View*> forward_view_list; - forward_view_list.push_back(search_box_view()->search_box()); const std::vector<SearchResultTileItemView*>& tile_views = contents_view() ->search_result_tile_item_list_view_for_test() ->tile_views_for_test(); + + if (app_list_features::IsSearchBoxSelectionEnabled()) + forward_view_list.push_back(tile_views[0]); + else + forward_view_list.push_back(search_box_view()->search_box()); + for (int i = 1; i < kTileResults; ++i) forward_view_list.push_back(tile_views[i]); - forward_view_list.push_back(search_box_view()->search_box()); - TestFocusTraversal(forward_view_list, - is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT, false); + if (app_list_features::IsSearchBoxSelectionEnabled()) + forward_view_list.push_back(tile_views[0]); + else + forward_view_list.push_back(search_box_view()->search_box()); + + if (app_list_features::IsSearchBoxSelectionEnabled()) { + TestSelectionTraversal(forward_view_list, + is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT, false); + } else { + TestFocusTraversal(forward_view_list, + is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT, false); + } std::vector<views::View*> backward_view_list = forward_view_list; - // Backwards traversal won't skip any items, as the first view won't be - // highlighted. - backward_view_list.insert(backward_view_list.begin() + 1, tile_views[0]); + if (!app_list_features::IsSearchBoxSelectionEnabled()) { + // Backwards traversal won't skip any items, as the first view won't be + // highlighted. + backward_view_list.insert(backward_view_list.begin() + 1, tile_views[0]); - // The intuitive focus is where the highlight is, on the first result. - // Because of this, the 'x' is effectively behind us and should only be - // traversed in the backwards list. The view in front of us it the second - // result, so that is what we should jump to next. - backward_view_list.insert(backward_view_list.begin() + 1, - search_box_view()->close_button()); + // The intuitive focus is where the highlight is, on the first result. + // Because of this, the 'x' is effectively behind us and should only be + // traversed in the backwards list. The view in front of us it the second + // result, so that is what we should jump to next. + backward_view_list.insert(backward_view_list.begin() + 1, + search_box_view()->close_button()); + } std::reverse(backward_view_list.begin(), backward_view_list.end()); - // The text in the box will be highlighted, the first press should deselect. - backward_view_list.insert(backward_view_list.begin(), - search_box_view()->search_box()); + if (!app_list_features::IsSearchBoxSelectionEnabled()) { + // The text in the box will be highlighted, the first press should deselect. + backward_view_list.insert(backward_view_list.begin(), + search_box_view()->search_box()); + } - TestFocusTraversal(backward_view_list, - is_rtl_ ? ui::VKEY_RIGHT : ui::VKEY_LEFT, false); + if (app_list_features::IsSearchBoxSelectionEnabled()) { + TestSelectionTraversal(backward_view_list, + is_rtl_ ? ui::VKEY_RIGHT : ui::VKEY_LEFT, false); + } else { + TestFocusTraversal(backward_view_list, + is_rtl_ ? ui::VKEY_RIGHT : ui::VKEY_LEFT, false); + } } // Tests the linear focus traversal in FULLSCREEN_ALL_APPS state within folder. @@ -881,7 +940,12 @@ SetUpSearchResults(kTileResults, kListResults, true); std::vector<views::View*> forward_view_list; - forward_view_list.push_back(search_box_view()->search_box()); + + // Removed with the flag. Search box will no longer be part of traversal + // within results. + if (!app_list_features::IsSearchBoxSelectionEnabled()) + forward_view_list.push_back(search_box_view()->search_box()); + const std::vector<SearchResultTileItemView*>& tile_views = contents_view() ->search_result_tile_item_list_view_for_test() @@ -889,7 +953,11 @@ // We skip the first view when coming from the search box. This is because // the first view is initially highlighted, and would already be activated // upon pressing enter. Hence, we skip adding the tile view to the expected - // view list. + // view list. This comment should be removed with the flag, the line should + // remain. + if (app_list_features::IsSearchBoxSelectionEnabled()) + forward_view_list.push_back(tile_views[0]); + forward_view_list.push_back(contents_view() ->search_result_answer_card_view_for_test() ->GetAnswerCardResultViewForTest()); @@ -897,23 +965,40 @@ contents_view()->search_result_list_view_for_test(); for (int i = 0; i < kListResults; ++i) forward_view_list.push_back(list_view->GetResultViewAt(i)); - forward_view_list.push_back(search_box_view()->search_box()); - // Test traversal triggered by down. - TestFocusTraversal(forward_view_list, ui::VKEY_DOWN, false); + if (!app_list_features::IsSearchBoxSelectionEnabled()) { + forward_view_list.push_back(search_box_view()->search_box()); + } else { + contents_view() + ->search_results_page_view() + ->result_selection_controller() + ->ResetSelection(); + } + if (app_list_features::IsSearchBoxSelectionEnabled()) { + // Test traversal triggered by down. + TestSelectionTraversal(forward_view_list, ui::VKEY_DOWN, false); + } else { + TestFocusTraversal(forward_view_list, ui::VKEY_DOWN, false); + } std::vector<views::View*> backward_view_list; - backward_view_list.push_back(search_box_view()->search_box()); + if (!app_list_features::IsSearchBoxSelectionEnabled()) + backward_view_list.push_back(search_box_view()->search_box()); for (int i = kListResults - 1; i >= 0; --i) backward_view_list.push_back(list_view->GetResultViewAt(i)); backward_view_list.push_back(contents_view() ->search_result_answer_card_view_for_test() ->GetAnswerCardResultViewForTest()); backward_view_list.push_back(tile_views[kTileResults - 1]); - backward_view_list.push_back(search_box_view()->search_box()); + if (!app_list_features::IsSearchBoxSelectionEnabled()) + backward_view_list.push_back(search_box_view()->search_box()); - // Test traversal triggered by up. - TestFocusTraversal(backward_view_list, ui::VKEY_UP, false); + if (app_list_features::IsSearchBoxSelectionEnabled()) { + // Test traversal triggered by up. + TestSelectionTraversal(backward_view_list, ui::VKEY_UP, false); + } else { + TestFocusTraversal(backward_view_list, ui::VKEY_UP, false); + } } // Tests the vertical focus traversal in FULLSCREEN_ALL_APPS state in the first @@ -1106,6 +1191,11 @@ // Tests that the search box textfield has no selection when the focus moves // away from the SearchBoxView. TEST_F(AppListViewFocusTest, SearchBoxTextfieldHasNoSelectionWhenFocusLeaves) { + // This test should be removed with the flag, as this behavior is no longer + // desired. + if (app_list_features::IsSearchBoxSelectionEnabled()) + return; + Show(); search_box_view()->search_box()->InsertText(base::UTF8ToUTF16("test")); @@ -1129,17 +1219,29 @@ AddSearchResultWithTitleAndScore("TestResult2", 2); AddSearchResultWithTitleAndScore("TestResult3", 1); - // Change focus to the first result - SimulateKeyPress(ui::VKEY_TAB, false); - SimulateKeyPress(ui::VKEY_TAB, false); + // With SearchBoxSelection, focus starts on result one. + // This should be removed with the flag. + if (!app_list_features::IsSearchBoxSelectionEnabled()) { + // Change focus to the first result + SimulateKeyPress(ui::VKEY_TAB, false); + SimulateKeyPress(ui::VKEY_TAB, false); - EXPECT_EQ(search_box->text(), base::UTF8ToUTF16("TestResult1")); - + EXPECT_EQ(search_box->text(), base::UTF8ToUTF16("TestResult1")); + } // Change focus to the next result SimulateKeyPress(ui::VKEY_TAB, false); EXPECT_EQ(search_box->text(), base::UTF8ToUTF16("TestResult2")); + // This should remain after the flag is removed. + if (app_list_features::IsSearchBoxSelectionEnabled()) { + SimulateKeyPress(ui::VKEY_TAB, true); + + EXPECT_EQ(search_box->text(), base::UTF8ToUTF16("TestResult1")); + + SimulateKeyPress(ui::VKEY_TAB, false); + } + // Change focus to the final result SimulateKeyPress(ui::VKEY_TAB, false); @@ -1149,6 +1251,11 @@ // Tests that the search box selects the whole query when focus moves to the // SearchBoxTextfield. TEST_F(AppListViewFocusTest, SearchBoxSelectionCoversWholeQueryOnFocus) { + // This test should be removed with the flag, as this feature is no longer + // desired. + if (app_list_features::IsSearchBoxSelectionEnabled()) + return; + Show(); search_box_view()->search_box()->InsertText(base::ASCIIToUTF16("test")); EXPECT_EQ(app_list_view()->app_list_state(), ash::AppListViewState::kHalf); @@ -1241,6 +1348,7 @@ SetUpSearchResults(0, kListResults, false); SearchResultListView* list_view = contents_view()->search_result_list_view_for_test(); + EXPECT_EQ(search_box_view()->search_box(), focused_view()); EXPECT_EQ(list_view->GetResultViewAt(0), contents_view()->search_results_page_view()->first_result_view()); @@ -1258,6 +1366,21 @@ contents_view()->search_results_page_view()->first_result_view()); EXPECT_TRUE(tile_views[0]->background_highlighted()); + // This section should remain after flag is removed. + if (app_list_features::IsSearchBoxSelectionEnabled()) { + ResultSelectionController* selection_controller = + contents_view() + ->search_results_page_view() + ->result_selection_controller(); + + // Ensures the |ResultSelectionController| selects the correct result + EXPECT_EQ(selection_controller->selected_result(), tile_views[0]); + + // Ensure current highlighted result loses highlight on transition + SimulateKeyPress(ui::VKEY_TAB, false); + EXPECT_FALSE(tile_views[0]->background_highlighted()); + } + // Populate only answer card. SetUpSearchResults(0, 0, true); EXPECT_EQ(search_box_view()->search_box(), focused_view()); @@ -1269,14 +1392,19 @@ contents_view()->search_results_page_view()->first_result_view()); EXPECT_TRUE(answer_container->background_highlighted()); - // Moving focus to views other than search box textfield removes the first - // result's highlight. - SimulateKeyPress(ui::VKEY_TAB, false); - EXPECT_EQ(search_box_view()->close_button(), focused_view()); - EXPECT_EQ(answer_container, - contents_view()->search_results_page_view()->first_result_view()); - EXPECT_FALSE(answer_container->background_highlighted()); - SimulateKeyPress(ui::VKEY_TAB, true); + // SearchBoxSelection keeps selection within existing results. Tabbing from + // within a single result has no effect. + // This section should be removed with the flag. + if (!app_list_features::IsSearchBoxSelectionEnabled()) { + // Moving focus to views other than search box textfield removes the first + // result's highlight. + SimulateKeyPress(ui::VKEY_TAB, false); + EXPECT_EQ(search_box_view()->close_button(), focused_view()); + EXPECT_EQ(answer_container, + contents_view()->search_results_page_view()->first_result_view()); + EXPECT_FALSE(answer_container->background_highlighted()); + SimulateKeyPress(ui::VKEY_TAB, true); + } // Clear up all search results. SetUpSearchResults(0, 0, false); @@ -1290,6 +1418,12 @@ // happens when the user quickly hits Tab key after typing query and before // search results are updated for the new query). TEST_F(AppListViewFocusTest, FirstResultNotSelectedAfterQuicklyHittingTab) { + // This is a purposeful regression. The existing fix for this is not viable, + // but the trigger requires sub-100ms timing. As such, the investment in + // preventing this regression is not worth holding off a release. + if (app_list_features::IsSearchBoxSelectionEnabled()) + return; + Show(); // Type something in search box to transition to HALF state and populate
diff --git a/ash/app_list/views/page_switcher.cc b/ash/app_list/views/page_switcher.cc index 98602506..a0337cd 100644 --- a/ash/app_list/views/page_switcher.cc +++ b/ash/app_list/views/page_switcher.cc
@@ -195,10 +195,11 @@ if (vertical_) { buttons_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), kVerticalButtonPadding)); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), + kVerticalButtonPadding)); } else { buttons_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), kHorizontalButtonPadding)); }
diff --git a/ash/app_list/views/remove_query_confirmation_dialog.cc b/ash/app_list/views/remove_query_confirmation_dialog.cc index f67b731..8d1bde9d 100644 --- a/ash/app_list/views/remove_query_confirmation_dialog.cc +++ b/ash/app_list/views/remove_query_confirmation_dialog.cc
@@ -32,7 +32,7 @@ contents_view_(contents_view) { const views::LayoutProvider* provider = views::LayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, provider->GetDialogInsetsForContentType(views::TEXT, views::TEXT), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL)));
diff --git a/ash/app_list/views/result_selection_controller.cc b/ash/app_list/views/result_selection_controller.cc new file mode 100644 index 0000000..aae7cb39 --- /dev/null +++ b/ash/app_list/views/result_selection_controller.cc
@@ -0,0 +1,239 @@ +// 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 "ash/app_list/views/result_selection_controller.h" + +#include "ash/app_list/app_list_util.h" +#include "ash/app_list/views/search_result_container_view.h" + +namespace app_list { + +ResultLocationDetails::ResultLocationDetails(int container_index, + int container_count, + int result_index, + int result_count, + bool container_is_horizontal) + : container_index(container_index), + container_count(container_count), + result_index(result_index), + result_count(result_count), + container_is_horizontal(container_is_horizontal) {} + +bool ResultLocationDetails::operator==( + const ResultLocationDetails& other) const { + return container_index == other.container_index && + container_count == other.container_count && + result_index == other.result_index && + result_count == other.result_count && + container_is_horizontal == other.container_is_horizontal; +} + +bool ResultLocationDetails::operator!=( + const ResultLocationDetails& other) const { + return !(*this == other); +} + +ResultSelectionController::ResultSelectionController( + const ResultSelectionModel* result_container_views) + : result_selection_model_(result_container_views) {} + +ResultSelectionController::~ResultSelectionController() = default; + +bool ResultSelectionController::MoveSelection(const ui::KeyEvent& event) { + ResultLocationDetails next_location = GetNextResultLocation(event); + bool selection_changed = !(next_location == *selected_location_details_); + SetSelection(next_location); + return selection_changed; +} + +void ResultSelectionController::ResetSelection() { + // Prevents crash on start up + if (result_selection_model_->size() == 0) + return; + ClearSelection(); + selected_location_details_ = std::make_unique<ResultLocationDetails>( + 0 /* container_index */, + result_selection_model_->size() /* container_count */, + 0 /* result_index */, + result_selection_model_->at(0)->num_results() /* result_count */, + result_selection_model_->at(0) + ->horizontally_traversable() /* container_is_horizontal */); + + selected_result_ = result_selection_model_->at(0)->GetFirstResultView(); + if (selected_result_) + selected_result_->SetBackgroundHighlighted(true); +} + +void ResultSelectionController::ClearSelection() { + selected_location_details_ = nullptr; + if (selected_result_) + selected_result_->SetBackgroundHighlighted(false); + selected_result_ = nullptr; +} + +ResultLocationDetails ResultSelectionController::GetNextResultLocation( + const ui::KeyEvent& event) { + return GetNextResultLocationForLocation(event, *selected_location_details_); +} + +ResultLocationDetails +ResultSelectionController::GetNextResultLocationForLocation( + const ui::KeyEvent& event, + const ResultLocationDetails& location) { + ResultLocationDetails new_location(location); + + // Only arrow keys (unhandled and unmodified) or the tab key will change our + // selection. + if (!(IsUnhandledArrowKeyEvent(event) || event.key_code() == ui::VKEY_TAB)) + return new_location; + + switch (event.key_code()) { + case ui::VKEY_TAB: + if (event.IsShiftDown()) { + // Reverse tab traversal always goes to the 'previous' result. + if (location.is_first_result()) + ChangeContainer(&new_location, location.container_index - 1); + else + --new_location.result_index; + } else { + // Forward tab traversal always goes to the 'next' result. + if (location.is_last_result()) + ChangeContainer(&new_location, location.container_index + 1); + else + ++new_location.result_index; + } + + break; + case ui::VKEY_UP: + if (location.container_is_horizontal || location.is_first_result()) { + // Traversing 'up' from the top of a container changes containers. + ChangeContainer(&new_location, location.container_index - 1); + } else { + // Traversing 'up' moves up one result. + --new_location.result_index; + } + break; + case ui::VKEY_DOWN: + if (location.container_is_horizontal || location.is_last_result()) { + // Traversing 'down' from the bottom of a container changes containers. + ChangeContainer(&new_location, location.container_index + 1); + } else { + // Traversing 'down' moves down one result. + ++new_location.result_index; + } + break; + case ui::VKEY_RIGHT: + case ui::VKEY_LEFT: { + // Containers are stacked, so left/right does not traverse vertical + // containers. + if (!location.container_is_horizontal) + break; + + ui::KeyboardCode forward = ui::VKEY_RIGHT; + + // If RTL is active, 'forward' is left instead. + if (base::i18n::IsRTL()) + forward = ui::VKEY_LEFT; + + // Traversing should move one result, but loop within the + // container. + if (event.key_code() == forward) { + // If not at the last result, increment forward. + if (location.result_index != location.result_count - 1) + ++new_location.result_index; + else + // Loop back to the first result. + new_location.result_index = 0; + } else { + // If not at the first result, increment backward. + if (location.result_index != 0) + --new_location.result_index; + else + // Loop around to the last result. + new_location.result_index = location.result_count - 1; + } + } break; + + default: + NOTREACHED(); + } + return new_location; +} + +void ResultSelectionController::SetSelection( + const ResultLocationDetails& location) { + ClearSelection(); + + selected_result_ = GetResultAtLocation(location); + selected_location_details_ = + std::make_unique<ResultLocationDetails>(location); + selected_result_->SetBackgroundHighlighted(true); +} + +SearchResultBaseView* ResultSelectionController::GetResultAtLocation( + const ResultLocationDetails& location) { + SearchResultContainerView* located_container = + result_selection_model_->at(location.container_index); + return located_container->GetResultViewAt(location.result_index); +} + +void ResultSelectionController::ChangeContainer( + ResultLocationDetails* location_details, + int new_container_index) { + if (new_container_index == location_details->container_index) { + return; + } + + // If the index is advancing + bool container_advancing = + new_container_index > location_details->container_index; + + // This handles 'looping', so if the selection goes off the end of the + // container, it will come back to the beginning. + int new_container = new_container_index; + if (new_container < 0) { + new_container = location_details->container_count - 1; + } + if (new_container >= location_details->container_count) + new_container = 0; + + // Because all containers always exist, we need to make sure there are results + // in the next container. + while (result_selection_model_->at(new_container)->num_results() <= 0) { + if (container_advancing) { + ++new_container; + } else { + --new_container; + } + + // Prevent any potential infinite looping by resetting to '0', a container + // that should never be empty. + if (new_container <= 0 || + new_container >= location_details->container_count) { + new_container = 0; + break; + } + } + + // Updates |result_count| and |container_is_horizontal| based on + // |new_container|. + location_details->result_count = + result_selection_model_->at(new_container)->num_results(); + location_details->container_is_horizontal = + result_selection_model_->at(new_container)->horizontally_traversable(); + + // Updates |result_index| to the first or the last result in the container + // based on whether the |container_index| is increasing or decreasing. + if (container_advancing) { + location_details->result_index = 0; + } else { + location_details->result_index = location_details->result_count - 1; + } + + // Finally, we update |container_index| to the new index. |container_count| + // doesn't change in this function. + location_details->container_index = new_container; +} + +} // namespace app_list
diff --git a/ash/app_list/views/result_selection_controller.h b/ash/app_list/views/result_selection_controller.h new file mode 100644 index 0000000..b28a248 --- /dev/null +++ b/ash/app_list/views/result_selection_controller.h
@@ -0,0 +1,126 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_APP_LIST_VIEWS_RESULT_SELECTION_CONTROLLER_H_ +#define ASH_APP_LIST_VIEWS_RESULT_SELECTION_CONTROLLER_H_ + +#include <vector> + +#include "ash/app_list/app_list_export.h" +#include "ash/app_list/views/search_result_base_view.h" +#include "ash/app_list/views/search_result_container_view.h" +#include "base/macros.h" + +namespace app_list { + +class SearchResultContainerView; + +// This alias is intended to clarify the intended use of this class within the +// context of this controller. +using ResultSelectionModel = std::vector<SearchResultContainerView*>; + +// Stores and organizes the details for the 'coordinates' of the selected +// result. This includes all information to determine exactly where a result is, +// including both inter- and intra-container details, along with the traversal +// direction for the container. +struct APP_LIST_EXPORT ResultLocationDetails { + ResultLocationDetails(int container_index, + int container_count, + int result_index, + int result_count, + bool container_is_horizontal); + + bool operator==(const ResultLocationDetails& other) const; + bool operator!=(const ResultLocationDetails& other) const; + + // True if the result is the first(0th) in its container + bool is_first_result() const { return result_index == 0; } + + // True if the result is the last in its container + bool is_last_result() const { return result_index == (result_count - 1); } + + // Index of the container within the overall nest of containers. + int container_index = 0; + + // Number of containers to traverse among. + int container_count = 0; + + // Index of the result within the list of results inside a container. + int result_index = 0; + + // Number of results within the current container. + int result_count = 0; + + // Whether the container is horizontally traversable. + bool container_is_horizontal = false; +}; + +// A controller class to manage result selection across containers. +class APP_LIST_EXPORT ResultSelectionController { + public: + explicit ResultSelectionController( + const ResultSelectionModel* result_container_views); + ~ResultSelectionController(); + + // Returns the currently selected result. + SearchResultBaseView* selected_result() { return selected_result_; } + + // Returns the |ResultLocationDetails| object for the |selected_result_|. + ResultLocationDetails* selected_location_details() { + return selected_location_details_.get(); + } + + // Calls |SetSelection| using the result of |GetNextResultLocation|. Returns + // true if selection was changed. + bool MoveSelection(const ui::KeyEvent& event); + + // Resets the selection to the first result. + void ResetSelection(); + + // Clears the |selected_result_|, |selected_location_details_|. + void ClearSelection(); + + private: + // Calls |GetNextResultLocationForLocation| using |selected_location_details_| + // as the location + ResultLocationDetails GetNextResultLocation(const ui::KeyEvent& event); + + // Logic for next is separated for modular use. You can ask for the "next" + // location to be generated using any starting location/event combination. + ResultLocationDetails GetNextResultLocationForLocation( + const ui::KeyEvent& event, + const ResultLocationDetails& location); + + // Sets the current selection to the provided |location|. + void SetSelection(const ResultLocationDetails& location); + + SearchResultBaseView* GetResultAtLocation( + const ResultLocationDetails& location); + + // Updates a |ResultLocationDetails| to a new container, updating most + // attributes based on |result_selection_model_|. + void ChangeContainer(ResultLocationDetails* location_details, + int new_container_index); + + // Container views to be traversed by this controller. + // Owned by |SearchResultPageView|. + const ResultSelectionModel* result_selection_model_; + + // Returns true if the container at the given |index| within + // |result_selection_model_| responds true to + // |SearchResultContainerView|->|IsHorizontallyTraversable|. + bool IsContainerAtIndexHorizontallyTraversable(int index) const; + + // The currently selected result view + SearchResultBaseView* selected_result_ = nullptr; + + // The |ResultLocationDetails| for the currently selected result view + std::unique_ptr<ResultLocationDetails> selected_location_details_; + + DISALLOW_COPY_AND_ASSIGN(ResultSelectionController); +}; + +} // namespace app_list + +#endif // ASH_APP_LIST_VIEWS_RESULT_SELECTION_CONTROLLER_H_
diff --git a/ash/app_list/views/result_selection_controller_unittest.cc b/ash/app_list/views/result_selection_controller_unittest.cc new file mode 100644 index 0000000..9b73060 --- /dev/null +++ b/ash/app_list/views/result_selection_controller_unittest.cc
@@ -0,0 +1,425 @@ +// 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 "ash/app_list/views/result_selection_controller.h" + +#include <gtest/gtest.h> +#include <cctype> +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "ash/app_list/test/app_list_test_view_delegate.h" +#include "ash/app_list/views/search_result_container_view.h" +#include "base/macros.h" +#include "ui/events/event.h" + +namespace app_list { +namespace { + +class TestResultView : public SearchResultBaseView { + public: + TestResultView() = default; + ~TestResultView() override = default; + + void ButtonPressed(Button* sender, const ui::Event& event) override { + // Do nothing for test. + } + + private: + DISALLOW_COPY_AND_ASSIGN(TestResultView); +}; + +// Allows immediate invocation of |VerticalTestContainer| and its derivatives, +// by handling the fake delegate's setup. +class TestContainerDelegateHarness { + public: + TestContainerDelegateHarness() { + app_list_test_delegate_ = + std::make_unique<app_list::test::AppListTestViewDelegate>(); + } + + ~TestContainerDelegateHarness() = default; + + protected: + std::unique_ptr<app_list::test::AppListTestViewDelegate> + app_list_test_delegate_; + + DISALLOW_COPY_AND_ASSIGN(TestContainerDelegateHarness); +}; + +class VerticalTestContainer : public TestContainerDelegateHarness, + public SearchResultContainerView { + public: + explicit VerticalTestContainer(int num_results) + : SearchResultContainerView(app_list_test_delegate_.get()) { + for (int i = 0; i < num_results; ++i) { + search_result_views_.emplace_back(std::make_unique<TestResultView>()); + search_result_views_.back()->set_index_in_container(i); + } + Update(); + } + ~VerticalTestContainer() override = default; + + TestResultView* GetResultViewAt(size_t index) override { + DCHECK_LT(index, search_result_views_.size()); + return search_result_views_[index].get(); + } + + private: + int DoUpdate() override { return search_result_views_.size(); } + + std::vector<std::unique_ptr<TestResultView>> search_result_views_; + + DISALLOW_COPY_AND_ASSIGN(VerticalTestContainer); +}; + +class HorizontalTestContainer : public VerticalTestContainer { + public: + explicit HorizontalTestContainer(int num_results) + : VerticalTestContainer(num_results) { + set_horizontally_traversable(true); + } + + ~HorizontalTestContainer() override = default; + + DISALLOW_COPY_AND_ASSIGN(HorizontalTestContainer); +}; + +class ResultSelectionTest : public testing::Test, + public testing::WithParamInterface<bool> { + public: + ResultSelectionTest() = default; + ~ResultSelectionTest() override = default; + + void SetUp() override { + if (testing::UnitTest::GetInstance()->current_test_info()->value_param()) { + // Setup right to left environment if necessary. + is_rtl_ = GetParam(); + if (is_rtl_) + base::i18n::SetICUDefaultLocale("he"); + } + + if (!is_rtl_) { + // Reset RTL if not needed. + base::i18n::SetICUDefaultLocale("en"); + } + + result_selection_controller_ = + std::make_unique<ResultSelectionController>(&containers_); + + testing::Test::SetUp(); + } + + protected: + std::vector<std::unique_ptr<SearchResultContainerView>> + CreateContainerVector(int container_count, int results, bool horizontal) { + std::vector<std::unique_ptr<SearchResultContainerView>> containers; + for (int i = 0; i < container_count; i++) { + if (horizontal) { + containers.emplace_back( + std::make_unique<HorizontalTestContainer>(results)); + } else { + containers.emplace_back( + std::make_unique<VerticalTestContainer>(results)); + } + } + return containers; + } + + std::vector<ResultLocationDetails> CreateLocationVector( + int results, + bool horizontal, + int container_count = 1, + int container_index = 0) { + std::vector<ResultLocationDetails> locations; + for (int i = 0; i < results; i++) { + locations.emplace_back(ResultLocationDetails( + container_index /*container_index*/, + container_count /*container_count*/, i /*result_index*/, + results /*result_count*/, horizontal /*container_is_horizontal*/)); + } + return locations; + } + + void SetContainers( + const std::vector<std::unique_ptr<SearchResultContainerView>>& + containers) { + containers_.clear(); + for (auto& container : containers) { + containers_.emplace_back(container.get()); + } + } + + void TestSingleAxisTraversal(ui::KeyEvent* forward, ui::KeyEvent* backward) { + const bool horizontal = + result_selection_controller_->selected_location_details() + ->container_is_horizontal; + + std::vector<ResultLocationDetails> locations = + CreateLocationVector(4, horizontal); + + // These are divided to give as much detail as possible for a test failure. + TestSingleAxisForward(forward, locations); + TestSingleAxisLoop(forward, locations); + TestSingleAxisLoopBack(backward, locations); + TestSingleAxisBackward(backward, locations); + } + + void TestSingleAxisForward( + ui::KeyEvent* forward, + const std::vector<ResultLocationDetails>& locations) { + // Starts at the beginning + ASSERT_EQ(*result_selection_controller_->selected_location_details(), + locations[0]); + for (int i = 1; i < (int)locations.size(); i++) { + result_selection_controller_->MoveSelection(*forward); + ASSERT_EQ(*result_selection_controller_->selected_location_details(), + locations[i]); + } + // Expect steady traversal to the end + } + + void TestSingleAxisLoop(ui::KeyEvent* forward, + const std::vector<ResultLocationDetails>& locations) { + // Starts at the end + ASSERT_EQ(*result_selection_controller_->selected_location_details(), + locations[3]); + + // Expect loop back to first result. + result_selection_controller_->MoveSelection(*forward); + ASSERT_EQ(*result_selection_controller_->selected_location_details(), + locations[0]); + } + + void TestSingleAxisLoopBack( + ui::KeyEvent* backward, + const std::vector<ResultLocationDetails>& locations) { + // Starts at the first + ASSERT_EQ(*result_selection_controller_->selected_location_details(), + locations[0]); + + // Expect loop back to last result. + result_selection_controller_->MoveSelection(*backward); + ASSERT_EQ(*result_selection_controller_->selected_location_details(), + locations[3]); + } + + void TestSingleAxisBackward( + ui::KeyEvent* backward, + const std::vector<ResultLocationDetails>& locations) { + const int last_index = (int)locations.size() - 1; + + // Test reverse direction from last result + ASSERT_EQ(*result_selection_controller_->selected_location_details(), + locations[last_index]); + for (int i = last_index - 1; i >= 0; i--) { + result_selection_controller_->MoveSelection(*backward); + ASSERT_EQ(*result_selection_controller_->selected_location_details(), + locations[i]); + } + } + + void TestMultiAxisTraversal(bool tab) { + ui::KeyEvent* forward; + ui::KeyEvent* backward; + ui::KeyEvent* vertical_forward; + ui::KeyEvent* vertical_backward; + if (tab) { + // Set up for tab traversal + forward = vertical_forward = &tab_key_; + backward = vertical_backward = &shift_tab_key_; + } else { + // Set up for arrow key traversal + forward = is_rtl_ ? &left_arrow_ : &right_arrow_; + backward = is_rtl_ ? &right_arrow_ : &left_arrow_; + vertical_forward = &down_arrow_; + vertical_backward = &up_arrow_; + } + + int num_containers = containers_.size(); + + for (int i = 0; i < num_containers; i++) { + const bool horizontal = + result_selection_controller_->selected_location_details() + ->container_is_horizontal; + + std::vector<ResultLocationDetails> locations = + CreateLocationVector(4, horizontal, num_containers, i); + + if (horizontal && !tab) { + TestSingleAxisForward(forward, locations); + TestSingleAxisLoop(forward, locations); + TestSingleAxisLoopBack(backward, locations); + TestSingleAxisBackward(backward, locations); + TestSingleAxisLoopBack(backward, locations); + // End on the last result. + } else { + // Tab and Vertical traversal are identical + TestSingleAxisForward(vertical_forward, locations); + TestSingleAxisBackward(vertical_backward, locations); + TestSingleAxisForward(vertical_forward, locations); + // End on the last result. + } + + // Change Containers + result_selection_controller_->MoveSelection(*vertical_forward); + } + } + + std::unique_ptr<ResultSelectionController> result_selection_controller_; + std::vector<SearchResultContainerView*> containers_; + + // Set up key events for test. These will never be marked as 'handled'. + ui::KeyEvent down_arrow_ = + ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_DOWN, ui::EF_NONE); + ui::KeyEvent up_arrow_ = + ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_UP, ui::EF_NONE); + ui::KeyEvent left_arrow_ = + ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_LEFT, ui::EF_NONE); + ui::KeyEvent right_arrow_ = + ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RIGHT, ui::EF_NONE); + ui::KeyEvent tab_key_ = + ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_TAB, ui::EF_NONE); + ui::KeyEvent shift_tab_key_ = + ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_TAB, ui::EF_SHIFT_DOWN); + + bool is_rtl_ = false; + + DISALLOW_COPY_AND_ASSIGN(ResultSelectionTest); +}; + +INSTANTIATE_TEST_SUITE_P(RTL, ResultSelectionTest, testing::Bool()); + +} // namespace + +TEST_F(ResultSelectionTest, VerticalTraversalOneContainerArrowKeys) { + std::unique_ptr<VerticalTestContainer> vertical_container = + std::make_unique<VerticalTestContainer>(4); + // The vertical container is not horizontally traversable + ASSERT_FALSE(vertical_container->horizontally_traversable()); + + containers_.clear(); + containers_.emplace_back(vertical_container.get()); + + // Initialize the RSC for test. + result_selection_controller_->ResetSelection(); + + TestSingleAxisTraversal(&down_arrow_, &up_arrow_); +} + +TEST_F(ResultSelectionTest, VerticalTraversalOneContainerTabKey) { + std::unique_ptr<VerticalTestContainer> vertical_container = + std::make_unique<VerticalTestContainer>(4); + + // The vertical container is not horizontally traversable + ASSERT_FALSE(vertical_container->horizontally_traversable()); + + containers_.clear(); + containers_.emplace_back(vertical_container.get()); + + // Initialize the RSC for test. + result_selection_controller_->ResetSelection(); + + TestSingleAxisTraversal(&tab_key_, &shift_tab_key_); +} + +TEST_P(ResultSelectionTest, HorizontalTraversalOneContainerArrowKeys) { + ui::KeyEvent* forward = is_rtl_ ? &left_arrow_ : &right_arrow_; + ui::KeyEvent* backward = is_rtl_ ? &right_arrow_ : &left_arrow_; + + std::unique_ptr<HorizontalTestContainer> horizontal_container = + std::make_unique<HorizontalTestContainer>(4); + + // The horizontal container is horizontally traversable + ASSERT_TRUE(horizontal_container->horizontally_traversable()); + + containers_.clear(); + containers_.emplace_back(horizontal_container.get()); + + // Initialize the RSC for test. + result_selection_controller_->ResetSelection(); + + TestSingleAxisTraversal(forward, backward); +} + +TEST_P(ResultSelectionTest, HorizontalVerticalArrowKeys) { + std::unique_ptr<HorizontalTestContainer> horizontal_container = + std::make_unique<HorizontalTestContainer>(4); + std::unique_ptr<VerticalTestContainer> vertical_container = + std::make_unique<VerticalTestContainer>(4); + + containers_.clear(); + containers_.emplace_back(horizontal_container.get()); + containers_.emplace_back(vertical_container.get()); + + // Initialize the RSC for test. + result_selection_controller_->ResetSelection(); + + TestMultiAxisTraversal(false); +} + +TEST_F(ResultSelectionTest, HorizontalVerticalTab) { + std::unique_ptr<HorizontalTestContainer> horizontal_container = + std::make_unique<HorizontalTestContainer>(4); + std::unique_ptr<VerticalTestContainer> vertical_container = + std::make_unique<VerticalTestContainer>(4); + + containers_.clear(); + containers_.emplace_back(horizontal_container.get()); + containers_.emplace_back(vertical_container.get()); + + // Initialize the RSC for test. + result_selection_controller_->ResetSelection(); + + TestMultiAxisTraversal(true); +} + +TEST_F(ResultSelectionTest, TestVerticalStackArrows) { + std::vector<std::unique_ptr<SearchResultContainerView>> vertical_containers = + CreateContainerVector(4, 4, false); + SetContainers(vertical_containers); + + // Initialize the RSC for test. + result_selection_controller_->ResetSelection(); + + TestMultiAxisTraversal(false); +} + +TEST_F(ResultSelectionTest, TestVerticalStackTab) { + std::vector<std::unique_ptr<SearchResultContainerView>> vertical_containers = + CreateContainerVector(4, 4, false); + SetContainers(vertical_containers); + + // Initialize the RSC for test. + result_selection_controller_->ResetSelection(); + + TestMultiAxisTraversal(true); +} + +TEST_P(ResultSelectionTest, TestHorizontalStackArrows) { + std::vector<std::unique_ptr<SearchResultContainerView>> + horizontal_containers = CreateContainerVector(4, 4, true); + SetContainers(horizontal_containers); + + // Initialize the RSC for test. + result_selection_controller_->ResetSelection(); + + TestMultiAxisTraversal(false); +} + +TEST_F(ResultSelectionTest, TestHorizontalStackTab) { + std::vector<std::unique_ptr<SearchResultContainerView>> + horizontal_containers = CreateContainerVector(4, 4, true); + SetContainers(horizontal_containers); + + // Initialize the RSC for test. + result_selection_controller_->ResetSelection(); + + TestMultiAxisTraversal(true); +} + +} // namespace app_list
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index 6339100..71756e9 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -17,6 +17,7 @@ #include "ash/app_list/views/app_list_view.h" #include "ash/app_list/views/contents_view.h" #include "ash/app_list/views/expand_arrow_view.h" +#include "ash/app_list/views/result_selection_controller.h" #include "ash/app_list/views/search_result_base_view.h" #include "ash/app_list/views/search_result_page_view.h" #include "ash/keyboard/ui/keyboard_controller.h" @@ -424,7 +425,8 @@ const base::string16& user_typed_text = search_box()->text().substr(0, highlight_range_.start()); if (last_key_pressed_ == ui::VKEY_BACK || - last_key_pressed_ == ui::VKEY_DELETE || !first_visible_result || + last_key_pressed_ == ui::VKEY_DELETE || IsArrowKey(last_key_pressed_) || + !first_visible_result || user_typed_text.length() < kMinimumLengthToAutocomplete) { // If the suggestion was rejected, no results exist, or current text // is too short for a confident autocomplete suggestion. @@ -553,19 +555,39 @@ bool SearchBoxView::HandleKeyEvent(views::Textfield* sender, const ui::KeyEvent& key_event) { - if (key_event.type() == ui::ET_KEY_PRESSED && - key_event.key_code() == ui::VKEY_RETURN) { - if (is_search_box_active()) { - // Hitting Enter when focus is on search box opens the first result. - ui::KeyEvent event(key_event); - views::View* first_result_view = - contents_view_->search_results_page_view()->first_result_view(); - if (first_result_view) - first_result_view->OnKeyEvent(&event); - } else { - SetSearchBoxActive(true, key_event.type()); + ResultSelectionController* selection_controller = + contents_view_->search_results_page_view()->result_selection_controller(); + if (app_list_features::IsSearchBoxSelectionEnabled()) { + if (key_event.type() == ui::ET_KEY_RELEASED) + return false; + + if (key_event.key_code() == ui::VKEY_RETURN) { + if (is_search_box_active()) { + // Hitting Enter when focus is on search box opens the selected result. + ui::KeyEvent event(key_event); + views::View* selected_result = selection_controller->selected_result(); + if (selected_result) + selected_result->OnKeyEvent(&event); + } else { + SetSearchBoxActive(true, key_event.type()); + } + return true; } - return true; + } else { + if (key_event.type() == ui::ET_KEY_PRESSED && + key_event.key_code() == ui::VKEY_RETURN) { + if (is_search_box_active()) { + // Hitting Enter when focus is on search box opens the first result. + ui::KeyEvent event(key_event); + views::View* first_result_view = + contents_view_->search_results_page_view()->first_result_view(); + if (first_result_view) + first_result_view->OnKeyEvent(&event); + } else { + SetSearchBoxActive(true, key_event.type()); + } + return true; + } } // Events occurring over an inactive search box are handled elsewhere, with @@ -577,14 +599,33 @@ return false; } + if (app_list_features::IsSearchBoxSelectionEnabled()) { + // Allows alt+back and alt+delete as a shortcut for the 'remove result' + // dialog + if (key_event.IsAltDown() && + ((key_event.key_code() == ui::VKEY_BROWSER_BACK) || + (key_event.key_code() == ui::VKEY_DELETE))) { + ui::KeyEvent event(key_event); + views::View* selected_result = selection_controller->selected_result(); + if (selected_result) + selected_result->OnKeyEvent(&event); + selection_controller->ResetSelection(); + search_box()->SetText(base::string16()); + return true; + } + } + // Record the |last_key_pressed_| for autocomplete. if (!search_box()->text().empty() && ShouldProcessAutocomplete()) last_key_pressed_ = key_event.key_code(); - // Only arrow key events intended for traversal within search results should - // be handled from here. - if (!IsUnhandledArrowKeyEvent(key_event)) + // Only arrow key or tab events intended for traversal within search results + // should be handled from here. + if (!(IsUnhandledArrowKeyEvent(key_event) || + (key_event.key_code() == ui::VKEY_TAB && + app_list_features::IsSearchBoxSelectionEnabled()))) { return false; + } SearchResultPageView* search_page = contents_view_->search_results_page_view(); @@ -595,25 +636,57 @@ ui::KeyboardCode backward = base::i18n::IsRTL() ? ui::VKEY_RIGHT : ui::VKEY_LEFT; - // Left/Right arrow keys are handled elsewhere, unless the first result is a - // tile, in which case right will be handled below. - // The focus traversal in the search box is based around the 'implicit focus' - // or whichever result is highlighted. As a result, we are trying to move - // the actual focus based on the position of this highlight. - // In addition to that, when there are tiles we want to allow a left/right - // traversal among the tiles. When there are no tiles, left/right should be - // handled in the ordinary way that a textfield would handle it. - if (key_event.key_code() == backward || - (key_event.key_code() == forward && !search_page->IsFirstResultTile())) { - return ProcessLeftRightKeyTraversalForTextfield(search_box(), key_event); + if (app_list_features::IsSearchBoxSelectionEnabled()) { + // Left/Right arrow keys are handled by the textfield, unless the current + // |search_result_container_view| is horizontal, in which case they are + // handled here, by the |result_selection_controller| + if ((key_event.key_code() == backward || key_event.key_code() == forward) && + !selection_controller->selected_location_details() + ->container_is_horizontal) { + return false; + } + + // If the |ResultSelectionController| decided not to change selection, + // return early, as what follows is actions for updating based on change. + if (!selection_controller->MoveSelection(key_event)) + return true; + + // Tells ChromeVox to read this result + selection_controller->selected_result()->NotifyAccessibilityEvent( + ax::mojom::Event::kSelection, true); + + // Fill text on result change. + SearchResultBaseView* selected_result_view = + selection_controller->selected_result(); + if (selected_result_view->result()->result_type() == + ash::SearchResultType::kOmnibox && + !selected_result_view->result()->is_omnibox_search()) { + // Use details to ensure url results fill url + search_box()->SetText(selected_result_view->result()->details()); + } else { + search_box()->SetText(selected_result_view->result()->title()); + } } - // Right arrow key should not be handled if the cursor is within text. - if (key_event.key_code() == forward && - !LeftRightKeyEventShouldExitText(search_box(), key_event)) { - return false; + // This code should be removed with the flag. + if (!app_list_features::IsSearchBoxSelectionEnabled()) { + if (key_event.key_code() == backward || + (key_event.key_code() == forward && + !search_page->IsFirstResultTile())) { + return ProcessLeftRightKeyTraversalForTextfield(search_box(), key_event); + } + + // Right arrow key should not be handled if the cursor is within text. + if (key_event.key_code() == forward && + !LeftRightKeyEventShouldExitText(search_box(), key_event)) { + return false; + } } + // All code below this line should be removed with the flag. + if (app_list_features::IsSearchBoxSelectionEnabled()) + return true; + views::View* result_view = nullptr; // The up arrow will loop focus to the last result.
diff --git a/ash/app_list/views/search_box_view_unittest.cc b/ash/app_list/views/search_box_view_unittest.cc index 09141e5..3156302 100644 --- a/ash/app_list/views/search_box_view_unittest.cc +++ b/ash/app_list/views/search_box_view_unittest.cc
@@ -79,6 +79,7 @@ counter_view_ = new KeyPressCounterView(app_list_view_); widget_->GetContentsView()->AddChildView(view()); widget_->GetContentsView()->AddChildView(counter_view_); + counter_view_->Init(view_delegate_.GetModel()); view()->set_contents_view(counter_view_); } @@ -597,12 +598,8 @@ } // Tests that autocomplete suggestion is accepted and displayed in SearchModel -// after pressing the tab key, clicking on the search box, or gesture tapping on -// the search box. -TEST_F(SearchBoxViewAutocompleteTest, - SearchBoxAcceptsAutocompleteForTabClickTap) { - TestKeyEvent(ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_TAB, ui::EF_NONE), - true); +// after clicking or tapping on the search box. +TEST_F(SearchBoxViewAutocompleteTest, SearchBoxAcceptsAutocompleteForClickTap) { TestMouseEvent(ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), 0, 0), true);
diff --git a/ash/app_list/views/search_result_actions_view.cc b/ash/app_list/views/search_result_actions_view.cc index 25a4a0b59..ba7d9b6 100644 --- a/ash/app_list/views/search_result_actions_view.cc +++ b/ash/app_list/views/search_result_actions_view.cc
@@ -220,7 +220,7 @@ SearchResultActionsViewDelegate* delegate) : delegate_(delegate) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), kActionButtonBetweenSpacing)); }
diff --git a/ash/app_list/views/search_result_list_view.cc b/ash/app_list/views/search_result_list_view.cc index d6c9a428..3a4fa016 100644 --- a/ash/app_list/views/search_result_list_view.cc +++ b/ash/app_list/views/search_result_list_view.cc
@@ -118,8 +118,8 @@ main_view_(main_view), view_delegate_(view_delegate), results_container_(new views::View) { - results_container_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + results_container_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); for (int i = 0; i < kMaxResults; ++i) { search_result_views_.emplace_back(
diff --git a/ash/app_list/views/search_result_page_view.cc b/ash/app_list/views/search_result_page_view.cc index 5445f54..51b6607 100644 --- a/ash/app_list/views/search_result_page_view.cc +++ b/ash/app_list/views/search_result_page_view.cc
@@ -19,6 +19,7 @@ #include "ash/app_list/views/search_result_list_view.h" #include "ash/app_list/views/search_result_tile_item_list_view.h" #include "ash/public/cpp/app_list/app_list_config.h" +#include "ash/public/cpp/app_list/app_list_features.h" #include "base/memory/ptr_util.h" #include "ui/chromeos/search_box/search_box_constants.h" #include "ui/gfx/canvas.h" @@ -155,7 +156,7 @@ SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false); contents_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), 0)); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), 0)); if (view_delegate_->ShouldShowAssistantPrivacyInfo()) { assistant_privacy_info_view_ = new PrivacyInfoView(view_delegate_, this); @@ -192,6 +193,9 @@ AddChildView(scroller); SetLayoutManager(std::make_unique<views::FillLayout>()); + + result_selection_controller_ = + std::make_unique<ResultSelectionController>(&result_container_views_); } SearchResultPageView::~SearchResultPageView() = default; @@ -322,31 +326,40 @@ ReorderSearchResultContainers(); - views::View* focused_view = GetFocusManager()->GetFocusedView(); + if (!app_list_features::IsSearchBoxSelectionEnabled()) { + views::View* focused_view = GetFocusManager()->GetFocusedView(); - // Clear the first search result view's background highlight. - if (first_result_view_ && first_result_view_ != focused_view) - first_result_view_->SetBackgroundHighlighted(false); + // Clear the first search result view's background highlight. + if (first_result_view_ && first_result_view_ != focused_view) + first_result_view_->SetBackgroundHighlighted(false); + } first_result_view_ = result_container_views_[0]->GetFirstResultView(); - - // Update SearchBoxView search box autocomplete as necessary based on new - // first result view. - if (first_result_view_) - AppListPage::contents_view()->GetSearchBoxView()->ProcessAutocomplete(); - - // If one of the search result is focused, do not highlight the first search - // result. - if (Contains(focused_view)) - return; - if (!first_result_view_) return; - // Highlight the first result after search results are updated. Note that the - // focus is not set on the first result to prevent frequent focus switch - // between the search box and the first result when the user is typing query. - first_result_view_->SetBackgroundHighlighted(true); + if (!app_list_features::IsSearchBoxSelectionEnabled()) { + views::View* focused_view = GetFocusManager()->GetFocusedView(); + // If one of the search result is focused, do not highlight the first search + // result. + if (Contains(focused_view)) + return; + } + + // Update SearchBoxView search box autocomplete as necessary based on new + // first result view. + AppListPage::contents_view()->GetSearchBoxView()->ProcessAutocomplete(); + + if (app_list_features::IsSearchBoxSelectionEnabled()) { + // Reset selection to first when things change. + result_selection_controller_->ResetSelection(); + } else { + // Highlight the first result after search results are updated. Note that + // the focus is not set on the first result to prevent frequent focus switch + // between the search box and the first result when the user is typing + // query. + first_result_view_->SetBackgroundHighlighted(true); + } } void SearchResultPageView::OnSearchResultContainerResultFocused(
diff --git a/ash/app_list/views/search_result_page_view.h b/ash/app_list/views/search_result_page_view.h index 7cc7e90..f91abe0 100644 --- a/ash/app_list/views/search_result_page_view.h +++ b/ash/app_list/views/search_result_page_view.h
@@ -10,6 +10,7 @@ #include "ash/app_list/app_list_export.h" #include "ash/app_list/model/app_list_model.h" #include "ash/app_list/views/app_list_page.h" +#include "ash/app_list/views/result_selection_controller.h" #include "ash/app_list/views/search_result_container_view.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -65,6 +66,9 @@ views::View* contents_view() { return contents_view_; } SearchResultBaseView* first_result_view() const { return first_result_view_; } + ResultSelectionController* result_selection_controller() { + return result_selection_controller_.get(); + } // Offset/add the size of the shadow border to the bounds // for proper sizing/placement with shadow included. @@ -83,6 +87,10 @@ // the views hierarchy. std::vector<SearchResultContainerView*> result_container_views_; + // |ResultSelectionController| handles selection within the + // |result_container_views_| + std::unique_ptr<ResultSelectionController> result_selection_controller_; + std::vector<HorizontalSeparator*> separators_; // View containing SearchCardView instances. Owned by view hierarchy.
diff --git a/ash/app_list/views/search_result_tile_item_list_view.cc b/ash/app_list/views/search_result_tile_item_list_view.cc index 530ae333..5e7a5f00 100644 --- a/ash/app_list/views/search_result_tile_item_list_view.cc +++ b/ash/app_list/views/search_result_tile_item_list_view.cc
@@ -82,7 +82,7 @@ max_search_result_tiles_( AppListConfig::instance().max_search_result_tiles()) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(kItemListVerticalSpacing, kItemListHorizontalSpacing), kBetweenItemSpacing)); for (size_t i = 0; i < max_search_result_tiles_; ++i) {
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc index 020dff8..8122648 100644 --- a/ash/app_list/views/search_result_view.cc +++ b/ash/app_list/views/search_result_view.cc
@@ -235,6 +235,12 @@ return !actions_view_->children().empty() && list_view_->HandleVerticalFocusMovement( this, event.key_code() == ui::VKEY_UP); + case ui::VKEY_DELETE: + case ui::VKEY_BROWSER_BACK: + // Allows alt+(back or delete) to trigger the 'remove result' dialog. + OnSearchResultActionActivated( + ash::OmniBoxZeroStateAction::kRemoveSuggestion, event.flags()); + return true; default: return false; }
diff --git a/ash/components/shortcut_viewer/views/bubble_view.cc b/ash/components/shortcut_viewer/views/bubble_view.cc index d325ae5..0159753 100644 --- a/ash/components/shortcut_viewer/views/bubble_view.cc +++ b/ash/components/shortcut_viewer/views/bubble_view.cc
@@ -46,7 +46,8 @@ kVerticalBottomPadding, kHorizontalPadding))); views::BoxLayout* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), kIconTextSpacing)); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + kIconTextSpacing)); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kCenter); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter);
diff --git a/ash/components/shortcut_viewer/views/keyboard_shortcut_item_list_view.cc b/ash/components/shortcut_viewer/views/keyboard_shortcut_item_list_view.cc index 2a71479..74be6773 100644 --- a/ash/components/shortcut_viewer/views/keyboard_shortcut_item_list_view.cc +++ b/ash/components/shortcut_viewer/views/keyboard_shortcut_item_list_view.cc
@@ -53,7 +53,8 @@ // side tab than the padding between list view and the border of the window. constexpr int kLeftPadding = 16; constexpr int kRightPadding = 32; - auto layout = std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + auto layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kCenter); SetLayoutManager(std::move(layout)); SetBorder(
diff --git a/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc b/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc index e566999..acdf852d 100644 --- a/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc +++ b/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc
@@ -70,7 +70,8 @@ constexpr int kTopPadding = 98; views::BoxLayout* layout = illustration_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(kTopPadding, 0, 0, 0))); + views::BoxLayout::Orientation::kVertical, + gfx::Insets(kTopPadding, 0, 0, 0))); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); views::ImageView* image_view = new views::ImageView(); image_view->SetImage(
diff --git a/ash/lock_screen_action/lock_screen_action_background_view.cc b/ash/lock_screen_action/lock_screen_action_background_view.cc index 711f0fc..44c2fe7 100644 --- a/ash/lock_screen_action/lock_screen_action_background_view.cc +++ b/ash/lock_screen_action/lock_screen_action_background_view.cc
@@ -63,8 +63,8 @@ }; LockScreenActionBackgroundView::LockScreenActionBackgroundView() { - auto layout_manager = - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + auto layout_manager = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); layout_manager->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch); auto* layout_ptr = SetLayoutManager(std::move(layout_manager));
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index 3c65f08..78f9a8f 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -409,8 +409,8 @@ // The top header view. top_header_ = new views::View(); - auto top_header_layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal); + auto top_header_layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal); top_header_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kEnd); top_header_->SetLayoutManager(std::move(top_header_layout)); @@ -419,7 +419,7 @@ system_info_ = new views::View(); auto* system_info_layout = system_info_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(6, 8))); + views::BoxLayout::Orientation::kVertical, gfx::Insets(6, 8))); system_info_layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kEnd); system_info_->SetVisible(false); @@ -655,8 +655,9 @@ } // Allocate layout and big user, which are common between all densities. - auto* main_layout = main_view_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + auto* main_layout = + main_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); main_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); main_layout->set_cross_axis_alignment( @@ -771,8 +772,8 @@ big_view->auth_user()->password_view()->GetPreferredSize().width()); auto* container = new NonAccessibleView(); - container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); container->AddChildView(label); auth_error_bubble_->SetAnchorView(big_view->auth_user()->password_view()); @@ -1738,7 +1739,7 @@ auto* container = new NonAccessibleView(kAuthErrorContainerName); container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), kLearnMoreButtonVerticalSpacingDp)); container->AddChildView(label); container->AddChildView(learn_more_button);
diff --git a/ash/login/ui/lock_debug_view.cc b/ash/login/ui/lock_debug_view.cc index 1c2b09e..cca2052 100644 --- a/ash/login/ui/lock_debug_view.cc +++ b/ash/login/ui/lock_debug_view.cc
@@ -666,8 +666,8 @@ &LockDebugView::UpdatePerUserActionContainerAndLayout, base::Unretained(this)))), next_auth_error_type_(AuthErrorType::kFirstUnlockFailed) { - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); auto debug_detachable_base_model = std::make_unique<DebugLoginDetachableBaseModel>(); @@ -679,8 +679,8 @@ AddChildView(lock_); container_ = new NonAccessibleView(); - container_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + container_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); AddChildView(container_); auto* margin = new NonAccessibleView(); @@ -689,12 +689,13 @@ global_action_view_container_ = new NonAccessibleView(); global_action_view_container_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); auto add_horizontal_container = [&]() { auto* container = new NonAccessibleView(); - container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); global_action_view_container_->AddChildView(container); return container; }; @@ -739,7 +740,8 @@ per_user_action_view_container_ = new NonAccessibleView(); per_user_action_view_container_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); UpdatePerUserActionContainer(); auto make_scroll = [](views::View* content, @@ -1047,8 +1049,8 @@ int num_users = debug_data_dispatcher_->GetUserCount(); for (int i = 0; i < num_users; ++i) { auto* row = new NonAccessibleView(); - row->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + row->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); auto* name = new views::Label(); name->SetText(debug_data_dispatcher_->GetDisplayNameForUserIndex(i));
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc index 9953ed7..c633aaa 100644 --- a/ash/login/ui/login_auth_user_view.cc +++ b/ash/login/ui/login_auth_user_view.cc
@@ -328,7 +328,7 @@ SetBorder(views::CreateEmptyBorder(kFingerprintIconTopSpacingDp, 0, 0, 0)); auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), kSpacingBetweenFingerprintIconAndLabelDp)); layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); @@ -441,7 +441,7 @@ public: DisabledAuthMessageView() { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(kDisabledAuthMessageVerticalBorderDp, kDisabledAuthMessageHorizontalBorderDp), kDisabledAuthMessageChildrenSpacingDp));
diff --git a/ash/login/ui/login_auth_user_view_unittest.cc b/ash/login/ui/login_auth_user_view_unittest.cc index 6cd0df5..34b970c 100644 --- a/ash/login/ui/login_auth_user_view_unittest.cc +++ b/ash/login/ui/login_auth_user_view_unittest.cc
@@ -49,8 +49,8 @@ // We proxy |view_| inside of |container_| so we can control layout. container_ = new views::View(); - container_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + container_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); container_->AddChildView(view_); SetWidget(CreateWidgetWithContent(container_)); }
diff --git a/ash/login/ui/login_base_bubble_view.cc b/ash/login/ui/login_base_bubble_view.cc index d88cf957..81261a8 100644 --- a/ash/login/ui/login_base_bubble_view.cc +++ b/ash/login/ui/login_base_bubble_view.cc
@@ -122,7 +122,7 @@ : anchor_view_(anchor_view), bubble_handler_(std::make_unique<LoginBubbleHandler>(this)) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(kBubbleTopMarginDp, kBubbleHorizontalMarginDp, kBubbleBottomMarginDp, kBubbleHorizontalMarginDp), kBubbleBetweenChildSpacingDp));
diff --git a/ash/login/ui/login_base_bubble_view_unittest.cc b/ash/login/ui/login_base_bubble_view_unittest.cc index 0b8680e57..4e85673 100644 --- a/ash/login/ui/login_base_bubble_view_unittest.cc +++ b/ash/login/ui/login_base_bubble_view_unittest.cc
@@ -29,8 +29,8 @@ anchor_ = new views::View(); anchor_->SetSize(gfx::Size(0, 25)); container_ = new views::View(); - container_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + container_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); container_->AddChildView(anchor_); SetWidget(CreateWidgetWithContent(container_)); @@ -39,8 +39,8 @@ auto* label = new views::Label(base::UTF8ToUTF16("A message"), views::style::CONTEXT_LABEL, views::style::STYLE_PRIMARY); - bubble_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + bubble_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); bubble_->AddChildView(label); container_->AddChildView(bubble_);
diff --git a/ash/login/ui/login_error_bubble.cc b/ash/login/ui/login_error_bubble.cc index 2ef1ef7..8dc73b5 100644 --- a/ash/login/ui/login_error_bubble.cc +++ b/ash/login/ui/login_error_bubble.cc
@@ -32,8 +32,8 @@ bool is_persistent) : LoginBaseBubbleView(anchor_view), is_persistent_(is_persistent) { auto* alert_view = new NonAccessibleView("AlertIconContainer"); - alert_view->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + alert_view->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); views::ImageView* alert_icon = new views::ImageView(); alert_icon->SetPreferredSize(gfx::Size(kAlertIconSizeDp, kAlertIconSizeDp)); alert_icon->SetImage(
diff --git a/ash/login/ui/login_error_bubble_unittest.cc b/ash/login/ui/login_error_bubble_unittest.cc index e212662..d35da4e 100644 --- a/ash/login/ui/login_error_bubble_unittest.cc +++ b/ash/login/ui/login_error_bubble_unittest.cc
@@ -15,8 +15,8 @@ TEST_F(LoginErrorBubbleTest, PersistentEventHandling) { auto* container = new views::View; - container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); SetWidget(CreateWidgetWithContent(container)); auto* anchor_view = new views::View;
diff --git a/ash/login/ui/login_expanded_public_account_view.cc b/ash/login/ui/login_expanded_public_account_view.cc index 172d657..8721e04 100644 --- a/ash/login/ui/login_expanded_public_account_view.cc +++ b/ash/login/ui/login_expanded_public_account_view.cc
@@ -145,8 +145,9 @@ }; auto* label_container = new NonAccessibleView(); - views::BoxLayout* label_layout = label_container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + views::BoxLayout* label_layout = + label_container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); label_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kStart); AddChildView(label_container); @@ -156,8 +157,9 @@ label_container->AddChildView(label_); auto* icon_container = new NonAccessibleView(); - views::BoxLayout* icon_layout = icon_container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + views::BoxLayout* icon_layout = + icon_container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); icon_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kEnd); AddChildView(icon_container); @@ -220,7 +222,7 @@ public: MonitoringWarningView() : NonAccessibleView(kMonitoringWarningClassName) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), kSpacingBetweenMonitoringWarningIconAndLabelDp)); image_ = new views::ImageView(); @@ -280,7 +282,8 @@ // Create labels view. labels_view_ = new NonAccessibleView(); labels_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), kSpacingBetweenLabelsDp)); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), + kSpacingBetweenLabelsDp)); AddChildView(labels_view_); monitoring_warning_view_ = new MonitoringWarningView(); @@ -321,8 +324,8 @@ // Create advanced view. advanced_view_ = new NonAccessibleView(); - advanced_view_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + advanced_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); AddChildView(advanced_view_); // Creates button to open the menu. @@ -669,8 +672,8 @@ on_dismissed_(on_dismissed), event_handler_( std::make_unique<LoginExpandedPublicAccountEventHandler>(this)) { - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); SetPreferredSize(gfx::Size(kExpandedViewWidthDp, kExpandedViewHeightDp)); user_view_ = new LoginUserView( @@ -681,8 +684,8 @@ auto* left_pane = new NonAccessibleView(); AddChildView(left_pane); - left_pane->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + left_pane->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); left_pane->SetPreferredSize( gfx::Size(kExpandedViewWidthDp / 2, kExpandedViewHeightDp));
diff --git a/ash/login/ui/login_expanded_public_account_view_unittest.cc b/ash/login/ui/login_expanded_public_account_view_unittest.cc index 9eacf64..1cde40d3 100644 --- a/ash/login/ui/login_expanded_public_account_view_unittest.cc +++ b/ash/login/ui/login_expanded_public_account_view_unittest.cc
@@ -57,8 +57,8 @@ other_view_ = new views::View(); container_ = new views::View(); - container_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + container_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); container_->AddChildView(public_account_); container_->AddChildView(other_view_); SetWidget(CreateWidgetWithContent(container_));
diff --git a/ash/login/ui/login_menu_view.cc b/ash/login/ui/login_menu_view.cc index 4f0f3b5..aa2b28b8 100644 --- a/ash/login/ui/login_menu_view.cc +++ b/ash/login/ui/login_menu_view.cc
@@ -37,8 +37,8 @@ const LoginMenuView::OnHighlight& on_highlight) : views::Button(this), item_(item), on_highlight_(on_highlight) { SetFocusBehavior(FocusBehavior::ALWAYS); - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); SetPreferredSize(gfx::Size(kMenuItemWidthDp, kMenuItemHeightDp)); auto* spacing = new NonAccessibleView(); @@ -140,13 +140,15 @@ scroller_->ClipHeightTo(kMenuItemHeightDp, kMenuItemHeightDp * 5); AddChildView(scroller_); - views::BoxLayout* box_layout = SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + views::BoxLayout* box_layout = + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); box_layout->SetFlexForView(scroller_, 1); auto contents = std::make_unique<NonAccessibleView>(); - views::BoxLayout* layout = contents->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + views::BoxLayout* layout = + contents->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); layout->SetDefaultFlex(1); layout->set_minimum_cross_axis_size(kMenuItemWidthDp); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kCenter);
diff --git a/ash/login/ui/login_password_view.cc b/ash/login/ui/login_password_view.cc index 3833e32..7776ad4d 100644 --- a/ash/login/ui/login_password_view.cc +++ b/ash/login/ui/login_password_view.cc
@@ -332,15 +332,15 @@ LoginPasswordView::LoginPasswordView() { Shell::Get()->ime_controller()->AddObserver(this); - auto* root_layout = SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + auto* root_layout = SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); root_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); password_row_ = new NonAccessibleView(); auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(kMarginAboveBelowPasswordIconsDp, 0)); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kCenter); layout->set_cross_axis_alignment(
diff --git a/ash/login/ui/login_pin_view.cc b/ash/login/ui/login_pin_view.cc index 896e30e..991cc8b 100644 --- a/ash/login/ui/login_pin_view.cc +++ b/ash/login/ui/login_pin_view.cc
@@ -94,8 +94,8 @@ SetFocusBehavior(FocusBehavior::ALWAYS); SetPreferredSize(size); - auto layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + auto layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); SetLayoutManager(std::move(layout)); @@ -411,14 +411,14 @@ // Builds and returns a new view which contains a row of the PIN keyboard. auto build_and_add_row = [this]() { auto* row = new NonAccessibleView(); - row->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + row->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); AddChildView(row); return row; }; - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); bool show_letters = keyboard_style == Style::kAlphanumeric; const gfx::Size button_size =
diff --git a/ash/login/ui/login_public_account_user_view.cc b/ash/login/ui/login_public_account_user_view.cc index 8cc8f57..fb7ec3c 100644 --- a/ash/login/ui/login_public_account_user_view.cc +++ b/ash/login/ui/login_public_account_user_view.cc
@@ -81,8 +81,8 @@ SetPaintToLayer(ui::LayerType::LAYER_NOT_DRAWN); // build layout for public account. - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); user_view_ = user_view.get(); auto wrapped_user_view = login_views_utils::WrapViewForPreferredSize(std::move(user_view));
diff --git a/ash/login/ui/login_public_account_user_view_unittest.cc b/ash/login/ui/login_public_account_user_view_unittest.cc index c1bceac..f27974e 100644 --- a/ash/login/ui/login_public_account_user_view_unittest.cc +++ b/ash/login/ui/login_public_account_user_view_unittest.cc
@@ -46,8 +46,8 @@ // We proxy |public_account_view_| inside of |container| so we can control // layout. auto* container = new views::View(); - container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); container->AddChildView(public_account_view_); container->AddChildView(focusable_view_); SetWidget(CreateWidgetWithContent(container));
diff --git a/ash/login/ui/login_user_menu_view.cc b/ash/login/ui/login_user_menu_view.cc index 1edd40f..302b91b 100644 --- a/ash/login/ui/login_user_menu_view.cc +++ b/ash/login/ui/login_user_menu_view.cc
@@ -150,7 +150,7 @@ kUserMenuMarginWidth); auto setup_horizontal_margin_container = [&](views::View* container) { container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(0, margins.left(), 0, margins.right()))); AddChildView(container); return container; @@ -164,7 +164,7 @@ }; SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(margins.top(), 0, margins.bottom(), 0))); // User information.
diff --git a/ash/login/ui/login_user_menu_view_unittest.cc b/ash/login/ui/login_user_menu_view_unittest.cc index 8521a55..ba6e47c 100644 --- a/ash/login/ui/login_user_menu_view_unittest.cc +++ b/ash/login/ui/login_user_menu_view_unittest.cc
@@ -25,8 +25,8 @@ TEST_F(LoginUserMenuViewTest, RemoveUserRequiresTwoActivations) { auto* anchor = new views::View; - anchor->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + anchor->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); SetWidget(CreateWidgetWithContent(anchor)); bool remove_warning_called = false; @@ -65,8 +65,8 @@ TEST_F(LoginUserMenuViewTest, LongUserNameAndEmailLaidOutCorrectly) { auto* anchor = new views::View; - anchor->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + anchor->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); SetWidget(CreateWidgetWithContent(anchor)); auto* bubble = new LoginUserMenuView( @@ -106,8 +106,8 @@ TEST_F(LoginUserMenuViewTest, LoginButtonRipple) { auto* container = new views::View(); - container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); LoginButton* bubble_opener = new LoginButton(nullptr /*listener*/); bubble_opener->SetFocusBehavior(views::View::FocusBehavior::ALWAYS); @@ -145,8 +145,8 @@ TEST_F(LoginUserMenuViewTest, ResetStateHidesConfirmData) { auto* container = new views::View; - container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); SetWidget(CreateWidgetWithContent(container)); auto* bubble = new LoginUserMenuView(
diff --git a/ash/login/ui/login_user_view.cc b/ash/login/ui/login_user_view.cc index 7f65871..2a8a5e50 100644 --- a/ash/login/ui/login_user_view.cc +++ b/ash/login/ui/login_user_view.cc
@@ -253,8 +253,8 @@ class LoginUserView::UserDomainInfoView : public NonAccessibleView { public: UserDomainInfoView() : NonAccessibleView(kLoginUserDomainClassName) { - auto layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal); + auto layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal); layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); SetLayoutManager(std::move(layout)); @@ -722,7 +722,7 @@ void LoginUserView::SetSmallishLayout() { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), kSmallManyDistanceFromUserIconToUserLabelDp)); AddChildView(user_image_);
diff --git a/ash/login/ui/login_user_view_unittest.cc b/ash/login/ui/login_user_view_unittest.cc index 424be3c..88b2cda 100644 --- a/ash/login/ui/login_user_view_unittest.cc +++ b/ash/login/ui/login_user_view_unittest.cc
@@ -55,12 +55,12 @@ LoginTestBase::SetUp(); container_ = new views::View(); - container_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + container_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); auto* root = new views::View(); - root->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + root->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); root->AddChildView(container_); SetWidget(CreateWidgetWithContent(root)); }
diff --git a/ash/login/ui/parent_access_view.cc b/ash/login/ui/parent_access_view.cc index f72c434..95c4cc9d 100644 --- a/ash/login/ui/parent_access_view.cc +++ b/ash/login/ui/parent_access_view.cc
@@ -180,7 +180,7 @@ DCHECK(on_input_change_); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), kAccessCodeBetweenInputFieldsGapDp)); SetGroup(kParentAccessInputGroup); SetPaintToLayer(); @@ -424,7 +424,7 @@ // Main view contains all other views aligned vertically and centered. auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(kParentAccessViewVerticalInsetDp, kParentAccessViewHorizontalInsetDp), 0); @@ -442,7 +442,7 @@ // Header view contains back button that is aligned to its start. auto header_layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), 0); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), 0); header_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kStart); auto* header = new NonAccessibleView(); @@ -548,7 +548,7 @@ footer->SetPreferredSize(gfx::Size(child_view_width, kArrowButtonSizeDp)); auto* bottom_layout = footer->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), 0)); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), 0)); AddChildView(footer); help_button_ = new views::LabelButton(
diff --git a/ash/login/ui/public_account_warning_dialog.cc b/ash/login/ui/public_account_warning_dialog.cc index 6d3b6c9..ed8c1f0c 100644 --- a/ash/login/ui/public_account_warning_dialog.cc +++ b/ash/login/ui/public_account_warning_dialog.cc
@@ -63,13 +63,14 @@ base::WeakPtr<LoginExpandedPublicAccountView> controller) : controller_(controller) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), kBetweenLabelPaddingDp)); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), + kBetweenLabelPaddingDp)); SetBorder(views::CreateEmptyBorder(gfx::Insets(kDialogContentMarginDp))); auto add_bulleted_label = [&](const base::string16& text) { auto* container = new views::View(); - container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); auto* label = new views::Label(text); label->SetMultiLine(true);
diff --git a/ash/login/ui/scrollable_users_list_view.cc b/ash/login/ui/scrollable_users_list_view.cc index a3c31f5..2c61bb4b 100644 --- a/ash/login/ui/scrollable_users_list_view.cc +++ b/ash/login/ui/scrollable_users_list_view.cc
@@ -295,7 +295,7 @@ user_view_host_ = new NonAccessibleView(); user_view_host_layout_ = user_view_host_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), layout_params.between_child_spacing)); user_view_host_layout_->set_minimum_cross_axis_size( LoginUserView::WidthForLayoutStyle(display_style)); @@ -326,8 +326,8 @@ // to be vertically centered when non-scrollable. auto ensure_min_height = std::make_unique<EnsureMinHeightView>(); ensure_min_height - ->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)) + ->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)) ->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kCenter); ensure_min_height->AddChildView(user_view_host_); SetContents(std::move(ensure_min_height));
diff --git a/ash/login/ui/views_utils.cc b/ash/login/ui/views_utils.cc index a215b4b..7032d08 100644 --- a/ash/login/ui/views_utils.cc +++ b/ash/login/ui/views_utils.cc
@@ -16,8 +16,8 @@ std::unique_ptr<views::View> WrapViewForPreferredSize( std::unique_ptr<views::View> view) { auto proxy = std::make_unique<NonAccessibleView>(); - auto layout_manager = - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + auto layout_manager = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); layout_manager->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart); proxy->SetLayoutManager(std::move(layout_manager));
diff --git a/ash/public/cpp/app_list/app_list_features.cc b/ash/public/cpp/app_list/app_list_features.cc index cc44518..254c641 100644 --- a/ash/public/cpp/app_list/app_list_features.cc +++ b/ash/public/cpp/app_list/app_list_features.cc
@@ -41,6 +41,8 @@ base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kEnableAppListLaunchRecording{ "EnableAppListLaunchRecording", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kEnableSearchBoxSelection{"EnableSearchBoxSelection", + base::FEATURE_ENABLED_BY_DEFAULT}; bool IsAnswerCardEnabled() { // Not using local static variable to allow tests to change this value. @@ -103,6 +105,10 @@ return base::FeatureList::IsEnabled(kEnableAppGridGhost); } +bool IsSearchBoxSelectionEnabled() { + return base::FeatureList::IsEnabled(kEnableSearchBoxSelection); +} + std::string AnswerServerUrl() { const std::string experiment_url = base::GetFieldTrialParamValueByFeature(kEnableAnswerCard, "ServerUrl");
diff --git a/ash/public/cpp/app_list/app_list_features.h b/ash/public/cpp/app_list/app_list_features.h index c762b3a..ad05896 100644 --- a/ash/public/cpp/app_list/app_list_features.h +++ b/ash/public/cpp/app_list/app_list_features.h
@@ -66,6 +66,8 @@ // Enables hashed recording of a app list launches. ASH_PUBLIC_EXPORT extern const base::Feature kEnableAppListLaunchRecording; +ASH_PUBLIC_EXPORT extern const base::Feature kEnableSearchBoxSelection; + bool ASH_PUBLIC_EXPORT IsAnswerCardEnabled(); bool ASH_PUBLIC_EXPORT IsBackgroundBlurEnabled(); bool ASH_PUBLIC_EXPORT IsPlayStoreAppSearchEnabled(); @@ -81,6 +83,7 @@ bool ASH_PUBLIC_EXPORT IsEmbeddedAssistantUIEnabled(); bool ASH_PUBLIC_EXPORT IsAppGridGhostEnabled(); bool ASH_PUBLIC_EXPORT IsAppListLaunchRecordingEnabled(); +bool ASH_PUBLIC_EXPORT IsSearchBoxSelectionEnabled(); std::string ASH_PUBLIC_EXPORT AnswerServerUrl(); std::string ASH_PUBLIC_EXPORT AnswerServerQuerySuffix();
diff --git a/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc b/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc index a8bc20e..d0d4a39 100644 --- a/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc +++ b/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc
@@ -153,8 +153,8 @@ views::Widget* frame) : frame_(frame), model_(std::make_unique<DefaultCaptionButtonModel>(frame)) { - auto layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal); + auto layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kEnd);
diff --git a/ash/session/multiprofiles_intro_dialog.cc b/ash/session/multiprofiles_intro_dialog.cc index 796e48c..559b698 100644 --- a/ash/session/multiprofiles_intro_dialog.cc +++ b/ash/session/multiprofiles_intro_dialog.cc
@@ -80,7 +80,7 @@ provider->GetDialogInsetsForContentType(views::TEXT, views::CONTROL))); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); // Explanation string
diff --git a/ash/session/teleport_warning_dialog.cc b/ash/session/teleport_warning_dialog.cc index 5d5f88a..e59aad0 100644 --- a/ash/session/teleport_warning_dialog.cc +++ b/ash/session/teleport_warning_dialog.cc
@@ -80,7 +80,7 @@ provider->GetDialogInsetsForContentType(views::TEXT, views::CONTROL))); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); // Explanation string
diff --git a/ash/shelf/login_shelf_view.cc b/ash/shelf/login_shelf_view.cc index 153a9ac..b5549d9 100644 --- a/ash/shelf/login_shelf_view.cc +++ b/ash/shelf/login_shelf_view.cc
@@ -384,8 +384,8 @@ // switch to the lock screen or status area. This view should otherwise not // be focusable. SetFocusBehavior(FocusBehavior::ALWAYS); - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); auto add_button = [this](ButtonId id, int text_resource_id, const gfx::VectorIcon& icon) {
diff --git a/ash/shelf/shelf_tooltip_preview_bubble.cc b/ash/shelf/shelf_tooltip_preview_bubble.cc index ec93b10..97c326a 100644 --- a/ash/shelf/shelf_tooltip_preview_bubble.cc +++ b/ash/shelf/shelf_tooltip_preview_bubble.cc
@@ -52,7 +52,7 @@ set_notify_enter_exit_on_child(true); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(kTooltipPaddingTop, kTooltipPaddingLeftRight, kTooltipPaddingBottom, kTooltipPaddingLeftRight), kPreviewPadding));
diff --git a/ash/sticky_keys/sticky_keys_overlay.cc b/ash/sticky_keys/sticky_keys_overlay.cc index 3e509db..afc95aa 100644 --- a/ash/sticky_keys/sticky_keys_overlay.cc +++ b/ash/sticky_keys/sticky_keys_overlay.cc
@@ -142,7 +142,7 @@ int child_spacing = font_size - 2 * font_padding; SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(vertical_spacing, horizontal_spacing), child_spacing)); AddKeyLabel(ui::EF_CONTROL_DOWN, l10n_util::GetStringUTF8(IDS_ASH_CONTROL_KEY));
diff --git a/ash/strings/ash_strings_el.xtb b/ash/strings/ash_strings_el.xtb index 7564d94..07417fb 100644 --- a/ash/strings/ash_strings_el.xtb +++ b/ash/strings/ash_strings_el.xtb
@@ -377,7 +377,7 @@ <translation id="6713285437468012787">Η συσκευή Bluetooth "<ph name="DEVICE_NAME" />" έχει συζευχθεί και είναι πλέον διαθέσιμη σε όλους τους χρήστες. Μπορείτε να καταργήσετε αυτήν τη σύζευξη μέσω των Ρυθμίσεων.</translation> <translation id="6715542151869432661">Δεν βρέθηκαν κινητές συσκευές.</translation> <translation id="6723839937902243910">Ενεργοποίηση</translation> -<translation id="6727969043791803658">Συνδεδεμένη, μπαταρία <ph name="BATTERY_PERCENTAGE" /></translation> +<translation id="6727969043791803658">Συνδεδεμένη, μπαταρία <ph name="BATTERY_PERCENTAGE" /> %</translation> <translation id="6751826523481687655">Η παρακολούθηση απόδοσης έχει ενεργοποιηθεί</translation> <translation id="6790428901817661496">Αναπαραγωγή</translation> <translation id="6803622936009808957">Δεν ήταν δυνατός ο αντικατοπτρισμός των οθονών καθώς δεν βρέθηκαν υποστηριζόμενες αναλύσεις. Έχει ενεργοποιηθεί εναλλακτικά η εκτεταμένη επιφάνεια εργασίας.</translation>
diff --git a/ash/system/accessibility/autoclick_menu_view.cc b/ash/system/accessibility/autoclick_menu_view.cc index 7b9e9c1..29e11ea 100644 --- a/ash/system/accessibility/autoclick_menu_view.cc +++ b/ash/system/accessibility/autoclick_menu_view.cc
@@ -201,14 +201,14 @@ scroll_button_->SetId(ButtonId::kScroll); std::unique_ptr<views::BoxLayout> layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), 0); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), 0); layout->set_cross_axis_alignment(views::BoxLayout::CrossAxisAlignment::kEnd); SetLayoutManager(std::move(layout)); // The action control buttons all have the same spacing. views::View* action_button_container = new views::View(); action_button_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, kUnifiedMenuItemPadding, + views::BoxLayout::Orientation::kHorizontal, kUnifiedMenuItemPadding, kUnifiedTopShortcutSpacing)); action_button_container->AddChildView(left_click_button_); action_button_container->AddChildView(right_click_button_); @@ -231,7 +231,7 @@ views::View* position_button_container = new views::View(); position_button_container->SetLayoutManager( std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(0, kPanelPositionButtonPadding, kPanelPositionButtonPadding, kPanelPositionButtonPadding), kPanelPositionButtonPadding));
diff --git a/ash/system/audio/unified_volume_view.cc b/ash/system/audio/unified_volume_view.cc index d4f97e7..8baaffc6 100644 --- a/ash/system/audio/unified_volume_view.cc +++ b/ash/system/audio/unified_volume_view.cc
@@ -59,7 +59,7 @@ explicit MoreButton(views::ButtonListener* listener) : views::Button(listener) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets((kTrayItemSize - GetDefaultSizeOfVectorIcon(vector_icons::kHeadsetIcon)) / 2),
diff --git a/ash/system/bluetooth/bluetooth_detailed_view.cc b/ash/system/bluetooth/bluetooth_detailed_view.cc index 64a6733d..78295b9 100644 --- a/ash/system/bluetooth/bluetooth_detailed_view.cc +++ b/ash/system/bluetooth/bluetooth_detailed_view.cc
@@ -73,8 +73,8 @@ views::View* CreateDisabledPanel() { views::View* container = new views::View; - auto box_layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + auto box_layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); box_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); container->SetLayoutManager(std::move(box_layout));
diff --git a/ash/system/ime_menu/ime_menu_tray.cc b/ash/system/ime_menu/ime_menu_tray.cc index ea384b0b..ebc252f 100644 --- a/ash/system/ime_menu/ime_menu_tray.cc +++ b/ash/system/ime_menu/ime_menu_tray.cc
@@ -131,8 +131,8 @@ views::CreateSolidSidedBorder(0, 0, kMenuSeparatorWidth, 0, kMenuSeparatorColor), gfx::Insets(kMenuSeparatorVerticalPadding - kMenuSeparatorWidth, 0))); - auto box_layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal); + auto box_layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal); box_layout->set_minimum_cross_axis_size(kTrayPopupItemMinHeight); views::BoxLayout* layout_ptr = SetLayoutManager(std::move(box_layout)); auto* title_label = @@ -226,8 +226,8 @@ private: void Init(bool show_emoji, bool show_handwriting, bool show_voice) { - auto box_layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal); + auto box_layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal); box_layout->set_minimum_cross_axis_size(kTrayPopupItemMinHeight); SetLayoutManager(std::move(box_layout)); SetBorder(views::CreatePaddedBorder(
diff --git a/ash/system/message_center/notification_swipe_control_view.cc b/ash/system/message_center/notification_swipe_control_view.cc index 4a89160..3731232 100644 --- a/ash/system/message_center/notification_swipe_control_view.cc +++ b/ash/system/message_center/notification_swipe_control_view.cc
@@ -26,7 +26,7 @@ message_center::MessageView* message_view) : message_view_(message_view) { auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(message_center_style::kSwipeControlButtonVerticalMargin, message_center_style::kSwipeControlButtonHorizontalMargin), message_center_style::kSwipeControlButtonHorizontalMargin));
diff --git a/ash/system/message_center/notifier_settings_view.cc b/ash/system/message_center/notifier_settings_view.cc index 0cf8b1a..35d2607 100644 --- a/ash/system/message_center/notifier_settings_view.cc +++ b/ash/system/message_center/notifier_settings_view.cc
@@ -270,7 +270,7 @@ EmptyNotifierView() { SkColor color = kUnifiedMenuTextColor; auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), 0); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), 0); layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); layout->set_cross_axis_alignment( @@ -440,7 +440,7 @@ auto header_view = std::make_unique<views::View>(); header_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, kHeaderViewPadding, 0)); + views::BoxLayout::Orientation::kVertical, kHeaderViewPadding, 0)); header_view->SetBorder( views::CreateSolidSidedBorder(1, 0, 0, 0, kTopBorderColor)); @@ -448,7 +448,7 @@ auto* quiet_mode_layout = quiet_mode_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, kQuietModeViewPadding, + views::BoxLayout::Orientation::kHorizontal, kQuietModeViewPadding, kQuietModeViewSpacing)); auto quiet_mode_icon = std::make_unique<views::ImageView>(); @@ -552,7 +552,8 @@ auto contents_view = std::make_unique<ScrollContentsView>(); contents_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(0, kHorizontalMargin))); + views::BoxLayout::Orientation::kVertical, + gfx::Insets(0, kHorizontalMargin))); for (const auto& notifier : notifiers) { NotifierButton* button = new NotifierButton(notifier, this);
diff --git a/ash/system/message_center/unified_message_center_view.cc b/ash/system/message_center/unified_message_center_view.cc index b2d7706..95c2842b 100644 --- a/ash/system/message_center/unified_message_center_view.cc +++ b/ash/system/message_center/unified_message_center_view.cc
@@ -51,7 +51,7 @@ ScrollerContentsView(UnifiedMessageListView* message_list_view, views::ButtonListener* listener) { auto* contents_layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(0, 0, kUnifiedNotificationCenterSpacing, 0))); contents_layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch); @@ -153,7 +153,7 @@ SetVisible(false); auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(0, kStackingNotificationClearAllButtonPadding.left(), 0, 0), 0)); layout->set_cross_axis_alignment(
diff --git a/ash/system/palette/palette_tray.cc b/ash/system/palette/palette_tray.cc index 4211274ef..3aad87e 100644 --- a/ash/system/palette/palette_tray.cc +++ b/ash/system/palette/palette_tray.cc
@@ -94,8 +94,8 @@ explicit TitleView(PaletteTray* palette_tray) : palette_tray_(palette_tray) { // TODO(tdanderson|jdufault): Use TriView to handle the layout of the title. // See crbug.com/614453. - auto box_layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal); + auto box_layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal); box_layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter); views::BoxLayout* layout_ptr = SetLayoutManager(std::move(box_layout));
diff --git a/ash/system/power/power_button_menu_screen_view.cc b/ash/system/power/power_button_menu_screen_view.cc index 828c0af..6b3f702 100644 --- a/ash/system/power/power_button_menu_screen_view.cc +++ b/ash/system/power/power_button_menu_screen_view.cc
@@ -98,7 +98,7 @@ // views::View: const char* GetClassName() const override { - return "PowerButtonMenuScreenView"; + return "PowerButtonMenuBackgroundView"; } private:
diff --git a/ash/system/power/power_button_menu_view.cc b/ash/system/power/power_button_menu_view.cc index d774f330..e9d2970 100644 --- a/ash/system/power/power_button_menu_view.cc +++ b/ash/system/power/power_button_menu_view.cc
@@ -5,7 +5,6 @@ #include "ash/system/power/power_button_menu_view.h" #include "ash/display/screen_orientation_controller.h" -#include "ash/kiosk_next/kiosk_next_shell_controller_impl.h" #include "ash/public/cpp/new_window_delegate.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller_impl.h" @@ -164,8 +163,7 @@ IDS_ASH_POWER_BUTTON_MENU_LOCK_SCREEN_BUTTON)); AddChildView(lock_screen_item_); - if (base::FeatureList::IsEnabled(kEnableFeedbackItem) || - Shell::Get()->kiosk_next_shell_controller()->IsEnabled()) { + if (base::FeatureList::IsEnabled(kEnableFeedbackItem)) { feedback_item_ = new PowerButtonMenuItemView( this, kSystemPowerButtonMenuFeedbackIcon, l10n_util::GetStringUTF16(
diff --git a/ash/system/power/power_status_view.cc b/ash/system/power/power_status_view.cc index 98dc68b..0907825c 100644 --- a/ash/system/power/power_status_view.cc +++ b/ash/system/power/power_status_view.cc
@@ -32,7 +32,7 @@ separator_label_->SetText(base::ASCIIToUTF16(" - ")); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(0, 12), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(0, 12), kTrayPopupPaddingBetweenItems)); AddChildView(percentage_label_);
diff --git a/ash/system/toast/toast_overlay.cc b/ash/system/toast/toast_overlay.cc index 1dd42fb0..ee85141 100644 --- a/ash/system/toast/toast_overlay.cc +++ b/ash/system/toast/toast_overlay.cc
@@ -150,8 +150,8 @@ const base::string16& text, const base::Optional<base::string16>& dismiss_text) : overlay_(overlay) { - auto* layout = SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); if (dismiss_text.has_value()) { button_ = new ToastOverlayButton(
diff --git a/ash/system/tray/detailed_view_delegate.cc b/ash/system/tray/detailed_view_delegate.cc index f2bc883..fcb8ab6bb 100644 --- a/ash/system/tray/detailed_view_delegate.cc +++ b/ash/system/tray/detailed_view_delegate.cc
@@ -34,9 +34,9 @@ case TriView::Container::START: FALLTHROUGH; case TriView::Container::END: - layout = std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal, - gfx::Insets(), - kUnifiedTopShortcutSpacing); + layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + kUnifiedTopShortcutSpacing); layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); layout->set_cross_axis_alignment( @@ -45,7 +45,8 @@ case TriView::Container::CENTER: tri_view->SetFlexForContainer(TriView::Container::CENTER, 1.f); - layout = std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); layout->set_cross_axis_alignment(
diff --git a/ash/system/tray/tray_bubble_view.cc b/ash/system/tray/tray_bubble_view.cc index 93f0925..415edc8 100644 --- a/ash/system/tray/tray_bubble_view.cc +++ b/ash/system/tray/tray_bubble_view.cc
@@ -89,7 +89,8 @@ class BottomAlignedBoxLayout : public views::BoxLayout { public: explicit BottomAlignedBoxLayout(TrayBubbleView* bubble_view) - : BoxLayout(BoxLayout::kVertical), bubble_view_(bubble_view) {} + : BoxLayout(BoxLayout::Orientation::kVertical), + bubble_view_(bubble_view) {} ~BottomAlignedBoxLayout() override {}
diff --git a/ash/system/tray/tray_container.cc b/ash/system/tray/tray_container.cc index 137231b9..2400e512 100644 --- a/ash/system/tray/tray_container.cc +++ b/ash/system/tray/tray_container.cc
@@ -70,8 +70,8 @@ // Adjust the size of status tray dark background by adding additional // empty border. views::BoxLayout::Orientation orientation = - is_horizontal ? views::BoxLayout::kHorizontal - : views::BoxLayout::kVertical; + is_horizontal ? views::BoxLayout::Orientation::kHorizontal + : views::BoxLayout::Orientation::kVertical; gfx::Insets insets(is_horizontal ? gfx::Insets(0, kHitRegionPadding) : gfx::Insets(kHitRegionPadding, 0));
diff --git a/ash/system/tray/tray_detailed_view.cc b/ash/system/tray/tray_detailed_view.cc index acce889..c7844972 100644 --- a/ash/system/tray/tray_detailed_view.cc +++ b/ash/system/tray/tray_detailed_view.cc
@@ -58,8 +58,8 @@ public: explicit ScrollContentsView(DetailedViewDelegate* delegate) : delegate_(delegate) { - box_layout_ = SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + box_layout_ = SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); } ~ScrollContentsView() override = default; @@ -272,8 +272,8 @@ progress_bar_(nullptr), tri_view_(nullptr), back_button_(nullptr) { - box_layout_ = SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + box_layout_ = SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); SetBackground(views::CreateSolidBackground( delegate_->GetBackgroundColor(GetNativeTheme()))); }
diff --git a/ash/system/tray/tray_popup_utils.cc b/ash/system/tray/tray_popup_utils.cc index 472ec797..fc9fa38 100644 --- a/ash/system/tray/tray_popup_utils.cc +++ b/ash/system/tray/tray_popup_utils.cc
@@ -45,7 +45,7 @@ std::unique_ptr<views::LayoutManager> CreateDefaultCenterLayoutManager() { // TODO(bruthig): Use constants instead of magic numbers. auto box_layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(8, kTrayPopupLabelHorizontalPadding)); box_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); @@ -57,8 +57,8 @@ // Creates a layout manager that positions Views horizontally. The Views will be // centered along the horizontal and vertical axis. std::unique_ptr<views::LayoutManager> CreateDefaultEndsLayoutManager() { - auto box_layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal); + auto box_layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal); box_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); box_layout->set_cross_axis_alignment(
diff --git a/ash/system/tray/tri_view.cc b/ash/system/tray/tri_view.cc index 6c3d858..3a42f0a 100644 --- a/ash/system/tray/tri_view.cc +++ b/ash/system/tray/tri_view.cc
@@ -19,13 +19,13 @@ views::BoxLayout::Orientation GetOrientation(TriView::Orientation orientation) { switch (orientation) { case TriView::Orientation::HORIZONTAL: - return views::BoxLayout::kHorizontal; + return views::BoxLayout::Orientation::kHorizontal; case TriView::Orientation::VERTICAL: - return views::BoxLayout::kVertical; + return views::BoxLayout::Orientation::kVertical; } // Required for some compilers. NOTREACHED(); - return views::BoxLayout::kHorizontal; + return views::BoxLayout::Orientation::kHorizontal; } // A View that will perform a layout if a child view's preferred size changes.
diff --git a/ash/system/tray/tri_view_unittest.cc b/ash/system/tray/tri_view_unittest.cc index 369bc507..f0788a904 100644 --- a/ash/system/tray/tri_view_unittest.cc +++ b/ash/system/tray/tri_view_unittest.cc
@@ -20,8 +20,8 @@ // Returns a layout manager that will size views according to their preferred // size. std::unique_ptr<views::LayoutManager> CreatePreferredSizeLayoutManager() { - auto layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal); + auto layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart); return std::move(layout);
diff --git a/ash/system/unified/feature_pod_button.cc b/ash/system/unified/feature_pod_button.cc index 6a9090d0..bb8839fc 100644 --- a/ash/system/unified/feature_pod_button.cc +++ b/ash/system/unified/feature_pod_button.cc
@@ -249,7 +249,8 @@ icon_button_(new FeaturePodIconButton(this)), label_button_(new FeaturePodLabelButton(this)) { auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), kUnifiedFeaturePodSpacing)); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), + kUnifiedFeaturePodSpacing)); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter);
diff --git a/ash/system/unified/notification_hidden_view.cc b/ash/system/unified/notification_hidden_view.cc index 30ccbcb..1d2065e7 100644 --- a/ash/system/unified/notification_hidden_view.cc +++ b/ash/system/unified/notification_hidden_view.cc
@@ -49,8 +49,8 @@ views::Painter::CreateSolidRoundRectPainter(kUnifiedMenuButtonColor, kUnifiedTrayCornerRadius))); - auto* layout = container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + auto* layout = container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); container->AddChildView(label); layout->SetFlexForView(label, 1);
diff --git a/ash/system/unified/page_indicator_view.cc b/ash/system/unified/page_indicator_view.cc index a89f821..7a68ea70 100644 --- a/ash/system/unified/page_indicator_view.cc +++ b/ash/system/unified/page_indicator_view.cc
@@ -152,7 +152,7 @@ layer()->SetFillsBoundsOpaquely(false); buttons_container_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets())); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets())); AddChildView(buttons_container_);
diff --git a/ash/system/unified/top_shortcuts_view.cc b/ash/system/unified/top_shortcuts_view.cc index 155c5ec..571cbd3 100644 --- a/ash/system/unified/top_shortcuts_view.cc +++ b/ash/system/unified/top_shortcuts_view.cc
@@ -160,7 +160,7 @@ DCHECK(controller_); auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, kUnifiedTopShortcutPadding, + views::BoxLayout::Orientation::kHorizontal, kUnifiedTopShortcutPadding, kUnifiedTopShortcutSpacing)); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart);
diff --git a/ash/system/unified/unified_slider_view.cc b/ash/system/unified/unified_slider_view.cc index 97e20ef..8c9f2fe37 100644 --- a/ash/system/unified/unified_slider_view.cc +++ b/ash/system/unified/unified_slider_view.cc
@@ -121,7 +121,7 @@ : button_(new UnifiedSliderButton(listener, icon, accessible_name_id)), slider_(CreateSlider(listener, readonly)) { auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, kUnifiedSliderRowPadding, + views::BoxLayout::Orientation::kHorizontal, kUnifiedSliderRowPadding, kUnifiedSliderViewSpacing)); AddChildView(button_);
diff --git a/ash/system/unified/unified_system_info_view.cc b/ash/system/unified/unified_system_info_view.cc index f51c974..2035597 100644 --- a/ash/system/unified/unified_system_info_view.cc +++ b/ash/system/unified/unified_system_info_view.cc
@@ -170,8 +170,8 @@ status_(new views::Label) { PowerStatus::Get()->AddObserver(this); - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); separator_->SetText( l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BATTERY_STATUS_SEPARATOR)); @@ -248,7 +248,8 @@ const gfx::VectorIcon& icon) : Button(listener) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), kUnifiedSystemInfoSpacing)); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + kUnifiedSystemInfoSpacing)); auto* label = new views::Label; label->SetAutoColorReadabilityEnabled(false); @@ -378,7 +379,7 @@ : enterprise_managed_(new EnterpriseManagedView(controller)), supervised_(new SupervisedUserView()) { auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, kUnifiedSystemInfoViewPadding, + views::BoxLayout::Orientation::kHorizontal, kUnifiedSystemInfoViewPadding, kUnifiedSystemInfoSpacing)); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter);
diff --git a/ash/system/unified/unified_system_tray_view.cc b/ash/system/unified/unified_system_tray_view.cc index 7049300f..7c7d3103 100644 --- a/ash/system/unified/unified_system_tray_view.cc +++ b/ash/system/unified/unified_system_tray_view.cc
@@ -86,8 +86,8 @@ class SystemTrayContainer : public views::View { public: SystemTrayContainer() { - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); SetBackground(UnifiedSystemTrayView::CreateBackground()); SetBorder(std::make_unique<TopCornerBorder>()); } @@ -244,8 +244,8 @@ std::make_unique<InteractedByTapRecorder>(this)) { DCHECK(controller_); - auto* layout = SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); SetBackground(CreateBackground()); SetPaintToLayer();
diff --git a/ash/system/unified/user_chooser_view.cc b/ash/system/unified/user_chooser_view.cc index 1354df8..df9986d6 100644 --- a/ash/system/unified/user_chooser_view.cc +++ b/ash/system/unified/user_chooser_view.cc
@@ -78,8 +78,8 @@ : Button(this), controller_(controller) { SetID(VIEW_ID_ADD_USER_BUTTON); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(kUnifiedTopShortcutSpacing), - kUnifiedTopShortcutSpacing)); + views::BoxLayout::Orientation::kHorizontal, + gfx::Insets(kUnifiedTopShortcutSpacing), kUnifiedTopShortcutSpacing)); auto* icon = new views::ImageView; icon->SetImage( @@ -196,8 +196,8 @@ VIEW_ID_USER_ITEM_BUTTON_START + user_index); SetID(VIEW_ID_USER_ITEM_BUTTON_START + user_index); auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(0, kUnifiedTopShortcutSpacing), - kUnifiedTopShortcutSpacing)); + views::BoxLayout::Orientation::kHorizontal, + gfx::Insets(0, kUnifiedTopShortcutSpacing), kUnifiedTopShortcutSpacing)); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter); layout->set_minimum_cross_axis_size(kUnifiedUserChooserRowHeight); @@ -205,8 +205,9 @@ views::View* vertical_labels = new views::View; vertical_labels->set_can_process_events_within_subtree(false); - auto* vertical_layout = vertical_labels->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + auto* vertical_layout = + vertical_labels->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); vertical_layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart); @@ -286,8 +287,8 @@ UserChooserView::UserChooserView( UserChooserDetailedViewController* controller) { - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); const int num_users = Shell::Get()->session_controller()->NumberOfLoggedInUsers(); for (int i = 0; i < num_users; ++i) {
diff --git a/ash/touch/touch_hud_debug.cc b/ash/touch/touch_hud_debug.cc index b583f2c8..4c3b239 100644 --- a/ash/touch/touch_hud_debug.cc +++ b/ash/touch/touch_hud_debug.cc
@@ -316,8 +316,8 @@ const gfx::Size& display_size = display.size(); canvas_->SetSize(display_size); - label_container_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + label_container_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); constexpr SkColor kShadowColor = SK_ColorWHITE; const SkColor label_color =
diff --git a/ash/wm/overview/caption_container_view.cc b/ash/wm/overview/caption_container_view.cc index c978011..e62d391 100644 --- a/ash/wm/overview/caption_container_view.cc +++ b/ash/wm/overview/caption_container_view.cc
@@ -112,7 +112,7 @@ header_view_ = new views::View(); views::BoxLayout* layout = header_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), kHorizontalLabelPaddingDp)); AddChildWithLayer(this, header_view_);
diff --git a/ash/wm/overview/rounded_label_widget.cc b/ash/wm/overview/rounded_label_widget.cc index 092515f..8a10601 100644 --- a/ash/wm/overview/rounded_label_widget.cc +++ b/ash/wm/overview/rounded_label_widget.cc
@@ -32,7 +32,7 @@ : horizontal_padding_(horizontal_padding), preferred_height_(preferred_height) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(vertical_padding, horizontal_padding))); SetPaintToLayer(ui::LAYER_SOLID_COLOR); layer()->SetColor(background_color);
diff --git a/ash/wm/splitview/split_view_drag_indicators.cc b/ash/wm/splitview/split_view_drag_indicators.cc index 392a864..c3a7c18f 100644 --- a/ash/wm/splitview/split_view_drag_indicators.cc +++ b/ash/wm/splitview/split_view_drag_indicators.cc
@@ -141,7 +141,7 @@ label_parent_->SetPaintToLayer(); label_parent_->layer()->SetFillsBoundsOpaquely(false); label_parent_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(kSplitviewLabelVerticalInsetDp, kSplitviewLabelHorizontalInsetDp))); label_parent_->AddChildView(label_);
diff --git a/ash/wm/window_cycle_list.cc b/ash/wm/window_cycle_list.cc index 8c75c47..de991946d 100644 --- a/ash/wm/window_cycle_list.cc +++ b/ash/wm/window_cycle_list.cc
@@ -43,9 +43,15 @@ bool g_disable_initial_delay = false; -// Used for the highlight view and the shield (black background). +// The color of the window cycle highlight. +constexpr SkColor kHighlightColor = SkColorSetARGB(36, 255, 255, 255); + +// Used for the shield (black background). constexpr float kBackgroundCornerRadius = 4.f; +// Corner radius applied to the alt-tab selector border. +constexpr gfx::RoundedCornersF kWindowSelectionCornerRadii{2}; + // Horizontal spacing between the icon and label views. constexpr int kIconLabelSpacingDp = 12; @@ -68,26 +74,6 @@ constexpr int kMinPreviewWidthDp = kFixedPreviewHeightDp / 2; constexpr int kMaxPreviewWidthDp = kFixedPreviewHeightDp * 2; -// This background paints a |Painter| but fills the view's layer's size rather -// than the view's size. -class LayerFillBackgroundPainter : public views::Background { - public: - explicit LayerFillBackgroundPainter(std::unique_ptr<views::Painter> painter) - : painter_(std::move(painter)) {} - - ~LayerFillBackgroundPainter() override = default; - - void Paint(gfx::Canvas* canvas, views::View* view) const override { - views::Painter::PaintPainterAt(canvas, painter_.get(), - gfx::Rect(view->layer()->size())); - } - - private: - std::unique_ptr<views::Painter> painter_; - - DISALLOW_COPY_AND_ASSIGN(LayerFillBackgroundPainter); -}; - } // namespace // This view represents a single aura::Window by displaying a title and a @@ -105,7 +91,8 @@ header_view_ = new views::View(); views::BoxLayout* layout = header_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), kIconLabelSpacingDp)); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + kIconLabelSpacingDp)); AddChildView(header_view_); gfx::ImageSkia* icon = window->GetProperty(aura::client::kAppIconKey); @@ -269,8 +256,8 @@ const int kInsideBorderPaddingDip = 64; const int kBetweenChildPaddingDip = 10; auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(kInsideBorderPaddingDip), - kBetweenChildPaddingDip); + views::BoxLayout::Orientation::kHorizontal, + gfx::Insets(kInsideBorderPaddingDip), kBetweenChildPaddingDip); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart); mirror_container_->SetLayoutManager(std::move(layout)); @@ -285,15 +272,10 @@ mirror_container_->AddChildView(view); } - // The background needs to be painted to fill the layer, not the View, - // because the layer animates bounds changes but the View's bounds change - // immediately. - highlight_view_->SetBackground(std::make_unique<LayerFillBackgroundPainter>( - views::Painter::CreateRoundRectWith1PxBorderPainter( - SkColorSetA(SK_ColorWHITE, 0x4D), SkColorSetA(SK_ColorWHITE, 0x33), - kBackgroundCornerRadius))); - highlight_view_->SetPaintToLayer(); - + highlight_view_->SetPaintToLayer(ui::LAYER_SOLID_COLOR); + highlight_view_->layer()->SetRoundedCornerRadius( + kWindowSelectionCornerRadii); + highlight_view_->layer()->SetColor(kHighlightColor); highlight_view_->layer()->SetFillsBoundsOpaquely(false); AddChildView(highlight_view_);
diff --git a/build/android/docs/class_verification_failures.md b/build/android/docs/class_verification_failures.md new file mode 100644 index 0000000..bf9a8a29 --- /dev/null +++ b/build/android/docs/class_verification_failures.md
@@ -0,0 +1,246 @@ +# Class Verification Failures + +[TOC] + +## What's this all about? + +This document aims to explain class verification on Android, how this can affect +app performance, how to identify problems, and chromium-specific solutions. For +simplicity, this document focuses on how class verification is implemented by +ART, the virtual machine which replaced Dalvik starting in Android Lollipop. + +## What is class verification? + +The Java language requires any virtual machine to _verify_ the class files it +loads and executes. Generally, verification is extra work the virtual machine is +responsible for doing, on top of the work of loading the class and performing +[class initialization][1]. + +A class may fail verification for a wide variety of reasons, but in practice +it's usually because the class's code refers to unknown classes or methods. An +example case might look like: + +```java +public class WindowHelper { + // ... + public boolean isWideColorGamut() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { + return mWindow.isWideColorGamut(); + } + return false; + } +} +``` + +### Why does that fail? + +In this example, `WindowHelper` is a helper class intended to help callers +figure out wide color gamut support, even on pre-OMR1 devices. However, this +class will fail class verification on pre-OMR1 devices, because it refers to +[`Window#isWideColorGamut()`][2] (new-in-OMR1), which appears to be an undefined +method. + +### Huh? But we have an SDK check! + +SDK checks are completely irrelevant for class verification. Although readers +can see we'll never call the new-in-OMR1 API unless we're on >= OMR1 devices, +the Oreo version of ART doesn't know `isWideColorGamut()` was added in next +year's release. From ART's perspective, we may as well be calling +`methodWhichDoesNotExist()`, which would clearly be unsafe. + +All the SDK check does is protect us from crashing at runtime if we call this +method on Oreo or below. + +### Class verification on ART + +While the above is a mostly general description of class verification, it's +important to understand how the Android runtime handles this. + +Since class verification is extra work, ART has an optimization called **AOT +("ahead-of-time") verification**¹. Immediately after installing an app, ART will +scan the dex files and verify as many classes as it can. If a class fails +verification, this is usually a "soft failure" (hard failures are uncommon), and +ART marks the class with the status `RetryVerificationAtRuntime`. + +`RetryVerificationAtRuntime`, as the name suggests, means ART must try again to +verify the class at runtime. ART does so the first time you access the class +(right before class initialization/`<clinit>()` method). However, depending on +the class, this verification step can be very expensive (we've observed cases +which take [several milliseconds][3]). Since apps tend to initialize most of +their classes during startup, verification significantly increases startup time. + +Another minor cost to failing class verification is that ART cannot optimize +classes which fail verification, so **all** methods in the class will perform +slower at runtime, even after the verification step. + +*** aside +¹ AOT _verification_ should not be confused with AOT _compilation_ (another ART +feature). Unlike compilation, AOT verification happens during install time for +every application, whereas recent versions of ART aim to apply AOT compilation +selectively to optimize space. +*** + +## Chromium's solution + +In Chromium, we try to avoid doing class verification at runtime by +manually out-of-lining all Android API usage like so: + +```java +public class ApiHelperForOMR1 { + public static boolean isWideColorGamut(Window window) { + return window.isWideColorGamut(); + } +} + +public class WindowHelper { + // ... + public boolean isWideColorGamut() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { + return ApiHelperForOMR1.isWideColorGamut(mWindow); + } + return false; + } +} +``` + +This pushes the class verification failure out of `WindowHelper` and into the +new `ApiHelperForOMR1` class. There's no magic here: `ApiHelperForOMR1` will +fail class verification on Oreo and below, for the same reason `WindowHelper` +did previously. + +The key is that, while `WindowHelper` is used on all API levels, it only calls +into `ApiHelperForOMR1` on OMR1 and above. Because we never use +`ApiHelperForOMR1` on Oreo and below, we never load and initialize the class, +and thanks to ART's lazy runtime class verification, we never actually retry +verification. **Note:** `list_class_verification_failures.py` will still list +`ApiHelperFor*` classes in its output, although these don't cause performance +issues. + +### Creating ApiHelperFor\* classes + +There are several examples throughout the code base, but such classes should +look as follows: + +```java +/** + * Utility class to use new APIs that were added in O_MR1 (API level 27). + * These need to exist in a separate class so that Android framework can successfully verify + * classes without encountering the new APIs. + */ +@DoNotInline +@TargetApi(Build.VERSION_CODES.O_MR1) +public class ApiHelperForOMR1 { + private ApiHelperForOMR1() {} + + // ... +} +``` + +* `@DoNotInline`: this is a chromium-defined annotation to tell proguard (and + similar tools) not to inline this class or its methods (since that would + defeat the point of out-of-lining!) +* `@TargetApi(Build.VERSION_CODES.O_MR1)`: this tells Android Lint it's OK to + use OMR1 APIs since this class is only used on OMR1 and above. Substitute + `O_MR1` for the [appropriate constant][4], depending when the APIs were + introduced. +* Don't put any `SDK_INT` checks inside this class, because it must only be + called on >= OMR1. + +## Investigating class verification failures + +Class verification is generally surprising and nonintuitive. Fortunately, the +ART team have provided tools to investigate errors (and the chromium team has +built helpful wrappers). + +### Listing failing classes + +The main starting point is to figure out which classes fail verification (those +which ART marks as `RetryVerificationAtRuntime`). This can be done for **any +Android app** (it doesn't have to be from the chromium project) like so: + +```shell +# Install the app first. Using Chrome as an example. +autoninja -C out/Default chrome_public_apk +out/Default/bin/chrome_public_apk install + +# List all classes marked as 'RetryVerificationAtRuntime' +build/android/list_class_verification_failures.py --package="org.chromium.chrome" +W 0.000s Main Skipping deobfuscation because no map file was provided. +first.failing.Class +second.failing.Class +... +``` + +"Skipping deobfuscation because no map file was provided" is a warning, since +many Android applications (including Chrome's release builds) are built with +proguard (or similar tools) to obfuscate Java classes and shrink code. Although +it's safe to ignore this warning if you don't obfuscate Java code, the script +knows how to deobfuscate classes for you (useful for `is_debug = true` or +`is_java_debug = true`): + +```shell +build/android/list_class_verification_failures.py --package="org.chromium.chrome" \ + --mapping=<path/to/file.mapping> # ex. out/Release/apks/ChromePublic.apk.mapping +android.support.design.widget.AppBarLayout +android.support.design.widget.TextInputLayout +... +``` + +Googlers can also download mappings for [official +builds](http://go/clank-webview/official-builds). + +### Understanding the reason for the failure + +ART team also provide tooling for this. You can configure ART on a rooted device +to log all class verification failures (during installation), at which point the +cause is much clearer: + +```shell +# Enable ART logging (requires root). Note the 2 pairs of quotes! +adb root +adb shell setprop dalvik.vm.dex2oat-flags '"--runtime-arg -verbose:verifier"' + +# Restart Android services to pick up the settings +adb shell stop && adb shell start + +# Optional: clear logs which aren't relevant +adb logcat -c + +# Install the app and check for ART logs +adb install -d -r out/Default/apks/ChromePublic.apk +adb logcat | grep 'dex2oat' +... +... I dex2oat : Soft verification failures in boolean org.chromium.content.browser.selection.SelectionPopupControllerImpl.b(android.view.ActionMode, android.view.Menu) +... I dex2oat : boolean org.chromium.content.browser.selection.SelectionPopupControllerImpl.b(android.view.ActionMode, android.view.Menu): [0xF0] couldn't find method android.view.textclassifier.TextClassification.getActions ()Ljava/util/List; +... I dex2oat : boolean org.chromium.content.browser.selection.SelectionPopupControllerImpl.b(android.view.ActionMode, android.view.Menu): [0xFA] couldn't find method android.view.textclassifier.TextClassification.getActions ()Ljava/util/List; +... +``` + +*** note +**Note:** you may want to avoid `adb` wrapper scripts (ex. +`out/Default/bin/chrome_public_apk install`). These scripts cache the package +manager state to optimize away idempotent installs. However in this case, we +**do** want to trigger idempotent installs, because we want to re-trigger AOT +verification. +*** + +In the above example, `SelectionPopupControllerImpl` fails verification on Oreo +(API 26) because it refers to [`TextClassification.getActions()`][5], which was +added in Pie (API 28). If `SelectionPopupControllerImpl` is used on pre-Pie +devices, then `TextClassification.getActions()` must be out-of-lined. + +## See also + +* Bugs or questions? Contact ntfschr@chromium.org +* ART team's Google I/O talks: [2014](https://youtu.be/EBlTzQsUoOw) and later + years +* Analysis of class verification in Chrome and WebView (Google-only + [doc](http://go/class-verification-chromium-analysis)) +* Presentation on class verification in Chrome and WebView (Google-only + [slide deck](http://go/class-verification-chromium-slides)) + +[1]: https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.5 +[2]: https://developer.android.com/reference/android/view/Window.html#isWideColorGamut() +[3]: https://bugs.chromium.org/p/chromium/issues/detail?id=838702 +[4]: https://developer.android.com/reference/android/os/Build.VERSION_CODES +[5]: https://developer.android.com/reference/android/view/textclassifier/TextClassification.html#getActions()
diff --git a/chrome/VERSION b/chrome/VERSION index 621aab1..409e7c2 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=77 MINOR=0 -BUILD=3834 +BUILD=3835 PATCH=0
diff --git a/chrome/android/java/res/layout/payment_request.xml b/chrome/android/java/res/layout/payment_request.xml index 9979c2e..8a9061af 100644 --- a/chrome/android/java/res/layout/payment_request.xml +++ b/chrome/android/java/res/layout/payment_request.xml
@@ -30,10 +30,19 @@ android:id="@+id/payment_container_layout" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" /> + android:orientation="vertical"> + <TextView + android:id="@+id/retry_error" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:visibility="gone" + android:textAppearance="@style/TextAppearance.PaymentsUiSectionWarningText" /> + </LinearLayout> </org.chromium.chrome.browser.widget.FadingEdgeScrollView> <include layout="@layout/payment_request_bottom_bar" /> -</org.chromium.chrome.browser.widget.BoundedLinearLayout> \ No newline at end of file +</org.chromium.chrome.browser.widget.BoundedLinearLayout>
diff --git a/chrome/android/java/res/layout/payment_request_header.xml b/chrome/android/java/res/layout/payment_request_header.xml index be4a8e6..80953d5 100644 --- a/chrome/android/java/res/layout/payment_request_header.xml +++ b/chrome/android/java/res/layout/payment_request_header.xml
@@ -13,69 +13,55 @@ android:id="@+id/header" android:layout_height="wrap_content" android:layout_width="match_parent" - android:layout_gravity="center_vertical" - android:orientation="vertical"> - <FrameLayout - android:layout_height="wrap_content" - android:layout_width="match_parent" - android:minHeight="64dp"> - <ImageView - android:id="@+id/icon_view" - android:layout_height="24dp" - android:layout_width="24dp" - android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" - android:layout_gravity="start|center_vertical" - android:importantForAccessibility="no" - android:scaleType="centerInside" /> - <LinearLayout - android:id="@+id/page_info" - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:layout_marginStart="50dp" - android:layout_marginEnd="50dp" - android:layout_marginBottom="@dimen/payments_section_vertical_spacing" - android:layout_marginTop="@dimen/payments_section_vertical_spacing" - android:layout_gravity="center_vertical" - android:orientation="vertical"> - <TextView - android:id="@+id/page_title" - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:paddingStart="6dp" - android:ellipsize="end" - android:maxLines="1" - android:singleLine="true" - android:textAppearance="@style/TextAppearance.PaymentRequestHeaderTitle" /> - <TextView - android:id="@+id/hostname" - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:paddingStart="6dp" - android:gravity="center_vertical" - android:ellipsize="start" - android:maxLines="1" - android:singleLine="true" - android:textAppearance="@style/TextAppearance.BlackBody" /> - </LinearLayout> - <ImageView - android:id="@+id/close_button" - android:layout_gravity="end|center_vertical" - android:layout_height="56dp" - android:layout_width="56dp" - android:src="@drawable/btn_close" - android:contentDescription="@string/close" - android:background="?attr/selectableItemBackground" - android:scaleType="center" - app:tint="@color/standard_mode_tint" /> - </FrameLayout> - <TextView - android:id="@+id/retry_error" - android:layout_height="wrap_content" - android:layout_width="match_parent" + android:minHeight="64dp"> + <ImageView + android:id="@+id/icon_view" + android:layout_height="24dp" + android:layout_width="24dp" android:layout_marginStart="16dp" android:layout_marginEnd="16dp" - android:visibility="gone" - android:textAppearance="@style/TextAppearance.PaymentsUiSectionWarningText" /> + android:layout_gravity="start|center_vertical" + android:importantForAccessibility="no" + android:scaleType="centerInside" /> + <LinearLayout + android:id="@+id/page_info" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_marginStart="50dp" + android:layout_marginEnd="50dp" + android:layout_marginBottom="@dimen/payments_section_vertical_spacing" + android:layout_marginTop="@dimen/payments_section_vertical_spacing" + android:layout_gravity="center_vertical" + android:orientation="vertical"> + <TextView + android:id="@+id/page_title" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:paddingStart="6dp" + android:ellipsize="end" + android:maxLines="1" + android:singleLine="true" + android:textAppearance="@style/TextAppearance.PaymentRequestHeaderTitle" /> + <TextView + android:id="@+id/hostname" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:paddingStart="6dp" + android:gravity="center_vertical" + android:ellipsize="start" + android:maxLines="1" + android:singleLine="true" + android:textAppearance="@style/TextAppearance.BlackBody" /> + </LinearLayout> + <ImageView + android:id="@+id/close_button" + android:layout_gravity="end|center_vertical" + android:layout_height="56dp" + android:layout_width="56dp" + android:src="@drawable/btn_close" + android:contentDescription="@string/close" + android:background="?attr/selectableItemBackground" + android:scaleType="center" + app:tint="@color/standard_mode_tint" /> </org.chromium.chrome.browser.payments.ui.PaymentRequestHeader> </merge>
diff --git a/chrome/android/java/res/xml/site_settings_preferences.xml b/chrome/android/java/res/xml/site_settings_preferences.xml index d5ae426..25ab570 100644 --- a/chrome/android/java/res/xml/site_settings_preferences.xml +++ b/chrome/android/java/res/xml/site_settings_preferences.xml
@@ -4,7 +4,7 @@ found in the LICENSE file. --> <!-- The order of the following items is from: http://crbug.com/610358. --> -<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" +<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <!-- All sites --> <org.chromium.chrome.browser.preferences.website.SiteSettingsPreference @@ -98,4 +98,4 @@ <org.chromium.chrome.browser.preferences.website.SiteSettingsPreference android:fragment="org.chromium.chrome.browser.preferences.website.SingleCategoryPreferences" android:key="clipboard" /> -</PreferenceScreen> +</android.support.v7.preference.PreferenceScreen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/DownloadGlue.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/DownloadGlue.java index b178b9e74..28a0c6f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/DownloadGlue.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/DownloadGlue.java
@@ -4,11 +4,11 @@ package org.chromium.chrome.browser.download.home.glue; -import android.os.Handler; import android.text.TextUtils; import org.chromium.base.Callback; import org.chromium.base.CollectionUtil; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.download.DownloadInfo; import org.chromium.chrome.browser.download.DownloadItem; import org.chromium.chrome.browser.download.DownloadManagerService; @@ -22,6 +22,7 @@ import org.chromium.components.offline_items_collection.OfflineItemShareInfo; import org.chromium.components.offline_items_collection.ShareCallback; import org.chromium.components.offline_items_collection.VisualsCallback; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.ArrayList; import java.util.List; @@ -65,7 +66,13 @@ @Override public void onDownloadItemUpdated(DownloadItem item) { if (!canShowDownloadItem(item)) return; - mDelegate.onItemUpdated(DownloadItem.createOfflineItem(item), null); + + OfflineItem offlineItem = DownloadItem.createOfflineItem(item); + mDelegate.onItemUpdated(offlineItem, null); + + if (offlineItem.externallyRemoved) { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> removeItem(offlineItem)); + } } /** @see OfflineContentProvider.Observer#onItemRemoved(ContentId) */ @@ -146,7 +153,7 @@ /** @see OfflineContentProvider#getItemById(ContentId, Callback) */ public void getItemById(ContentId id, Callback<OfflineItem> callback) { assert false : "Not supported."; - new Handler().post(() -> callback.onResult(null)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> callback.onResult(null)); } /** @see OfflineContentProvider#getAllItems(Callback) */ @@ -161,14 +168,15 @@ /** @see OfflineContentProvider#getVisualsForItem(ContentId, VisualsCallback) */ public void getVisualsForItem(ContentId id, VisualsCallback callback) { - new Handler().post(() -> callback.onVisualsAvailable(id, null)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> callback.onVisualsAvailable(id, null)); } /** @see OfflineContentProvider#getShareInfoForItem(ContentId, ShareCallback) */ public void getShareInfoForItem(OfflineItem item, ShareCallback callback) { OfflineItemShareInfo info = new OfflineItemShareInfo(); info.uri = DownloadUtils.getUriForItem(item.filePath); - new Handler().post(() -> callback.onShareInfoAvailable(item.id, info)); + PostTask.postTask( + UiThreadTaskTraits.DEFAULT, () -> callback.onShareInfoAvailable(item.id, info)); } /** @see OfflineContentProvider#renameItem(ContentId, String, Callback)*/
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestHeader.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestHeader.java index 7eb8a67a..4296e5c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestHeader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestHeader.java
@@ -9,11 +9,9 @@ import android.support.annotation.ColorInt; import android.text.Spannable; import android.text.SpannableStringBuilder; -import android.text.TextUtils; import android.util.AttributeSet; -import android.view.View; +import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; @@ -25,7 +23,7 @@ import org.chromium.chrome.browser.widget.TintedDrawable; /** This class represents a bar to display at the top of the payment request UI. */ -public class PaymentRequestHeader extends LinearLayout { +public class PaymentRequestHeader extends FrameLayout { private final @ColorInt int mBackgroundColor; private Context mContext; @@ -83,19 +81,4 @@ hostName.setPaddingRelative(0, 0, 0, 0); } } - - /** - * Sets the retry error message on the header. - * - * @param error The error message to display on the header. - */ - public void setRetryErrorMessage(String error) { - TextView errorMessageView = (TextView) findViewById(R.id.retry_error); - errorMessageView.setText(error); - if (TextUtils.isEmpty(error)) { - errorMessageView.setVisibility(View.GONE); - } else { - errorMessageView.setVisibility(View.VISIBLE); - } - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java index 7c945092..62d299e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
@@ -281,6 +281,7 @@ private FadingEdgeScrollView mPaymentContainer; private LinearLayout mPaymentContainerLayout; + private TextView mRetryErrorView; private ViewGroup mBottomBar; private Button mEditButton; private Button mPayButton; @@ -498,6 +499,7 @@ mPaymentContainer = (FadingEdgeScrollView) mRequestView.findViewById(R.id.option_container); mPaymentContainerLayout = (LinearLayout) mRequestView.findViewById(R.id.payment_container_layout); + mRetryErrorView = mRequestView.findViewById(R.id.retry_error); mOrderSummarySection = new LineItemBreakdownSection(context, context.getString(R.string.payments_order_summary_label), this, context.getString(R.string.payments_updated_label)); @@ -625,7 +627,23 @@ * @param error The error message to display on the header. */ public void setRetryErrorMessage(String error) { - ((PaymentRequestHeader) mRequestView.findViewById(R.id.header)).setRetryErrorMessage(error); + if (mRetryErrorView == null) return; + + mRetryErrorView.setText(error); + if (TextUtils.isEmpty(error)) { + mRetryErrorView.setVisibility(View.GONE); + } else { + if (mIsExpandedToFullHeight) { + // Add paddings instead of margin to let getMeasuredHeight return correct value for + // section resize animation. + int paddingSize = mContext.getResources().getDimensionPixelSize( + R.dimen.editor_dialog_section_large_spacing); + ViewCompat.setPaddingRelative(mRetryErrorView, 0, paddingSize, 0, paddingSize); + } else { + ViewCompat.setPaddingRelative(mRetryErrorView, 0, 0, 0, 0); + } + mRetryErrorView.setVisibility(View.VISIBLE); + } } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromeBasePreferenceCompat.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromeBasePreferenceCompat.java index 124de2b..723cfec 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromeBasePreferenceCompat.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromeBasePreferenceCompat.java
@@ -48,6 +48,7 @@ */ public ChromeBasePreferenceCompat(Context context, AttributeSet attrs) { super(context, attrs); + setLayoutResource(R.layout.preference_compat); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ChromeBasePreference); mIconTint = a.getColorStateList(R.styleable.ChromeBasePreference_iconTint);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreference.java index 3c349963..ee69eac4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreference.java
@@ -6,17 +6,17 @@ import android.content.Context; import android.support.v4.view.ViewCompat; +import android.support.v7.preference.PreferenceViewHolder; import android.util.AttributeSet; -import android.view.View; import android.widget.ImageView; import org.chromium.chrome.R; -import org.chromium.chrome.browser.preferences.ChromeBasePreference; +import org.chromium.chrome.browser.preferences.ChromeBasePreferenceCompat; /** * A custom preference for drawing Site Settings entries. */ -public class SiteSettingsPreference extends ChromeBasePreference { +public class SiteSettingsPreference extends ChromeBasePreferenceCompat { /** * Constructor for inflating from XML. */ @@ -25,11 +25,11 @@ } @Override - protected void onBindView(View view) { - super.onBindView(view); + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); int padding = getContext().getResources().getDimensionPixelSize(R.dimen.pref_icon_padding); - ImageView icon = (ImageView) view.findViewById(android.R.id.icon); + ImageView icon = (ImageView) holder.findViewById(android.R.id.icon); ViewCompat.setPaddingRelative( icon, padding, icon.getPaddingTop(), 0, icon.getPaddingBottom()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java index 2716cb9..4387c5c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java
@@ -5,10 +5,8 @@ package org.chromium.chrome.browser.preferences.website; import android.os.Bundle; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceClickListener; -import android.preference.PreferenceFragment; -import android.widget.ListView; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceFragmentCompat; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; @@ -31,8 +29,8 @@ * version/experiment so the organization of this menu should be simplified, probably by moving * Media to its own dedicated PreferenceFragment rather than sharing this one. */ -public class SiteSettingsPreferences extends PreferenceFragment - implements OnPreferenceClickListener { +public class SiteSettingsPreferences + extends PreferenceFragmentCompat implements Preference.OnPreferenceClickListener { // The keys for each category shown on the Site Settings page // are defined in the SiteSettingsCategory, additional keys // are listed here. @@ -43,8 +41,7 @@ boolean mMediaSubMenu; @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { PreferenceUtils.addPreferencesFromResource(this, R.xml.site_settings_preferences); getActivity().setTitle(R.string.prefs_site_settings); @@ -64,7 +61,7 @@ @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - ((ListView) getView().findViewById(android.R.id.list)).setDivider(null); + setDivider(null); } private Preference findPreference(@Type int type) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java index 8ae6b4a..8c986a6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java
@@ -466,7 +466,7 @@ SiteSettingsTestUtils.startSiteSettingsMenu(SiteSettingsPreferences.MEDIA_KEY); TestThreadUtils.runOnUiThreadBlocking(() -> { SiteSettingsPreferences siteSettings = - (SiteSettingsPreferences) preferenceActivity.getMainFragment(); + (SiteSettingsPreferences) preferenceActivity.getMainFragmentCompat(); SiteSettingsPreference allSites = (SiteSettingsPreference) siteSettings.findPreference( SiteSettingsCategory.preferenceKey(SiteSettingsCategory.Type.ALL_SITES));
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index e8230f2c..86297c3d 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-77.0.3832.0_rc-r1-merged.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-77.0.3833.0_rc-r1-merged.afdo.bz2 \ No newline at end of file
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb index c212e56..a359106 100644 --- a/chrome/app/resources/generated_resources_el.xtb +++ b/chrome/app/resources/generated_resources_el.xtb
@@ -3755,7 +3755,7 @@ <translation id="6725073593266469338">Υπηρεσία διεπαφής χρήστη</translation> <translation id="6725206449694821596">Πρωτόκολλο εκτύπωσης στο διαδίκτυο (IPP)</translation> <translation id="67269783048918309">Αποστολή δεδομένων χρήσης και διαγνωστικών. Επί του παρόντος, αυτή η συσκευή στέλνει αυτόματα διαγνωστικά δεδομένα, δεδομένα συσκευής και χρήσης εφαρμογών στην Google. Αυτά τα δεδομένα δεν θα χρησιμοποιηθούν για την ταυτοποίηση του παιδιού σας και θα βοηθήσουν με τη σταθερότητα του συστήματος και των εφαρμογών και την παροχή άλλων βελτιώσεων. Ορισμένα συγκεντρωτικά δεδομένα θα βοηθήσουν επίσης τις εφαρμογές και τους συνεργάτες της Google, όπως τους προγραμματιστές Android. Αυτή η <ph name="BEGIN_LINK1" />ρύθμιση<ph name="END_LINK1" /> επιβάλλεται από τον κάτοχο. Εάν είναι ενεργή η ρύθμιση της πρόσθετης Δραστηριότητας ιστού και εφαρμογών για το παιδί σας, αυτά τα δεδομένα μπορεί να αποθηκευτούν στον Λογαριασμό του Google. <ph name="BEGIN_LINK2" />Μάθετε περισσότερα<ph name="END_LINK2" /></translation> -<translation id="6727969043791803658">Συνδεδεμένη, μπαταρία <ph name="BATTERY_PERCENTAGE" /></translation> +<translation id="6727969043791803658">Συνδεδεμένη, μπαταρία <ph name="BATTERY_PERCENTAGE" /> %</translation> <translation id="6732801395666424405">Δεν έχουν φορτωθεί τα πιστοποιητικά</translation> <translation id="6732900235521116609">Δεν είναι δυνατή η κατάργηση της συντόμευσης</translation> <translation id="6735304988756581115">Εμφάνιση cookie και άλλων δεδομένων ιστότοπου...</translation>
diff --git a/chrome/app/theme/default_100_percent/mac/bookmark_bar_folder_managed_white.png b/chrome/app/theme/default_100_percent/mac/bookmark_bar_folder_managed_white.png new file mode 100644 index 0000000..dd21508 --- /dev/null +++ b/chrome/app/theme/default_100_percent/mac/bookmark_bar_folder_managed_white.png Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index cc49225..f494eaf9 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd
@@ -63,8 +63,7 @@ <if expr="is_macosx"> <structure type="chrome_scaled_image" name="IDR_BOOKMARK_BAR_FOLDER" file="mac/bookmark_bar_folder.png" /> <structure type="chrome_scaled_image" name="IDR_BOOKMARK_BAR_FOLDER_MANAGED" file="mac/bookmark_bar_folder_managed.png" /> - </if> - <if expr="is_macosx"> + <structure type="chrome_scaled_image" name="IDR_BOOKMARK_BAR_FOLDER_MANAGED_WHITE" file="mac/bookmark_bar_folder_managed_white.png" /> <structure type="chrome_scaled_image" name="IDR_BOOKMARK_BAR_FOLDER_WHITE" file="mac/bookmark_bar_folder_white.png" /> </if> <if expr="is_win">
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 3d6430a..6f85d57 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1230,6 +1230,8 @@ "predictors/predictor_database_factory.h", "predictors/predictor_table_base.cc", "predictors/predictor_table_base.h", + "predictors/predictors_features.cc", + "predictors/predictors_features.h", "predictors/proxy_lookup_client_impl.cc", "predictors/proxy_lookup_client_impl.h", "predictors/resolve_host_client_impl.cc", @@ -4677,8 +4679,6 @@ "plugins/plugin_prefs_factory.h", "plugins/plugin_response_interceptor_url_loader_throttle.cc", "plugins/plugin_response_interceptor_url_loader_throttle.h", - "plugins/plugin_status_pref_setter.cc", - "plugins/plugin_status_pref_setter.h", "plugins/plugin_utils.cc", "plugins/plugin_utils.h", "plugins/plugins_resource_service.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index fc29a38..9933081 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2022,6 +2022,10 @@ ENABLE_DISABLE_VALUE_TYPE( service_manager::switches::kEnableAppContainer, service_manager::switches::kDisableAppContainer)}, + {"enable-aura-tooltips-on-windows", + flag_descriptions::kEnableAuraTooltipsOnWindowsName, + flag_descriptions::kEnableAuraTooltipsOnWindowsDescription, kOsWin, + FEATURE_VALUE_TYPE(views::features::kEnableAuraTooltipsOnWindows)}, #endif // OS_WIN #if defined(TOOLKIT_VIEWS) || defined(OS_ANDROID) {"enable-autofill-credit-card-upload", @@ -2169,6 +2173,12 @@ kOsCrOS, SINGLE_VALUE_TYPE( ::switches::kEnableExperimentalAccessibilitySwitchAccess)}, + {"enable-experimental-accessibility-switch-access-text", + flag_descriptions::kExperimentalAccessibilitySwitchAccessTextName, + flag_descriptions::kExperimentalAccessibilitySwitchAccessTextDescription, + kOsCrOS, + SINGLE_VALUE_TYPE( + ::switches::kEnableExperimentalAccessibilitySwitchAccessText)}, {"enable-experimental-accessibility-chromevox-language-switching", flag_descriptions:: kExperimentalAccessibilityChromeVoxLanguageSwitchingName, @@ -3147,6 +3157,11 @@ {"enable-app-grid-ghost", flag_descriptions::kEnableAppGridGhostName, flag_descriptions::kEnableAppGridGhostDescription, kOsCrOS, FEATURE_VALUE_TYPE(app_list_features::kEnableAppGridGhost)}, + + {"enable-search-box-selection", + flag_descriptions::kEnableSearchBoxSelectionName, + flag_descriptions::kEnableSearchBoxSelectionDescription, kOsCrOS, + FEATURE_VALUE_TYPE(app_list_features::kEnableSearchBoxSelection)}, #endif // OS_CHROMEOS {"enable-accessibility-image-descriptions",
diff --git a/chrome/browser/android/DEPS b/chrome/browser/android/DEPS index 0206149..b5da37d 100644 --- a/chrome/browser/android/DEPS +++ b/chrome/browser/android/DEPS
@@ -12,6 +12,7 @@ "+sandbox/linux/seccomp-bpf-helpers", "+sandbox/sandbox_buildflags.h", "+third_party/gvr-android-sdk", + "+third_party/blink/public/common", "+third_party/blink/public/mojom/unhandled_tap_notifier/unhandled_tap_notifier.mojom.h", ]
diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browser/android/bookmarks/bookmark_bridge.cc index fcf3af5..4a91aa6 100644 --- a/chrome/browser/android/bookmarks/bookmark_bridge.cc +++ b/chrome/browser/android/bookmarks/bookmark_bridge.cc
@@ -12,6 +12,7 @@ #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/bind.h" +#include "base/containers/adapters.h" #include "base/containers/stack.h" #include "base/containers/stack_container.h" #include "base/i18n/string_compare.h" @@ -187,9 +188,8 @@ // Save all the permanent nodes. const BookmarkNode* root_node = bookmark_model_->root_node(); permanent_nodes->push_back(root_node); - for (int i = 0; i < root_node->child_count(); ++i) { - permanent_nodes->push_back(root_node->GetChild(i)); - } + for (const auto& child : root_node->children()) + permanent_nodes->push_back(child.get()); permanent_nodes->push_back( partner_bookmarks_shim_->GetPartnerBookmarksRoot()); @@ -225,7 +225,7 @@ if (get_special) { if (managed_bookmark_service_->managed_node() && - managed_bookmark_service_->managed_node()->child_count() > 0) { + !managed_bookmark_service_->managed_node()->children().empty()) { top_level_folders.push_back(managed_bookmark_service_->managed_node()); } if (partner_bookmarks_shim_->HasPartnerBookmarks() @@ -237,31 +237,21 @@ std::size_t special_count = top_level_folders.size(); if (get_normal) { - DCHECK_EQ(bookmark_model_->root_node()->child_count(), 5); + DCHECK_EQ(5u, bookmark_model_->root_node()->children().size()); - const BookmarkNode* mobile_node = bookmark_model_->mobile_node(); - for (int i = 0; i < mobile_node->child_count(); ++i) { - const BookmarkNode* node = mobile_node->GetChild(i); - if (node->is_folder()) { - top_level_folders.push_back(node); - } + for (const auto& node : bookmark_model_->mobile_node()->children()) { + if (node->is_folder()) + top_level_folders.push_back(node.get()); } - const BookmarkNode* bookmark_bar_node = - bookmark_model_->bookmark_bar_node(); - for (int i = 0; i < bookmark_bar_node->child_count(); ++i) { - const BookmarkNode* node = bookmark_bar_node->GetChild(i); - if (node->is_folder()) { - top_level_folders.push_back(node); - } + for (const auto& node : bookmark_model_->bookmark_bar_node()->children()) { + if (node->is_folder()) + top_level_folders.push_back(node.get()); } - const BookmarkNode* other_node = bookmark_model_->other_node(); - for (int i = 0; i < other_node->child_count(); ++i) { - const BookmarkNode* node = other_node->GetChild(i); - if (node->is_folder()) { - top_level_folders.push_back(node); - } + for (const auto& node : bookmark_model_->other_node()->children()) { + if (node->is_folder()) + top_level_folders.push_back(node.get()); } std::unique_ptr<icu::Collator> collator = GetICUCollator(); @@ -289,53 +279,37 @@ std::unique_ptr<icu::Collator> collator = GetICUCollator(); // Vector to temporarily contain all child bookmarks at same level for sorting - std::vector<const BookmarkNode*> bookmarkList; - - // Stack for Depth-First Search of bookmark model. It stores nodes and their - // heights. - base::stack<std::pair<const BookmarkNode*, int>> stk; - - bookmarkList.push_back(bookmark_model_->mobile_node()); - bookmarkList.push_back(bookmark_model_->bookmark_bar_node()); - bookmarkList.push_back(bookmark_model_->other_node()); + std::vector<const BookmarkNode*> bookmarks = { + bookmark_model_->mobile_node(), + bookmark_model_->bookmark_bar_node(), + bookmark_model_->other_node(), + }; // Push all sorted top folders in stack and give them depth of 0. // Note the order to push folders to stack should be opposite to the order in // output. - for (std::vector<const BookmarkNode*>::reverse_iterator it = - bookmarkList.rbegin(); - it != bookmarkList.rend(); - ++it) { - stk.push(std::make_pair(*it, 0)); - } + base::stack<std::pair<const BookmarkNode*, int>> stk; + for (const auto* bookmark : base::Reversed(bookmarks)) + stk.emplace(bookmark, 0); while (!stk.empty()) { const BookmarkNode* node = stk.top().first; int depth = stk.top().second; stk.pop(); - Java_BookmarkBridge_addToBookmarkIdListWithDepth(env, - j_folders_obj, - node->id(), - GetBookmarkType(node), - j_depths_obj, - depth); - bookmarkList.clear(); - for (int i = 0; i < node->child_count(); ++i) { - const BookmarkNode* child = node->GetChild(i); + Java_BookmarkBridge_addToBookmarkIdListWithDepth( + env, j_folders_obj, node->id(), GetBookmarkType(node), j_depths_obj, + depth); + bookmarks.clear(); + for (const auto& child : node->children()) { if (child->is_folder() && - managed_bookmark_service_->CanBeEditedByUser(child)) { - bookmarkList.push_back(node->GetChild(i)); + managed_bookmark_service_->CanBeEditedByUser(child.get())) { + bookmarks.push_back(child.get()); } } - std::stable_sort(bookmarkList.begin(), - bookmarkList.end(), + std::stable_sort(bookmarks.begin(), bookmarks.end(), BookmarkTitleComparer(this, collator.get())); - for (std::vector<const BookmarkNode*>::reverse_iterator it = - bookmarkList.rbegin(); - it != bookmarkList.rend(); - ++it) { - stk.push(std::make_pair(*it, depth + 1)); - } + for (const auto* bookmark : base::Reversed(bookmarks)) + stk.emplace(bookmark, depth + 1); } } @@ -385,7 +359,7 @@ jint type) { DCHECK(IsLoaded()); const BookmarkNode* node = GetNodeByID(id, type); - return node->child_count(); + return jint{node->children().size()}; } void BookmarkBridge::GetChildIDs(JNIEnv* env, @@ -402,15 +376,11 @@ return; // Get the folder contents - for (int i = 0; i < parent->child_count(); ++i) { - const BookmarkNode* child = parent->GetChild(i); - if (!IsFolderAvailable(child) || !IsReachable(child)) - continue; - - if ((child->is_folder() && get_folders) || - (!child->is_folder() && get_bookmarks)) { - Java_BookmarkBridge_addToBookmarkIdList( - env, j_result_obj, child->id(), GetBookmarkType(child)); + for (const auto& child : parent->children()) { + if (IsFolderAvailable(child.get()) && IsReachable(child.get()) && + (child->is_folder() ? get_folders : get_bookmarks)) { + Java_BookmarkBridge_addToBookmarkIdList(env, j_result_obj, child->id(), + GetBookmarkType(child.get())); } } @@ -458,17 +428,15 @@ const BookmarkNode* node = nodes.front(); nodes.pop(); - for (int i = 0; i < node->child_count(); ++i) { + for (const auto& child : node->children()) { // Empty title means deleted partner bookmarks or folders. See // PartnerBookmarksShim::RemoveBookmark(). - const BookmarkNode* child = node->GetChild(i); - if (GetTitle(child).empty()) + if (GetTitle(child.get()).empty()) continue; - if (child->is_folder()) { - nodes.push(child); - } else { - count += 1; - } + if (child->is_folder()) + nodes.push(child.get()); + else + ++count; } } @@ -542,11 +510,9 @@ env, folder->id(), GetBookmarkType(folder)); // Get the folder contents. - for (int i = 0; i < folder->child_count(); ++i) { - const BookmarkNode* node = folder->GetChild(i); - if (!IsFolderAvailable(node)) - continue; - ExtractBookmarkNodeInformation(node, j_result_obj); + for (const auto& node : folder->children()) { + if (IsFolderAvailable(node.get())) + ExtractBookmarkNodeInformation(node.get(), j_result_obj); } if (folder == bookmark_model_->mobile_node() &&
diff --git a/chrome/browser/android/bookmarks/partner_bookmarks_reader.cc b/chrome/browser/android/bookmarks/partner_bookmarks_reader.cc index 4617da13..5507ad73 100644 --- a/chrome/browser/android/bookmarks/partner_bookmarks_reader.cc +++ b/chrome/browser/android/bookmarks/partner_bookmarks_reader.cc
@@ -103,12 +103,12 @@ const BookmarkNode* GetNodeByID(const BookmarkNode* parent, int64_t id) { if (parent->id() == id) return parent; - for (int i= 0, child_count = parent->child_count(); i < child_count; ++i) { - const BookmarkNode* result = GetNodeByID(parent->GetChild(i), id); + for (const auto& child : parent->children()) { + const BookmarkNode* result = GetNodeByID(child.get(), id); if (result) return result; } - return NULL; + return nullptr; } } // namespace
diff --git a/chrome/browser/android/bookmarks/partner_bookmarks_shim.cc b/chrome/browser/android/bookmarks/partner_bookmarks_shim.cc index 4e592dc..87a37053 100644 --- a/chrome/browser/android/bookmarks/partner_bookmarks_shim.cc +++ b/chrome/browser/android/bookmarks/partner_bookmarks_shim.cc
@@ -230,12 +230,12 @@ int64_t id) const { if (parent->id() == id) return parent; - for (int i = 0, child_count = parent->child_count(); i < child_count; ++i) { - const BookmarkNode* result = GetNodeByID(parent->GetChild(i), id); + for (const auto& node : parent->children()) { + const BookmarkNode* result = GetNodeByID(node.get(), id); if (result) return result; } - return NULL; + return nullptr; } void PartnerBookmarksShim::ReloadNodeMapping() {
diff --git a/chrome/browser/android/signin/signin_manager_android_unittest.cc b/chrome/browser/android/signin/signin_manager_android_unittest.cc index 14c90f3..36c96e4 100644 --- a/chrome/browser/android/signin/signin_manager_android_unittest.cc +++ b/chrome/browser/android/signin/signin_manager_android_unittest.cc
@@ -169,17 +169,17 @@ // Tests that wiping all data also deletes bookmarks. TEST_F(SigninManagerAndroidTest, DeleteBookmarksWhenWipingAllData) { bookmarks::BookmarkModel* bookmark_model = AddTestBookmarks(); - ASSERT_GE(bookmark_model->bookmark_bar_node()->child_count(), 0); + ASSERT_GE(bookmark_model->bookmark_bar_node()->children().size(), 0u); WipeData(true); - EXPECT_EQ(0, bookmark_model->bookmark_bar_node()->child_count()); + EXPECT_EQ(0u, bookmark_model->bookmark_bar_node()->children().size()); } // Tests that wiping Google service worker caches does not delete bookmarks. TEST_F(SigninManagerAndroidTest, DontDeleteBookmarksWhenDeletingSWCaches) { bookmarks::BookmarkModel* bookmark_model = AddTestBookmarks(); - int bookmarks_count = bookmark_model->bookmark_bar_node()->child_count(); - ASSERT_GE(bookmarks_count, 0); + size_t num_bookmarks = bookmark_model->bookmark_bar_node()->children().size(); + ASSERT_GE(num_bookmarks, 0u); WipeData(false); - EXPECT_EQ(bookmarks_count, - bookmark_model->bookmark_bar_node()->child_count()); + EXPECT_EQ(num_bookmarks, + bookmark_model->bookmark_bar_node()->children().size()); }
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.cc b/chrome/browser/android/tab_web_contents_delegate_android.cc index 6906071b..0a537adc 100644 --- a/chrome/browser/android/tab_web_contents_delegate_android.cc +++ b/chrome/browser/android/tab_web_contents_delegate_android.cc
@@ -60,6 +60,7 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/security_style_explanations.h" #include "content/public/browser/web_contents.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" #include "third_party/blink/public/common/mediastream/media_stream_request.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" @@ -452,10 +453,12 @@ security_style_explanations); } -void TabWebContentsDelegateAndroid::OnDidBlockFramebust( +void TabWebContentsDelegateAndroid::OnDidBlockNavigation( content::WebContents* web_contents, - const GURL& url) { - ShowFramebustBlockInfobarInternal(web_contents, url); + const GURL& blocked_url, + const GURL& initiator_url, + blink::NavigationBlockedReason reason) { + ShowFramebustBlockInfobarInternal(web_contents, blocked_url); } void TabWebContentsDelegateAndroid::UpdateUserGestureCarryoverInfo(
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.h b/chrome/browser/android/tab_web_contents_delegate_android.h index eeed982c..80f3608 100644 --- a/chrome/browser/android/tab_web_contents_delegate_android.h +++ b/chrome/browser/android/tab_web_contents_delegate_android.h
@@ -11,6 +11,7 @@ #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "printing/buildflags/buildflags.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" class FindNotificationDetails; @@ -87,8 +88,10 @@ blink::WebSecurityStyle GetSecurityStyle( content::WebContents* web_contents, content::SecurityStyleExplanations* security_style_explanations) override; - void OnDidBlockFramebust(content::WebContents* web_contents, - const GURL& url) override; + void OnDidBlockNavigation(content::WebContents* web_contents, + const GURL& blocked_url, + const GURL& initiator_url, + blink::NavigationBlockedReason reason) override; void UpdateUserGestureCarryoverInfo( content::WebContents* web_contents) override; std::unique_ptr<content::WebContents> SwapWebContents(
diff --git a/chrome/browser/android/webapk/webapk_icon_hasher.cc b/chrome/browser/android/webapk/webapk_icon_hasher.cc index 0ead7442..9ce3731e 100644 --- a/chrome/browser/android/webapk/webapk_icon_hasher.cc +++ b/chrome/browser/android/webapk/webapk_icon_hasher.cc
@@ -38,15 +38,18 @@ // static void WebApkIconHasher::DownloadAndComputeMurmur2Hash( network::mojom::URLLoaderFactory* url_loader_factory, + const url::Origin& request_initiator, const GURL& icon_url, const Murmur2HashCallback& callback) { DownloadAndComputeMurmur2HashWithTimeout( - url_loader_factory, icon_url, kDownloadTimeoutInMilliseconds, callback); + url_loader_factory, request_initiator, icon_url, + kDownloadTimeoutInMilliseconds, callback); } // static void WebApkIconHasher::DownloadAndComputeMurmur2HashWithTimeout( network::mojom::URLLoaderFactory* url_loader_factory, + const url::Origin& request_initiator, const GURL& icon_url, int timeout_ms, const Murmur2HashCallback& callback) { @@ -69,11 +72,13 @@ } // The icon hasher will delete itself when it is done. - new WebApkIconHasher(url_loader_factory, icon_url, timeout_ms, callback); + new WebApkIconHasher(url_loader_factory, request_initiator, icon_url, + timeout_ms, callback); } WebApkIconHasher::WebApkIconHasher( network::mojom::URLLoaderFactory* url_loader_factory, + const url::Origin& request_initiator, const GURL& icon_url, int timeout_ms, const Murmur2HashCallback& callback) @@ -86,6 +91,7 @@ base::Unretained(this))); auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->request_initiator = request_initiator; resource_request->url = icon_url; simple_url_loader_ = network::SimpleURLLoader::Create( std::move(resource_request),
diff --git a/chrome/browser/android/webapk/webapk_icon_hasher.h b/chrome/browser/android/webapk/webapk_icon_hasher.h index d6226ca2..ffe3213 100644 --- a/chrome/browser/android/webapk/webapk_icon_hasher.h +++ b/chrome/browser/android/webapk/webapk_icon_hasher.h
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/timer/timer.h" #include "url/gurl.h" +#include "url/origin.h" namespace network { class SimpleURLLoader; @@ -33,17 +34,20 @@ // the image cannot not be downloaded in time (e.g. 404 HTTP error code). static void DownloadAndComputeMurmur2Hash( network::mojom::URLLoaderFactory* url_loader_factory, + const url::Origin& request_initiator, const GURL& icon_url, const Murmur2HashCallback& callback); static void DownloadAndComputeMurmur2HashWithTimeout( network::mojom::URLLoaderFactory* url_loader_factory, + const url::Origin& request_initiator, const GURL& icon_url, int timeout_ms, const Murmur2HashCallback& callback); private: WebApkIconHasher(network::mojom::URLLoaderFactory* url_loader_factory, + const url::Origin& request_initiator, const GURL& icon_url, int timeout_ms, const Murmur2HashCallback& callback);
diff --git a/chrome/browser/android/webapk/webapk_icon_hasher_unittest.cc b/chrome/browser/android/webapk/webapk_icon_hasher_unittest.cc index 2211223..1b6dce26 100644 --- a/chrome/browser/android/webapk/webapk_icon_hasher_unittest.cc +++ b/chrome/browser/android/webapk/webapk_icon_hasher_unittest.cc
@@ -23,6 +23,7 @@ #include "services/network/test/test_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" +#include "url/origin.h" namespace { @@ -38,7 +39,7 @@ void Run(network::mojom::URLLoaderFactory* url_loader_factory, const GURL& icon_url) { WebApkIconHasher::DownloadAndComputeMurmur2HashWithTimeout( - url_loader_factory, icon_url, 300, + url_loader_factory, url::Origin::Create(icon_url), icon_url, 300, base::Bind(&WebApkIconHasherRunner::OnCompleted, base::Unretained(this)));
diff --git a/chrome/browser/android/webapk/webapk_installer.cc b/chrome/browser/android/webapk/webapk_installer.cc index e7fb55d..004c369a 100644 --- a/chrome/browser/android/webapk/webapk_installer.cc +++ b/chrome/browser/android/webapk/webapk_installer.cc
@@ -53,6 +53,7 @@ #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/codec/png_codec.h" #include "url/gurl.h" +#include "url/origin.h" namespace { @@ -611,6 +612,7 @@ // should be fast because the icon should be in the HTTP cache. WebApkIconHasher::DownloadAndComputeMurmur2Hash( GetURLLoaderFactory(browser_context_), + url::Origin::Create(install_shortcut_info_->url), install_shortcut_info_->best_primary_icon_url, base::Bind(&WebApkInstaller::OnGotPrimaryIconMurmur2Hash, weak_ptr_factory_.GetWeakPtr())); @@ -629,6 +631,7 @@ install_shortcut_info_->best_primary_icon_url) { WebApkIconHasher::DownloadAndComputeMurmur2Hash( GetURLLoaderFactory(browser_context_), + url::Origin::Create(install_shortcut_info_->url), install_shortcut_info_->best_badge_icon_url, base::Bind(&WebApkInstaller::OnGotBadgeIconMurmur2Hash, weak_ptr_factory_.GetWeakPtr(), true, primary_icon_hash));
diff --git a/chrome/browser/android/webapk/webapk_installer_unittest.cc b/chrome/browser/android/webapk/webapk_installer_unittest.cc index 133b678..7c228900 100644 --- a/chrome/browser/android/webapk/webapk_installer_unittest.cc +++ b/chrome/browser/android/webapk/webapk_installer_unittest.cc
@@ -41,12 +41,18 @@ // URL of mock WebAPK server. const char* kServerUrl = "/webapkserver/"; +// Start URL for the WebAPK +const char* kStartUrl = "/index.html"; + // The URLs of best icons from Web Manifest. We use a random file in the test // data directory. Since WebApkInstaller does not try to decode the file as an // image it is OK that the file is not an image. const char* kBestPrimaryIconUrl = "/simple.html"; const char* kBestBadgeIconUrl = "/nostore.html"; +// Icon which has Cross-Origin-Resource-Policy: same-origin set. +const char* kBestPrimaryIconCorpUrl = "/banners/image-512px-corp.png"; + // Token from the WebAPK server. In production, the token is sent to Google // Play. Google Play uses the token to retrieve the WebAPK from the WebAPK // server. @@ -95,10 +101,12 @@ class WebApkInstallerRunner { public: WebApkInstallerRunner(content::BrowserContext* browser_context, + const GURL& start_url, const GURL& best_primary_icon_url, const GURL& best_badge_icon_url, SpaceStatus test_space_status) : browser_context_(browser_context), + start_url_(start_url), best_primary_icon_url_(best_primary_icon_url), best_badge_icon_url_(best_badge_icon_url), test_space_status_(test_space_status) {} @@ -109,7 +117,7 @@ base::RunLoop run_loop; on_completed_callback_ = run_loop.QuitClosure(); - ShortcutInfo info((GURL())); + ShortcutInfo info(start_url_); info.best_primary_icon_url = best_primary_icon_url_; info.best_badge_icon_url = best_badge_icon_url_; WebApkInstaller::InstallAsyncForTesting( @@ -152,6 +160,8 @@ content::BrowserContext* browser_context_; + const GURL start_url_; + // The Web Manifest's icon URLs. const GURL best_primary_icon_url_; const GURL best_badge_icon_url_; @@ -302,6 +312,9 @@ base::RunLoop().RunUntilIdle(); } + // Sets the Web Manifest's start URL. + void SetStartUrl(const GURL& start_url) { start_url_ = start_url; } + // Sets the best Web Manifest's primary icon URL. void SetBestPrimaryIconUrl(const GURL& best_primary_icon_url) { best_primary_icon_url_ = best_primary_icon_url; @@ -330,9 +343,9 @@ void SetSpaceStatus(const SpaceStatus status) { test_space_status_ = status; } std::unique_ptr<WebApkInstallerRunner> CreateWebApkInstallerRunner() { - return std::unique_ptr<WebApkInstallerRunner>( - new WebApkInstallerRunner(profile_.get(), best_primary_icon_url_, - best_badge_icon_url_, test_space_status_)); + return std::unique_ptr<WebApkInstallerRunner>(new WebApkInstallerRunner( + profile_.get(), start_url_, best_primary_icon_url_, + best_badge_icon_url_, test_space_status_)); } std::unique_ptr<BuildProtoRunner> CreateBuildProtoRunner() { @@ -344,6 +357,7 @@ private: // Sets default configuration for running WebApkInstaller. void SetDefaults() { + SetStartUrl(test_server_.GetURL(kStartUrl)); SetBestPrimaryIconUrl(test_server_.GetURL(kBestPrimaryIconUrl)); SetBestBadgeIconUrl(test_server_.GetURL(kBestBadgeIconUrl)); SetWebApkServerUrl(test_server_.GetURL(kServerUrl)); @@ -362,6 +376,9 @@ content::TestBrowserThreadBundle thread_bundle_; net::EmbeddedTestServer test_server_; + // Web Manifest's start URL. + GURL start_url_; + // Web Manifest's icon URLs. GURL best_primary_icon_url_; GURL best_badge_icon_url_; @@ -390,6 +407,17 @@ EXPECT_EQ(WebApkInstallResult::FAILURE, runner->result()); } +// Test that installation succeeds when the primary icon is guarded by +// a Cross-Origin-Resource-Policy: same-origin header and the icon is +// same-origin with the start URL. +TEST_F(WebApkInstallerTest, CrossOriginResourcePolicySameOriginIconSuccess) { + SetBestPrimaryIconUrl(test_server()->GetURL(kBestPrimaryIconCorpUrl)); + + std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); + runner->RunInstallWebApk(); + EXPECT_EQ(WebApkInstallResult::SUCCESS, runner->result()); +} + // Test that installation fails if fetching the bitmap at the best primary icon // URL returns no content. In a perfect world the fetch would always succeed // because the fetch for the same icon succeeded recently.
diff --git a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc index ea51b1c..040376e 100644 --- a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc +++ b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc
@@ -27,6 +27,7 @@ #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/codec/png_codec.h" #include "url/gurl.h" +#include "url/origin.h" using base::android::JavaParamRef; using base::android::ScopedJavaLocalRef; @@ -160,7 +161,7 @@ content::BrowserContext::GetDefaultStoragePartition(profile) ->GetURLLoaderFactoryForBrowserProcess() .get(), - info_.best_primary_icon_url, + url::Origin::Create(last_fetched_url_), info_.best_primary_icon_url, base::Bind(&WebApkUpdateDataFetcher::OnGotPrimaryIconMurmur2Hash, weak_ptr_factory_.GetWeakPtr())); } @@ -179,7 +180,7 @@ content::BrowserContext::GetDefaultStoragePartition(profile) ->GetURLLoaderFactoryForBrowserProcess() .get(), - info_.best_badge_icon_url, + url::Origin::Create(last_fetched_url_), info_.best_badge_icon_url, base::Bind(&WebApkUpdateDataFetcher::OnDataAvailable, weak_ptr_factory_.GetWeakPtr(), primary_icon_murmur2_hash, true));
diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/bookmarks/bookmark_html_writer.cc index 910d451..5fff539 100644 --- a/chrome/browser/bookmarks/bookmark_html_writer.cc +++ b/chrome/browser/bookmarks/bookmark_html_writer.cc
@@ -437,8 +437,8 @@ if (!url.empty()) bookmark_urls_.push_back(url); } else { - for (int i = 0; i < node->child_count(); ++i) - ExtractUrls(node->GetChild(i)); + for (const auto& child : node->children()) + ExtractUrls(child.get()); } }
diff --git a/chrome/browser/bookmarks/managed_bookmark_service_unittest.cc b/chrome/browser/bookmarks/managed_bookmark_service_unittest.cc index ef5ece5..b739c05d 100644 --- a/chrome/browser/bookmarks/managed_bookmark_service_unittest.cc +++ b/chrome/browser/bookmarks/managed_bookmark_service_unittest.cc
@@ -132,26 +132,23 @@ return false; if (node->is_folder()) { - const base::ListValue* children = NULL; + const base::ListValue* children = nullptr; if (!dict->GetList("children", &children) || - node->child_count() != static_cast<int>(children->GetSize())) { + node->children().size() != children->GetSize()) { return false; } - for (int i = 0; i < node->child_count(); ++i) { - const base::DictionaryValue* child = NULL; - if (!children->GetDictionary(i, &child) || - !NodeMatchesValue(node->GetChild(i), child)) { - return false; - } - } - } else if (node->is_url()) { - std::string url; - if (!dict->GetString("url", &url) || node->url() != url) - return false; - } else { - return false; + size_t i = 0; + return std::all_of(node->children().cbegin(), node->children().cend(), + [children, &i](const auto& child_node) { + const base::DictionaryValue* child = nullptr; + return children->GetDictionary(i++, &child) && + NodeMatchesValue(child_node.get(), child); + }); } - return true; + if (!node->is_url()) + return false; + std::string url; + return dict->GetString("url", &url) && node->url() == url; } content::TestBrowserThreadBundle thread_bundle_; @@ -256,14 +253,14 @@ managed_->managed_node())); const BookmarkNode* parent = managed_->managed_node(); - ASSERT_EQ(2, parent->child_count()); + ASSERT_EQ(2u, parent->children().size()); EXPECT_TRUE( bookmarks::IsDescendantOf(parent->GetChild(0), managed_->managed_node())); EXPECT_TRUE( bookmarks::IsDescendantOf(parent->GetChild(1), managed_->managed_node())); parent = parent->GetChild(1); - ASSERT_EQ(2, parent->child_count()); + ASSERT_EQ(2u, parent->children().size()); EXPECT_TRUE( bookmarks::IsDescendantOf(parent->GetChild(0), managed_->managed_node())); EXPECT_TRUE( @@ -271,7 +268,7 @@ } TEST_F(ManagedBookmarkServiceTest, RemoveAllDoesntRemoveManaged) { - EXPECT_EQ(2, managed_->managed_node()->child_count()); + EXPECT_EQ(2u, managed_->managed_node()->children().size()); EXPECT_CALL(observer_, BookmarkNodeAdded(model_, model_->bookmark_bar_node(), 0)); @@ -281,13 +278,13 @@ GURL("http://google.com/")); model_->AddFolder(model_->bookmark_bar_node(), 1, base::ASCIIToUTF16("Test Folder")); - EXPECT_EQ(2, model_->bookmark_bar_node()->child_count()); + EXPECT_EQ(2u, model_->bookmark_bar_node()->children().size()); Mock::VerifyAndClearExpectations(&observer_); EXPECT_CALL(observer_, BookmarkAllUserNodesRemoved(model_, _)); model_->RemoveAllUserBookmarks(); - EXPECT_EQ(2, managed_->managed_node()->child_count()); - EXPECT_EQ(0, model_->bookmark_bar_node()->child_count()); + EXPECT_EQ(2u, managed_->managed_node()->children().size()); + EXPECT_EQ(0u, model_->bookmark_bar_node()->children().size()); Mock::VerifyAndClearExpectations(&observer_); }
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc index 81ae7d8..f64ddef 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -225,18 +225,14 @@ // Returns the sum of the number of datatypes per host. int GetCookiesTreeModelCount(const CookieTreeNode* root) { int count = 0; - for (int i = 0; i < root->child_count(); i++) { - const CookieTreeNode* node = root->GetChild(i); - EXPECT_GE(node->child_count(), 1); - for (int j = 0; j < node->child_count(); j++) { - const CookieTreeNode* child = node->GetChild(j); - // Quota nodes are not included in the UI due to crbug.com/642955. - if (child->GetDetailedInfo().node_type == - CookieTreeNode::DetailedInfo::TYPE_QUOTA) { - continue; - } - count++; - } + for (const auto& node : root->children()) { + EXPECT_GE(node->children().size(), 1u); + count += std::count_if(node->children().cbegin(), node->children().cend(), + [](const auto& child) { + // TODO(crbug.com/642955): Include quota nodes. + return child->GetDetailedInfo().node_type != + CookieTreeNode::DetailedInfo::TYPE_QUOTA; + }); } return count; } @@ -246,18 +242,13 @@ std::string GetCookiesTreeModelInfo(const CookieTreeNode* root) { std::stringstream info; info << "CookieTreeModel: " << std::endl; - for (int i = 0; i < root->child_count(); i++) { - const CookieTreeNode* node = root->GetChild(i); + for (const auto& node : root->children()) { info << node->GetTitle() << std::endl; - for (int j = 0; j < node->child_count(); j++) { - const CookieTreeNode* child = node->GetChild(j); + for (const auto& child : node->children()) { // Quota nodes are not included in the UI due to crbug.com/642955. - if (child->GetDetailedInfo().node_type == - CookieTreeNode::DetailedInfo::TYPE_QUOTA) { - continue; - } - info << " " << child->GetTitle() << " " - << child->GetDetailedInfo().node_type << std::endl; + const auto node_type = child->GetDetailedInfo().node_type; + if (node_type != CookieTreeNode::DetailedInfo::TYPE_QUOTA) + info << " " << child->GetTitle() << " " << node_type << std::endl; } } return info.str();
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index 72f12cd..7a42e84 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -1571,11 +1571,11 @@ bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model); bookmark_model->AddURL(bookmark_model->bookmark_bar_node(), 0, base::ASCIIToUTF16("a"), bookmarked_page); - EXPECT_EQ(1, bookmark_model->bookmark_bar_node()->child_count()); + EXPECT_EQ(1u, bookmark_model->bookmark_bar_node()->children().size()); BlockUntilBrowsingDataRemoved( base::Time(), base::Time::Max(), ChromeBrowsingDataRemoverDelegate::DATA_TYPE_BOOKMARKS, false); - EXPECT_EQ(0, bookmark_model->bookmark_bar_node()->child_count()); + EXPECT_EQ(0u, bookmark_model->bookmark_bar_node()->children().size()); } // TODO(crbug.com/589586): Disabled, since history is not yet marked as
diff --git a/chrome/browser/browsing_data/cookies_tree_model.cc b/chrome/browser/browsing_data/cookies_tree_model.cc index 35636ff..cb4e8e5 100644 --- a/chrome/browser/browsing_data/cookies_tree_model.cc +++ b/chrome/browser/browsing_data/cookies_tree_model.cc
@@ -9,6 +9,7 @@ #include <algorithm> #include <functional> #include <map> +#include <numeric> #include <utility> #include <vector> @@ -318,11 +319,10 @@ } int CookieTreeNode::NumberOfCookies() const { - int number_of_cookies = 0; - for (int i = 0; i < this->child_count(); ++i) { - number_of_cookies += this->GetChild(i)->NumberOfCookies(); - } - return number_of_cookies; + return std::accumulate(children().cbegin(), children().cend(), 0, + [](int total, const auto& child) { + return total + child->NumberOfCookies(); + }); } void CookieTreeNode::AddChildSortedByTitle( @@ -894,11 +894,10 @@ ~CookieTreeCollectionNode() override {} int64_t InclusiveSize() const final { - int64_t total_size = 0; - for (int i = 0; i < this->child_count(); ++i) { - total_size += this->GetChild(i)->InclusiveSize(); - } - return total_size; + return std::accumulate(children().cbegin(), children().cend(), int64_t{0}, + [](int64_t total, const auto& child) { + return total + child->InclusiveSize(); + }); } private: @@ -1331,11 +1330,10 @@ } int64_t CookieTreeHostNode::InclusiveSize() const { - int64_t total_size = 0; - for (int i = 0; i < this->child_count(); ++i) { - total_size += this->GetChild(i)->InclusiveSize(); - } - return total_size; + return std::accumulate(children().cbegin(), children().cend(), int64_t{0}, + [](int64_t total, const auto& child) { + return total + child->InclusiveSize(); + }); } ///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/browsing_data/cookies_tree_model_unittest.cc b/chrome/browser/browsing_data/cookies_tree_model_unittest.cc index 504f3bb6..a59c3c3 100644 --- a/chrome/browser/browsing_data/cookies_tree_model_unittest.cc +++ b/chrome/browser/browsing_data/cookies_tree_model_unittest.cc
@@ -230,9 +230,8 @@ CookieTreeNode::DetailedInfo::NodeType node_type, content_settings::CookieSettings* cookie_settings, const GURL& expected_url) { - for (int i = 0; i < node->child_count(); ++i) { - const CookieTreeNode* child = node->GetChild(i); - CheckContentSettingsUrlForHostNodes(child, + for (const auto& child : node->children()) { + CheckContentSettingsUrlForHostNodes(child.get(), child->GetDetailedInfo().node_type, cookie_settings, expected_url); } @@ -261,9 +260,8 @@ CookieTreeNode::DetailedInfo::NodeType node_type) { if (!node->children().empty()) { std::string retval; - for (int i = 0; i < node->child_count(); ++i) { - retval += GetNodesOfChildren(node->GetChild(i), node_type); - } + for (const auto& child : node->children()) + retval += GetNodesOfChildren(child.get(), node_type); return retval; } @@ -486,7 +484,7 @@ // 2 nodes - root and app SCOPED_TRACE("After removing"); EXPECT_EQ(1, cookies_model->GetRoot()->GetTotalNodeCount()); - EXPECT_EQ(0, cookies_model->GetRoot()->child_count()); + EXPECT_EQ(0u, cookies_model->GetRoot()->children().size()); EXPECT_EQ(std::string(), GetDisplayedCookies(cookies_model.get())); EXPECT_TRUE(mock_browsing_data_cookie_helper_->AllDeleted()); EXPECT_TRUE(mock_browsing_data_database_helper_->AllDeleted()); @@ -1619,7 +1617,7 @@ CookieTreeHostNode* origin = root->GetOrCreateHostNode(host); - EXPECT_EQ(1, origin->child_count()); + EXPECT_EQ(1u, origin->children().size()); EXPECT_TRUE(origin->CanCreateContentException()); EXPECT_CALL(observer, OnContentSettingsChanged( content_settings, CONTENT_SETTINGS_TYPE_COOKIES,
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index ea14910..0149bfa 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2902,7 +2902,7 @@ } // namespace -void ChromeContentBrowserClient::SelectClientCertificate( +base::OnceClosure ChromeContentBrowserClient::SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs, @@ -2912,7 +2912,7 @@ if (prerender_contents) { prerender_contents->Destroy( prerender::FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED); - return; + return base::OnceClosure(); } GURL requesting_url("https://" + cert_request_info->host_and_port.ToString()); @@ -2948,7 +2948,7 @@ // Continue without client certificate. We do this to mimic the case of no // client certificate being present in the profile's certificate store. delegate->ContinueWithCertificate(nullptr, nullptr); - return; + return base::OnceClosure(); } VLOG(1) << "Client cert requested in sign-in profile."; } @@ -2967,7 +2967,7 @@ &content::ClientCertificateDelegate::ContinueWithCertificate, std::move(delegate), std::move(cert))); LogClientAuthResult(ClientCertSelectionResult::kAutoSelect); - return; + return base::OnceClosure(); } if (!may_show_cert_selection) { @@ -2977,12 +2977,12 @@ // Continue without client certificate. We do this to mimic the case of no // client certificate being present in the profile's certificate store. delegate->ContinueWithCertificate(nullptr, nullptr); - return; + return base::OnceClosure(); } - chrome::ShowSSLClientCertificateSelector(web_contents, cert_request_info, - std::move(client_certs), - std::move(delegate)); + return chrome::ShowSSLClientCertificateSelector( + web_contents, cert_request_info, std::move(client_certs), + std::move(delegate)); } content::MediaObserver* ChromeContentBrowserClient::GetMediaObserver() {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 1d4f95b..02795a8e 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -309,7 +309,7 @@ bool expired_previous_decision, const base::Callback<void(content::CertificateRequestResultType)>& callback) override; - void SelectClientCertificate( + base::OnceClosure SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs,
diff --git a/chrome/browser/chrome_notification_types.h b/chrome/browser/chrome_notification_types.h index 59b253a..10c15de 100644 --- a/chrome/browser/chrome_notification_types.h +++ b/chrome/browser/chrome_notification_types.h
@@ -335,10 +335,6 @@ // The source is the browser's FullscreenController, no details. NOTIFICATION_MOUSE_LOCK_CHANGED, - // Sent by the PluginPrefs when there is a change of plugin enable/disable - // status. The source is the profile. - NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, - // Sent when a global error has changed and the error UI should update it // self. The source is a Source<Profile> containing the profile for the // error. The detail is a GlobalError object that has changed or NULL if
diff --git a/chrome/browser/chromeos/login/auth/auth_prewarmer.cc b/chrome/browser/chromeos/login/auth/auth_prewarmer.cc index 567f8167..6be81f7 100644 --- a/chrome/browser/chromeos/login/auth/auth_prewarmer.cc +++ b/chrome/browser/chromeos/login/auth/auth_prewarmer.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include "base/optional.h" #include "base/task/post_task.h" #include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -66,7 +67,7 @@ if (network_context) { // Do nothing if NetworkContext isn't available. network_context->PreconnectSockets(kConnectionsNeeded, url, kLoadFlags, - kShouldUsePrivacyMode); + kShouldUsePrivacyMode, base::nullopt); } if (!completion_callback_.is_null()) { base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc index 7fd22443..16ec84bf 100644 --- a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc +++ b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
@@ -678,7 +678,7 @@ "legacy", kAdTestUser, "password"); WaitForMessage(&message_queue, "\"ShowADJoinError\""); enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepADJoinError); - test::OobeJS().TapOnPath({kEnrollmentUI, kAdErrorCard, kSubmitButton}); + test::OobeJS().ClickOnPath({kEnrollmentUI, kAdErrorCard, kSubmitButton}); enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepADJoin); }
diff --git a/chrome/browser/chromeos/login/password_change_browsertest.cc b/chrome/browser/chromeos/login/password_change_browsertest.cc index 2768f476..ff00d937 100644 --- a/chrome/browser/chromeos/login/password_change_browsertest.cc +++ b/chrome/browser/chromeos/login/password_change_browsertest.cc
@@ -143,7 +143,7 @@ // Fill out and submit the old password passed to the stub authenticator. test::OobeJS().TypeIntoPath("old user password", {"gaia-password-changed", "oldPasswordInput"}); - test::OobeJS().TapOnPath( + test::OobeJS().ClickOnPath( {"gaia-password-changed", "oldPasswordInputForm", "button"}); // User session should start, and whole OOBE screen is expected to be hidden, @@ -169,7 +169,7 @@ // Fill out and submit the old password passed to the stub authenticator. test::OobeJS().TypeIntoPath("incorrect old user password", {"gaia-password-changed", "oldPasswordInput"}); - test::OobeJS().TapOnPath( + test::OobeJS().ClickOnPath( {"gaia-password-changed", "oldPasswordInputForm", "button"}); // Expect the UI to report failure. @@ -189,7 +189,7 @@ // Submit the correct password. test::OobeJS().TypeIntoPath("old user password", {"gaia-password-changed", "oldPasswordInput"}); - test::OobeJS().TapOnPath( + test::OobeJS().ClickOnPath( {"gaia-password-changed", "oldPasswordInputForm", "button"}); // User session should start, and whole OOBE screen is expected to be hidden, @@ -213,7 +213,7 @@ true, {"gaia-password-changed", "oldPasswordCard"}); // Click forgot password link. - test::OobeJS().TapOnPath({"gaia-password-changed", "forgot-password-link"}); + test::OobeJS().ClickOnPath({"gaia-password-changed", "forgot-password-link"}); test::OobeJS().CreateVisibilityWaiter( false, {"gaia-password-changed", "oldPasswordCard"}); @@ -223,7 +223,7 @@ {"gaia-password-changed", "proceedAnywayBtn"}); // Click "Proceed anyway". - test::OobeJS().TapOnPath({"gaia-password-changed", "proceedAnywayBtn"}); + test::OobeJS().ClickOnPath({"gaia-password-changed", "proceedAnywayBtn"}); // User session should start, and whole OOBE screen is expected to be hidden, OobeWindowVisibilityWaiter(false).Wait(); @@ -246,7 +246,7 @@ true, {"gaia-password-changed", "oldPasswordCard"}); // Click forgot password link. - test::OobeJS().TapOnPath({"gaia-password-changed", "forgot-password-link"}); + test::OobeJS().ClickOnPath({"gaia-password-changed", "forgot-password-link"}); test::OobeJS().CreateVisibilityWaiter( false, {"gaia-password-changed", "oldPasswordCard"}); @@ -256,7 +256,7 @@ {"gaia-password-changed", "proceedAnywayBtn"}); // Go back to old password input by clicking Try Again. - test::OobeJS().TapOnPath({"gaia-password-changed", "try-again-link"}); + test::OobeJS().ClickOnPath({"gaia-password-changed", "try-again-link"}); test::OobeJS().CreateVisibilityWaiter( true, {"gaia-password-changed", "oldPasswordCard"}); @@ -264,7 +264,7 @@ // Enter and submit the correct password. test::OobeJS().TypeIntoPath("old user password", {"gaia-password-changed", "oldPasswordInput"}); - test::OobeJS().TapOnPath( + test::OobeJS().ClickOnPath( {"gaia-password-changed", "oldPasswordInputForm", "button"}); // User session should start, and whole OOBE screen is expected to be hidden, @@ -289,7 +289,7 @@ test::OobeJS().TypeIntoPath("old user password", {"gaia-password-changed", "oldPasswordInput"}); // Click the close button. - test::OobeJS().TapOnPath( + test::OobeJS().ClickOnPath( {"gaia-password-changed", "navigation", "closeButton"}); OobeWindowVisibilityWaiter(false).Wait();
diff --git a/chrome/browser/chromeos/login/test/active_directory_login_mixin.cc b/chrome/browser/chromeos/login/test/active_directory_login_mixin.cc index 63d3a9f6..055988a 100644 --- a/chrome/browser/chromeos/login/test/active_directory_login_mixin.cc +++ b/chrome/browser/chromeos/login/test/active_directory_login_mixin.cc
@@ -228,7 +228,7 @@ {kGaiaSigninId, kAdOfflineAuthId, kAdUserInput}); test::OobeJS().TypeIntoPath( password, {kGaiaSigninId, kAdOfflineAuthId, kAdPasswordInput}); - test::OobeJS().TapOnPath({kGaiaSigninId, kAdOfflineAuthId, kAdCredsButton}); + test::OobeJS().ClickOnPath({kGaiaSigninId, kAdOfflineAuthId, kAdCredsButton}); } // Sets username and password for the Active Directory login and submits it. @@ -242,7 +242,7 @@ {kPasswordChangeId, kAdNewPassword1Input}); test::OobeJS().TypeIntoPath(new_password2, {kPasswordChangeId, kAdNewPassword2Input}); - test::OobeJS().TapOnPath( + test::OobeJS().ClickOnPath( {kPasswordChangeId, kPasswordChangeFormId, kFormButtonId}); }
diff --git a/chrome/browser/chromeos/login/test/enrollment_ui_mixin.cc b/chrome/browser/chromeos/login/test/enrollment_ui_mixin.cc index fcd7be8..b04fce5 100644 --- a/chrome/browser/chromeos/login/test/enrollment_ui_mixin.cc +++ b/chrome/browser/chromeos/login/test/enrollment_ui_mixin.cc
@@ -111,12 +111,12 @@ } void EnrollmentUIMixin::RetryAfterError() { - OobeJS().TapOnPath(kEnrollmentErrorRetryButtonPath); + OobeJS().ClickOnPath(kEnrollmentErrorRetryButtonPath); WaitForStep(ui::kEnrollmentStepSignin); } void EnrollmentUIMixin::LeaveDeviceAttributeErrorScreen() { - OobeJS().TapOnPath(kEnrollmentDeviceAttributesErrorButtonPath); + OobeJS().ClickOnPath(kEnrollmentDeviceAttributesErrorButtonPath); } void EnrollmentUIMixin::SubmitDeviceAttributes(const std::string& asset_id,
diff --git a/chrome/browser/chromeos/login/test/offline_gaia_test_mixin.cc b/chrome/browser/chromeos/login/test/offline_gaia_test_mixin.cc index 63d8bf1c..e99e94cd 100644 --- a/chrome/browser/chromeos/login/test/offline_gaia_test_mixin.cc +++ b/chrome/browser/chromeos/login/test/offline_gaia_test_mixin.cc
@@ -115,7 +115,7 @@ ->Wait(); test::OobeJS().TypeIntoPath(user_email, {"gaia-signin", "offline-gaia", "emailInput"}); - test::OobeJS().TapOnPath( + test::OobeJS().ClickOnPath( {"gaia-signin", "offline-gaia", "email-input-form", "button"}); test::OobeJS() .CreateDisplayedWaiter(false, @@ -127,7 +127,7 @@ ->Wait(); test::OobeJS().TypeIntoPath(password, {"gaia-signin", "offline-gaia", "passwordInput"}); - test::OobeJS().TapOnPath( + test::OobeJS().ClickOnPath( {"gaia-signin", "offline-gaia", "password-input-form", "button"}); }
diff --git a/chrome/browser/chromeos/login/ui/user_adding_screen_browsertest.cc b/chrome/browser/chromeos/login/ui/user_adding_screen_browsertest.cc index 40d339d..b475c08a 100644 --- a/chrome/browser/chromeos/login/ui/user_adding_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/ui/user_adding_screen_browsertest.cc
@@ -258,8 +258,8 @@ StartupUtils::MarkOobeCompleted(); } -// Trying to catch http://crbug.com/362153. -IN_PROC_BROWSER_TEST_F(UserAddingScreenTest, ScreenVisibility) { +// http://crbug.com/978267 +IN_PROC_BROWSER_TEST_F(UserAddingScreenTest, DISABLED_ScreenVisibility) { LoginUser(test_users_[0]); UserAddingScreen::Get()->Start();
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 442f7ee..9ee32ea 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -685,6 +685,7 @@ "suspicious_extension_bubble_delegate.h", "sync_bundle.cc", "sync_bundle.h", + "system_display/display_info_provider.h", "system_display/display_info_provider_chromeos.cc", "system_display/display_info_provider_chromeos.h", "system_display/display_info_provider_mac.cc",
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc index c288b10..42aa452 100644 --- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc +++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
@@ -111,9 +111,8 @@ element.url.reset(new std::string(node.url().spec())); element.title = base::UTF16ToUTF8(node.GetTitle()); - for (int i = 0; i < node.child_count(); ++i) { - element.children.push_back( - CreateNodeDataElementFromBookmarkNode(*node.GetChild(i))); + for (const auto& child : node.children()) { + element.children.push_back(CreateNodeDataElementFromBookmarkNode(*child)); } return element;
diff --git a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.cc b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.cc index 4a0be82..f358ee3 100644 --- a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.cc +++ b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.cc
@@ -93,11 +93,10 @@ if (recurse && node->is_folder()) { std::vector<BookmarkTreeNode> children; - for (int i = 0; i < node->child_count(); ++i) { - const BookmarkNode* child = node->GetChild(i); + for (const auto& child : node->children()) { if (child->IsVisible() && (!only_folders || child->is_folder())) { children.push_back( - GetBookmarkTreeNode(managed, child, true, only_folders)); + GetBookmarkTreeNode(managed, child.get(), true, only_folders)); } } out_bookmark_tree_node->children.reset( @@ -162,9 +161,8 @@ id_to_meta_info_map->Set(base::NumberToString(node.id()), std::move(value)); if (node.is_folder()) { - for (int i = 0; i < node.child_count(); ++i) { - GetMetaInfo(*(node.GetChild(i)), id_to_meta_info_map); - } + for (const auto& child : node.children()) + GetMetaInfo(*child, id_to_meta_info_map); } }
diff --git a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc index b0e8290..81209a9a 100644 --- a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc +++ b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc
@@ -165,10 +165,10 @@ } TEST_F(ExtensionBookmarksTest, RemoveNodeRecursive) { - EXPECT_EQ(3, model_->other_node()->child_count()); + EXPECT_EQ(3u, model_->other_node()->children().size()); std::string error; EXPECT_TRUE(RemoveNode(model_, managed_, folder_->id(), true, &error)); - EXPECT_EQ(2, model_->other_node()->child_count()); + EXPECT_EQ(2u, model_->other_node()->children().size()); } TEST_F(ExtensionBookmarksTest, GetMetaInfo) {
diff --git a/chrome/browser/extensions/api/bookmarks/bookmark_apitest.cc b/chrome/browser/extensions/api/bookmarks/bookmark_apitest.cc index 51335d49..5d4a47c 100644 --- a/chrome/browser/extensions/api/bookmarks/bookmark_apitest.cc +++ b/chrome/browser/extensions/api/bookmarks/bookmark_apitest.cc
@@ -42,7 +42,7 @@ node->Set("children", std::make_unique<base::ListValue>()); list.Append(std::move(node)); profile->GetPrefs()->Set(bookmarks::prefs::kManagedBookmarks, list); - ASSERT_EQ(2, managed->managed_node()->child_count()); + ASSERT_EQ(2u, managed->managed_node()->children().size()); ASSERT_TRUE(RunExtensionTest("bookmarks")) << message_; }
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc index 4545ad2..3ee9269 100644 --- a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc +++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
@@ -357,11 +357,8 @@ BookmarkModel* model, const BookmarkNode* node) { api::bookmarks::OnChildrenReordered::ReorderInfo reorder_info; - int childCount = node->child_count(); - for (int i = 0; i < childCount; ++i) { - const BookmarkNode* child = node->GetChild(i); + for (const auto& child : node->children()) reorder_info.child_ids.push_back(base::NumberToString(child->id())); - } DispatchEvent(events::BOOKMARKS_ON_CHILDREN_REORDERED, api::bookmarks::OnChildrenReordered::kEventName, @@ -458,11 +455,9 @@ return false; std::vector<BookmarkTreeNode> nodes; - int child_count = node->child_count(); - for (int i = 0; i < child_count; ++i) { - const BookmarkNode* child = node->GetChild(i); - bookmark_api_helpers::AddNode(GetManagedBookmarkService(), child, &nodes, - false); + for (const auto& child : node->children()) { + bookmark_api_helpers::AddNode(GetManagedBookmarkService(), child.get(), + &nodes, false); } results_ = api::bookmarks::GetChildren::Results::Create(nodes);
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.cc b/chrome/browser/extensions/api/chrome_extensions_api_client.cc index b90abe9..4e6a70c 100644 --- a/chrome/browser/extensions/api/chrome_extensions_api_client.cc +++ b/chrome/browser/extensions/api/chrome_extensions_api_client.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/extensions/api/storage/sync_value_store_cache.h" #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" #include "chrome/browser/extensions/extension_action_runner.h" +#include "chrome/browser/extensions/system_display/display_info_provider.h" #include "chrome/browser/favicon/favicon_utils.h" #include "chrome/browser/guest_view/app_view/chrome_app_view_guest_delegate.h" #include "chrome/browser/guest_view/chrome_guest_view_manager_delegate.h" @@ -47,6 +48,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" +#include "extensions/browser/api/system_display/display_info_provider.h" #include "extensions/browser/api/virtual_keyboard_private/virtual_keyboard_delegate.h" #include "extensions/browser/api/web_request/web_request_info.h" #include "extensions/browser/extension_registry.h" @@ -283,6 +285,11 @@ return new ChromeManagementAPIDelegate; } +std::unique_ptr<DisplayInfoProvider> +ChromeExtensionsAPIClient::CreateDisplayInfoProvider() const { + return CreateChromeDisplayInfoProvider(); +} + MetricsPrivateDelegate* ChromeExtensionsAPIClient::GetMetricsPrivateDelegate() { if (!metrics_private_delegate_) metrics_private_delegate_.reset(new ChromeMetricsPrivateDelegate());
diff --git a/chrome/browser/extensions/api/chrome_extensions_api_client.h b/chrome/browser/extensions/api/chrome_extensions_api_client.h index 15b684a..5041237 100644 --- a/chrome/browser/extensions/api/chrome_extensions_api_client.h +++ b/chrome/browser/extensions/api/chrome_extensions_api_client.h
@@ -59,6 +59,8 @@ std::unique_ptr<VirtualKeyboardDelegate> CreateVirtualKeyboardDelegate( content::BrowserContext* browser_context) const override; ManagementAPIDelegate* CreateManagementAPIDelegate() const override; + std::unique_ptr<DisplayInfoProvider> CreateDisplayInfoProvider() + const override; MetricsPrivateDelegate* GetMetricsPrivateDelegate() override; NetworkingCastPrivateDelegate* GetNetworkingCastPrivateDelegate() override; FileSystemDelegate* GetFileSystemDelegate() override;
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index a9e024c2..93a67b6 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -16,12 +16,14 @@ #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/extensions/crx_installer.h" +#include "chrome/browser/extensions/extension_action_runner.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/lazy_background_page_test_util.h" #include "chrome/browser/extensions/unpacked_installer.h" #include "chrome/browser/gcm/gcm_profile_service_factory.h" #include "chrome/browser/notifications/notification_display_service_factory.h" +#include "chrome/browser/notifications/notification_display_service_tester.h" #include "chrome/browser/notifications/notification_permission_context.h" #include "chrome/browser/notifications/stub_notification_display_service.h" #include "chrome/browser/permissions/permission_manager.h" @@ -29,6 +31,7 @@ #include "chrome/browser/push_messaging/push_messaging_app_identifier.h" #include "chrome/browser/push_messaging/push_messaging_service_factory.h" #include "chrome/browser/push_messaging/push_messaging_service_impl.h" +#include "chrome/browser/ui/extensions/browser_action_test_util.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/api/web_navigation.h" @@ -67,6 +70,7 @@ #include "extensions/test/test_extension_dir.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "ui/message_center/public/cpp/notification.h" #include "url/url_constants.h" namespace extensions { @@ -279,6 +283,38 @@ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerBasedBackgroundTest); }; +class ServiceWorkerBasedBackgroundTestWithNotification + : public ServiceWorkerBasedBackgroundTest { + public: + ServiceWorkerBasedBackgroundTestWithNotification() {} + ~ServiceWorkerBasedBackgroundTestWithNotification() override = default; + + void SetUpOnMainThread() override { + ServiceWorkerBasedBackgroundTest::SetUpOnMainThread(); + display_service_tester_ = + std::make_unique<NotificationDisplayServiceTester>( + browser()->profile()); + } + + void TearDownOnMainThread() override { + display_service_tester_.reset(); + ServiceWorkerBasedBackgroundTest::TearDownOnMainThread(); + } + + protected: + // Returns a vector with the Notification objects that are being displayed + // by the notification display service. Synchronous. + std::vector<message_center::Notification> GetDisplayedNotifications() const { + return display_service_tester_->GetDisplayedNotificationsForType( + NotificationHandler::Type::WEB_PERSISTENT); + } + + std::unique_ptr<NotificationDisplayServiceTester> display_service_tester_; + + private: + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerBasedBackgroundTestWithNotification); +}; + // Tests that Service Worker based background pages can be loaded and they can // receive extension events. // The extension is installed and loaded during this step and it registers @@ -1836,6 +1872,54 @@ EXPECT_TRUE(worker_filtered_event_listener.WaitUntilSatisfied()); } +// Tests that chrome.browserAction.onClicked sees user gesture. +IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, + BrowserActionUserGesture) { + // First, load |extension| first so that it has browserAction.onClicked + // listener registered. + ExtensionTestMessageListener listener_added("ready", false); + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("service_worker/worker_based_background/" + "browser_action")); + ASSERT_TRUE(extension); + EXPECT_TRUE(listener_added.WaitUntilSatisfied()); + + ResultCatcher catcher; + // Click on browser action to start the test. + { + content::WebContents* web_contents = AddTab(browser(), GURL("about:blank")); + ASSERT_TRUE(web_contents); + ExtensionActionRunner::GetForWebContents( + browser()->tab_strip_model()->GetActiveWebContents()) + ->RunAction(extension, true); + } + EXPECT_TRUE(catcher.GetNextResult()) << message_; +} + +// Tests that Service Worker notification handlers can call extension APIs that +// require user gesture to be present. +IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTestWithNotification, + ServiceWorkerNotificationClick) { + ResultCatcher catcher; + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("service_worker/worker_based_background/" + "notification_click")); + ASSERT_TRUE(extension); + EXPECT_TRUE(catcher.GetNextResult()) << message_; + + // Click on the Service Worker notification. + { + std::vector<message_center::Notification> notifications = + GetDisplayedNotifications(); + ASSERT_EQ(1u, notifications.size()); + display_service_tester_->SimulateClick( + NotificationHandler::Type::WEB_PERSISTENT, notifications[0].id(), + base::nullopt, base::nullopt); + } + + EXPECT_TRUE(catcher.GetNextResult()) << message_; +} + // Tests that console messages logged by extension service workers, both via // the typical console.* methods and via our custom bindings console, are // passed through the normal ServiceWorker console messaging and are
diff --git a/chrome/browser/extensions/system_display/display_info_provider.h b/chrome/browser/extensions/system_display/display_info_provider.h new file mode 100644 index 0000000..5e446e5 --- /dev/null +++ b/chrome/browser/extensions/system_display/display_info_provider.h
@@ -0,0 +1,19 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_H_ +#define CHROME_BROWSER_EXTENSIONS_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_H_ + +#include <memory> + +namespace extensions { + +class DisplayInfoProvider; + +// Returns platform-specific DisplayInfoProvider instance. +std::unique_ptr<DisplayInfoProvider> CreateChromeDisplayInfoProvider(); + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_H_
diff --git a/chrome/browser/extensions/system_display/display_info_provider_aura.cc b/chrome/browser/extensions/system_display/display_info_provider_aura.cc index e502558..823f5a3ba 100644 --- a/chrome/browser/extensions/system_display/display_info_provider_aura.cc +++ b/chrome/browser/extensions/system_display/display_info_provider_aura.cc
@@ -4,13 +4,14 @@ #include "chrome/browser/extensions/system_display/display_info_provider_aura.h" +#include "chrome/browser/extensions/system_display/display_info_provider.h" + namespace extensions { DisplayInfoProviderAura::DisplayInfoProviderAura() = default; -// static -DisplayInfoProvider* DisplayInfoProvider::Create() { - return new DisplayInfoProviderAura(); +std::unique_ptr<DisplayInfoProvider> CreateChromeDisplayInfoProvider() { + return std::make_unique<DisplayInfoProviderAura>(); } } // namespace extensions
diff --git a/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc b/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc index a14bfc5..a3d7072 100644 --- a/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc +++ b/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc
@@ -13,6 +13,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" +#include "chrome/browser/extensions/system_display/display_info_provider.h" #include "chrome/browser/ui/ash/tablet_mode_client.h" #include "content/public/browser/system_connector.h" #include "extensions/common/api/system_display.h" @@ -621,9 +622,9 @@ DispatchOnDisplayChangedEvent(); } -// static -DisplayInfoProvider* DisplayInfoProvider::Create() { - return new DisplayInfoProviderChromeOS(content::GetSystemConnector()); +std::unique_ptr<DisplayInfoProvider> CreateChromeDisplayInfoProvider() { + return std::make_unique<DisplayInfoProviderChromeOS>( + content::GetSystemConnector()); } } // namespace extensions
diff --git a/chrome/browser/extensions/system_display/display_info_provider_mac.cc b/chrome/browser/extensions/system_display/display_info_provider_mac.cc index ba19257f..ae9f5ed 100644 --- a/chrome/browser/extensions/system_display/display_info_provider_mac.cc +++ b/chrome/browser/extensions/system_display/display_info_provider_mac.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/extensions/system_display/display_info_provider_mac.h" #include "base/logging.h" +#include "chrome/browser/extensions/system_display/display_info_provider.h" namespace extensions { @@ -16,9 +17,8 @@ NOTIMPLEMENTED_LOG_ONCE(); } -// static -DisplayInfoProvider* DisplayInfoProvider::Create() { - return new DisplayInfoProviderMac(); +std::unique_ptr<DisplayInfoProvider> CreateChromeDisplayInfoProvider() { + return std::make_unique<DisplayInfoProviderMac>(); } } // namespace extensions
diff --git a/chrome/browser/extensions/system_display/display_info_provider_win.cc b/chrome/browser/extensions/system_display/display_info_provider_win.cc index e71556d..917dad1 100644 --- a/chrome/browser/extensions/system_display/display_info_provider_win.cc +++ b/chrome/browser/extensions/system_display/display_info_provider_win.cc
@@ -11,6 +11,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/win/win_util.h" +#include "chrome/browser/extensions/system_display/display_info_provider.h" #include "extensions/common/api/system_display.h" #include "ui/display/display.h" #include "ui/display/win/dpi.h" @@ -72,9 +73,8 @@ } } -// static -DisplayInfoProvider* DisplayInfoProvider::Create() { - return new DisplayInfoProviderWin(); +std::unique_ptr<DisplayInfoProvider> CreateChromeDisplayInfoProvider() { + return std::make_unique<DisplayInfoProviderWin>(); } } // namespace extensions
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 8c11379..8ee2c512 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -766,6 +766,11 @@ "expiry_milestone": 78 }, { + "name": "enable-search-box-selection", + "owners": [ "ginko", "newcomer" ], + "expiry_milestone": 78 + }, + { "name": "enable-app-list-search-autocomplete", "owners": [ "newcomer" ], "expiry_milestone": 75 @@ -831,6 +836,11 @@ "expiry_milestone": 76 }, { + "name": "enable-aura-tooltips-on-windows", + "owners": [ "cliffsmo" ], + "expiry_milestone": 78 + }, + { "name": "enable-autofill-account-wallet-storage", "owners": [ "feuunk", "butter-team@google.com" ], "expiry_milestone": 76 @@ -1073,6 +1083,11 @@ "expiry_milestone": 78 }, { + "name": "enable-experimental-accessibility-switch-access-text", + "owners": [ "anastasi@google.com", "//ui/accessibility/OWNERS" ], + "expiry_milestone": 80 + }, + { "name": "enable-experimental-accessibility-autoclick", "owners": [ "katie", "dmazzoni", "dtseng" ], "expiry_milestone": 78
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 63cf00f..8827816 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -771,11 +771,6 @@ "Enable language detection for in-page content which is then exposed to " "accessiblity technologies such as screen readers."; -const char kExperimentalAccessibilitySwitchAccessName[] = - "Experimental feature Switch Access"; -const char kExperimentalAccessibilitySwitchAccessDescription[] = - "Add a setting to enable the prototype of Switch Access"; - const char kVizDisplayCompositorName[] = "Viz Display Compositor (OOP-D)"; const char kVizDisplayCompositorDescription[] = "If enabled, the display compositor runs as part of the viz service in the" @@ -2762,6 +2757,11 @@ "Enables the use of an AppContainer on sandboxed processes to improve " "security."; +const char kEnableAuraTooltipsOnWindowsName[] = + "Enable aura tooltips on Windows"; +const char kEnableAuraTooltipsOnWindowsDescription[] = + "Enables aura tooltips instead of the native comctl32 tooltips on Windows."; + const char kEnableGpuAppcontainerName[] = "Enable GPU AppContainer Lockdown."; const char kEnableGpuAppcontainerDescription[] = "Enables the use of an AppContainer for the GPU sandboxed processes to " @@ -3027,6 +3027,11 @@ const char kEnableAppGridGhostDescription[] = "Enables ghosting during an item drag in launcher."; +const char kEnableSearchBoxSelectionName[] = "Search Box Selection"; +const char kEnableSearchBoxSelectionDescription[] = + "Enables the ResultSelectionController in the Search Box. This alters " + "perceived focus traversal."; + const char kEnableAppListSearchAutocompleteName[] = "App List Search Autocomplete"; const char kEnableAppListSearchAutocompleteDescription[] = @@ -3139,6 +3144,17 @@ "Enable ChromeVox rich text indication, which automatically notifies the " "user of text styling."; +const char kExperimentalAccessibilitySwitchAccessName[] = + "Experimental feature Switch Access"; +const char kExperimentalAccessibilitySwitchAccessDescription[] = + "Add a setting to enable the prototype of Switch Access"; + +const char kExperimentalAccessibilitySwitchAccessTextName[] = + "Enable enhanced Switch Access text input."; +const char kExperimentalAccessibilitySwitchAccessTextDescription[] = + "Enable experimental or in-progress Switch Access features for improved " + "text input"; + const char kFileManagerFeedbackPanelDescription[] = "Enable feedback panel in the Files app."; const char kFileManagerFeedbackPanelName[] = "Files App. feedback panel";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index a78f28f..1eddd0c 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -197,9 +197,6 @@ extern const char kExperimentalAccessibilityLanguageDetectionName[]; extern const char kExperimentalAccessibilityLanguageDetectionDescription[]; -extern const char kExperimentalAccessibilitySwitchAccessName[]; -extern const char kExperimentalAccessibilitySwitchAccessDescription[]; - extern const char kFCMInvalidationsName[]; extern const char kFCMInvalidationsDescription[]; @@ -1626,6 +1623,9 @@ extern const char kEnableAppcontainerName[]; extern const char kEnableAppcontainerDescription[]; +extern const char kEnableAuraTooltipsOnWindowsName[]; +extern const char kEnableAuraTooltipsOnWindowsDescription[]; + extern const char kEnableGpuAppcontainerName[]; extern const char kEnableGpuAppcontainerDescription[]; @@ -1803,6 +1803,9 @@ extern const char kEnableAppGridGhostName[]; extern const char kEnableAppGridGhostDescription[]; +extern const char kEnableSearchBoxSelectionName[]; +extern const char kEnableSearchBoxSelectionDescription[]; + extern const char kEnableAppListSearchAutocompleteName[]; extern const char kEnableAppListSearchAutocompleteDescription[]; @@ -1874,6 +1877,12 @@ extern const char kExperimentalAccessibilityChromeVoxRichTextIndicationDescription[]; +extern const char kExperimentalAccessibilitySwitchAccessName[]; +extern const char kExperimentalAccessibilitySwitchAccessDescription[]; + +extern const char kExperimentalAccessibilitySwitchAccessTextName[]; +extern const char kExperimentalAccessibilitySwitchAccessTextDescription[]; + extern const char kFileManagerFeedbackPanelDescription[]; extern const char kFileManagerFeedbackPanelName[];
diff --git a/chrome/browser/history/android/android_provider_backend_unittest.cc b/chrome/browser/history/android/android_provider_backend_unittest.cc index 23852bd..5d97f4b 100644 --- a/chrome/browser/history/android/android_provider_backend_unittest.cc +++ b/chrome/browser/history/android/android_provider_backend_unittest.cc
@@ -575,7 +575,7 @@ (*notifier_.modified_details())[0].title()); EXPECT_FALSE(notifier_.favicon_changed()); content::RunAllPendingInMessageLoop(); - ASSERT_EQ(1, bookmark_model_->mobile_node()->child_count()); + ASSERT_EQ(1u, bookmark_model_->mobile_node()->children().size()); const BookmarkNode* child = bookmark_model_->mobile_node()->GetChild(0); ASSERT_TRUE(child); EXPECT_EQ(row1.title(), child->GetTitle()); @@ -675,7 +675,7 @@ ASSERT_TRUE(backend->InsertHistoryAndBookmark(row2)); // Verify the row1 has been added in bookmark model. content::RunAllPendingInMessageLoop(); - ASSERT_EQ(1, bookmark_model_->mobile_node()->child_count()); + ASSERT_EQ(1u, bookmark_model_->mobile_node()->children().size()); const BookmarkNode* child = bookmark_model_->mobile_node()->GetChild(0); ASSERT_TRUE(child); EXPECT_EQ(row1.title(), child->GetTitle()); @@ -690,7 +690,7 @@ EXPECT_EQ(1, deleted_count); // Verify the row1 was removed from bookmark model. content::RunAllPendingInMessageLoop(); - ASSERT_EQ(0, bookmark_model_->mobile_node()->child_count()); + ASSERT_EQ(0u, bookmark_model_->mobile_node()->children().size()); // Verify notifications ASSERT_TRUE(notifier_.deleted_details()); @@ -865,7 +865,7 @@ // Verify the row1 has been added in bookmark model. content::RunAllPendingInMessageLoop(); - ASSERT_EQ(1, bookmark_model_->mobile_node()->child_count()); + ASSERT_EQ(1u, bookmark_model_->mobile_node()->children().size()); const BookmarkNode* child = bookmark_model_->mobile_node()->GetChild(0); ASSERT_TRUE(child); EXPECT_EQ(row1.title(), child->GetTitle()); @@ -942,7 +942,7 @@ // Verify the bookmark model was updated. content::RunAllPendingInMessageLoop(); - ASSERT_EQ(1, bookmark_model_->mobile_node()->child_count()); + ASSERT_EQ(1u, bookmark_model_->mobile_node()->children().size()); const BookmarkNode* child1 = bookmark_model_->mobile_node()->GetChild(0); ASSERT_TRUE(child1); EXPECT_EQ(row1.title(), child1->GetTitle()); @@ -1626,7 +1626,7 @@ // Verify the row1 has been added in bookmark model. content::RunAllPendingInMessageLoop(); - ASSERT_EQ(1, bookmark_model_->mobile_node()->child_count()); + ASSERT_EQ(1u, bookmark_model_->mobile_node()->children().size()); const BookmarkNode* child = bookmark_model_->mobile_node()->GetChild(0); ASSERT_TRUE(child); EXPECT_EQ(row1.title(), child->GetTitle()); @@ -1649,7 +1649,7 @@ // Verify the row1 is still in bookmark model. content::RunAllPendingInMessageLoop(); - ASSERT_EQ(1, bookmark_model_->mobile_node()->child_count()); + ASSERT_EQ(1u, bookmark_model_->mobile_node()->children().size()); const BookmarkNode* child1 = bookmark_model_->mobile_node()->GetChild(0); ASSERT_TRUE(child1); EXPECT_EQ(row1.title(), child1->GetTitle()); @@ -1951,7 +1951,7 @@ (*notifier_.modified_details())[0].title()); EXPECT_FALSE(notifier_.favicon_changed()); content::RunAllPendingInMessageLoop(); - ASSERT_EQ(1, bookmark_model_->mobile_node()->child_count()); + ASSERT_EQ(1u, bookmark_model_->mobile_node()->children().size()); const BookmarkNode* child = bookmark_model_->mobile_node()->GetChild(0); ASSERT_TRUE(child); EXPECT_EQ(row1.title(), child->GetTitle()); @@ -2006,7 +2006,7 @@ ASSERT_TRUE(backend->InsertHistoryAndBookmark(row2)); // Verify the row1 has been added in bookmark model. content::RunAllPendingInMessageLoop(); - ASSERT_EQ(1, bookmark_model_->mobile_node()->child_count()); + ASSERT_EQ(1u, bookmark_model_->mobile_node()->children().size()); const BookmarkNode* child = bookmark_model_->mobile_node()->GetChild(0); ASSERT_TRUE(child); EXPECT_EQ(row1.title(), child->GetTitle()); @@ -2027,7 +2027,7 @@ EXPECT_EQ(2, deleted_count); // Verify the rows was removed from bookmark model. content::RunAllPendingInMessageLoop(); - ASSERT_EQ(0, bookmark_model_->mobile_node()->child_count()); + ASSERT_EQ(0u, bookmark_model_->mobile_node()->children().size()); // Verify notifications ASSERT_TRUE(notifier_.deleted_details());
diff --git a/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc b/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc index dc643c5..ade5d51 100644 --- a/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc +++ b/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc
@@ -228,8 +228,8 @@ ASSERT_TRUE(handler.Insert(&row)); RunMessageLoopForUI(); // Get all bookmarks and verify there are 3 bookmarks. - EXPECT_EQ(1, bookmark_model_->mobile_node()->child_count()); - EXPECT_EQ(2, bookmark_model_->other_node()->child_count()); + EXPECT_EQ(1u, bookmark_model_->mobile_node()->children().size()); + EXPECT_EQ(2u, bookmark_model_->other_node()->children().size()); // Remove the third one. TableIDRow id_row; @@ -240,8 +240,8 @@ ASSERT_TRUE(handler.Delete(id_rows)); RunMessageLoopForUI(); // Verify the first 2 bookmarks still exist. - EXPECT_EQ(1, bookmark_model_->mobile_node()->child_count()); - EXPECT_EQ(1, bookmark_model_->other_node()->child_count()); + EXPECT_EQ(1u, bookmark_model_->mobile_node()->children().size()); + EXPECT_EQ(1u, bookmark_model_->other_node()->children().size()); id_row.url = url1; id_rows.clear();
diff --git a/chrome/browser/importer/profile_writer.cc b/chrome/browser/importer/profile_writer.cc index 275d348..2200c8a 100644 --- a/chrome/browser/importer/profile_writer.cc +++ b/chrome/browser/importer/profile_writer.cc
@@ -47,8 +47,7 @@ // Build a set containing the bookmark bar folder names. std::set<base::string16> existing_folder_names; const BookmarkNode* bookmark_bar = model->bookmark_bar_node(); - for (int i = 0; i < bookmark_bar->child_count(); ++i) { - const BookmarkNode* node = bookmark_bar->GetChild(i); + for (const auto& node : bookmark_bar->children()) { if (node->is_folder()) existing_folder_names.insert(node->GetTitle()); } @@ -188,19 +187,15 @@ continue; } - const BookmarkNode* child = NULL; - for (int index = 0; index < parent->child_count(); ++index) { - const BookmarkNode* node = parent->GetChild(index); - if (node->is_folder() && node->GetTitle() == *folder_name) { - child = node; - break; - } - } - if (!child) { - child = - model->AddFolder(parent, parent->children().size(), *folder_name); - } - parent = child; + const auto it = std::find_if( + parent->children().cbegin(), parent->children().cend(), + [folder_name](const auto& node) { + return node->is_folder() && node->GetTitle() == *folder_name; + }); + parent = (it == parent->children().cend()) + ? model->AddFolder(parent, parent->children().size(), + *folder_name) + : it->get(); } folders_added_to.insert(parent);
diff --git a/chrome/browser/interstitials/enterprise_util.cc b/chrome/browser/interstitials/enterprise_util.cc index 6098f26..1acb33d 100644 --- a/chrome/browser/interstitials/enterprise_util.cc +++ b/chrome/browser/interstitials/enterprise_util.cc
@@ -84,6 +84,7 @@ case safe_browsing::SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE: case safe_browsing::SB_THREAT_TYPE_AD_SAMPLE: case safe_browsing::SB_THREAT_TYPE_BLOCKED_AD_POPUP: + case safe_browsing::SB_THREAT_TYPE_BLOCKED_AD_REDIRECT: case safe_browsing::SB_THREAT_TYPE_SUSPICIOUS_SITE: case safe_browsing::SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE: case safe_browsing::SB_THREAT_TYPE_APK_DOWNLOAD:
diff --git a/chrome/browser/metrics/perf/perf_events_collector.cc b/chrome/browser/metrics/perf/perf_events_collector.cc index 2b97998..1e943d7a 100644 --- a/chrome/browser/metrics/perf/perf_events_collector.cc +++ b/chrome/browser/metrics/perf/perf_events_collector.cc
@@ -392,6 +392,22 @@ return PerfProtoType::PERF_TYPE_UNSUPPORTED; } +void PerfCollector::OnPerfOutputComplete( + std::unique_ptr<WindowedIncognitoObserver> incognito_observer, + std::unique_ptr<SampledProfile> sampled_profile, + PerfProtoType type, + bool has_cycles, + std::string perf_stdout) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // We are done using |perf_output_call_| and may destroy it. + perf_output_call_ = nullptr; + + ParseOutputProtoIfValid(std::move(incognito_observer), + std::move(sampled_profile), type, has_cycles, + perf_stdout); +} + void PerfCollector::ParseOutputProtoIfValid( std::unique_ptr<WindowedIncognitoObserver> incognito_observer, std::unique_ptr<SampledProfile> sampled_profile, @@ -400,10 +416,6 @@ const std::string& perf_stdout) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // |perf_output_call_| called us, and owns |perf_stdout|. We must delete it, - // but not before parsing |perf_stdout|, and we may return early. - std::unique_ptr<PerfOutputCall> call_deleter(std::move(perf_output_call_)); - if (incognito_observer->incognito_launched()) { AddToUmaHistogram(CollectionAttemptStatus::INCOGNITO_LAUNCHED); return; @@ -481,7 +493,7 @@ perf_output_call_ = std::make_unique<PerfOutputCall>( collection_params_.collection_duration, command, - base::BindOnce(&PerfCollector::ParseOutputProtoIfValid, + base::BindOnce(&PerfCollector::OnPerfOutputComplete, weak_factory_.GetWeakPtr(), std::move(incognito_observer), std::move(sampled_profile), type, has_cycles)); }
diff --git a/chrome/browser/metrics/perf/perf_events_collector.h b/chrome/browser/metrics/perf/perf_events_collector.h index aadf0fa..d2a0db8d 100644 --- a/chrome/browser/metrics/perf/perf_events_collector.h +++ b/chrome/browser/metrics/perf/perf_events_collector.h
@@ -35,6 +35,13 @@ // arguments, starting with "perf" itself in |args[0]|. static PerfProtoType GetPerfProtoType(const std::vector<std::string>& args); + void OnPerfOutputComplete( + std::unique_ptr<WindowedIncognitoObserver> incognito_observer, + std::unique_ptr<SampledProfile> sampled_profile, + PerfProtoType type, + bool has_cycles, + std::string perf_stdout); + // Parses a PerfDataProto or PerfStatProto from serialized data |perf_stdout|, // if non-empty. Which proto to use depends on |subcommand|. If |perf_stdout| // is empty, it is counted as an error. |incognito_observer| indicates
diff --git a/chrome/browser/metrics/perf/perf_output.cc b/chrome/browser/metrics/perf/perf_output.cc index 02374734..53f2c51c8 100644 --- a/chrome/browser/metrics/perf/perf_output.cc +++ b/chrome/browser/metrics/perf/perf_output.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/metrics/perf/perf_output.h" #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/task/post_task.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/debug_daemon_client.h" @@ -17,6 +18,7 @@ : duration_(duration), perf_args_(perf_args), done_callback_(std::move(callback)), + pending_stop_(false), weak_factory_(this) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -36,10 +38,27 @@ PerfOutputCall::~PerfOutputCall() {} +void PerfOutputCall::Stop() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + if (!perf_session_id_) { + // GetPerfOutputFd hasn't returned the session ID yet. Mark that Stop() has + // been called. StopImpl() will be delayed until we receive the session ID. + pending_stop_ = true; + return; + } + + StopImpl(); +} + void PerfOutputCall::OnIOComplete(base::Optional<std::string> result) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + perf_data_pipe_reader_.reset(); - std::move(done_callback_).Run(result.value_or(std::string())); + // Use the r-value variant of base::Optional::value_or() to move |result| to + // the callback argument. Callback can safely use |result| after |this| is + // deleted. + std::move(done_callback_).Run(std::move(result).value_or(std::string())); // The callback may delete us, so it's hammertime: Can't touch |this|. } @@ -51,6 +70,22 @@ perf_data_pipe_reader_.reset(); std::move(done_callback_).Run(std::string()); } + + // DBus method GetPerfOutputFd returns a generated session ID back to the + // caller. The session ID will be used in stopping the existing perf session. + perf_session_id_ = result; + if (pending_stop_) { + // Stop() is called before GetPerfOutputFd returns the session ID. We can + // invoke the StopPerf DBus method now. + StopImpl(); + } +} + +void PerfOutputCall::StopImpl() { + DCHECK(perf_session_id_); + chromeos::DebugDaemonClient* client = + chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); + client->StopPerf(*perf_session_id_, base::DoNothing()); } } // namespace metrics
diff --git a/chrome/browser/metrics/perf/perf_output.h b/chrome/browser/metrics/perf/perf_output.h index ec6d9a06..089f9777c 100644 --- a/chrome/browser/metrics/perf/perf_output.h +++ b/chrome/browser/metrics/perf/perf_output.h
@@ -28,18 +28,24 @@ // - Output from "perf record", in PerfDataProto format, OR // - Output from "perf stat", in PerfStatProto format, OR // - The empty string if there was an error. - using DoneCallback = base::OnceCallback<void(const std::string& perf_stdout)>; + // The output is transferred to |perf_stdout|. + using DoneCallback = base::OnceCallback<void(std::string perf_stdout)>; PerfOutputCall(base::TimeDelta duration, const std::vector<std::string>& perf_args, DoneCallback callback); - ~PerfOutputCall(); + virtual ~PerfOutputCall(); + + // Stop() is made virtual for mocks in testing. + virtual void Stop(); private: // Internal callbacks. void OnIOComplete(base::Optional<std::string> data); void OnGetPerfOutput(base::Optional<uint64_t> result); + void StopImpl(); + // Used to capture perf data written to a pipe. std::unique_ptr<chromeos::PipeReader> perf_data_pipe_reader_; @@ -48,6 +54,13 @@ std::vector<std::string> perf_args_; DoneCallback done_callback_; + // Whether Stop() is called before OnGetPerfOutput() has returned the session + // ID. If true (meaning Stop() is called very soon after we request perf + // output), the stop request will be sent out after we have the session ID to + // stop the perf session. + bool pending_stop_; + base::Optional<uint64_t> perf_session_id_; + THREAD_CHECKER(thread_checker_); // To pass around the "this" pointer across threads safely.
diff --git a/chrome/browser/notifications/scheduler/internal/notification_scheduler.cc b/chrome/browser/notifications/scheduler/internal/notification_scheduler.cc index cbdb641..3c15e9ac 100644 --- a/chrome/browser/notifications/scheduler/internal/notification_scheduler.cc +++ b/chrome/browser/notifications/scheduler/internal/notification_scheduler.cc
@@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" +#include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/notifications/scheduler/internal/background_task_coordinator.h" #include "chrome/browser/notifications/scheduler/internal/display_decider.h" #include "chrome/browser/notifications/scheduler/internal/distribution_policy.h" @@ -132,9 +133,34 @@ void OnInitialized(std::unique_ptr<InitHelper>, InitCallback init_callback, bool success) { - // TODO(xingliu): Inform the clients about initialization results and tear - // down internal components. + // TODO(xingliu): Tear down internal components if initialization failed. std::move(init_callback).Run(success); + NotifyClientsAfterInit(success); + } + + void NotifyClientsAfterInit(bool success) { + std::vector<SchedulerClientType> clients; + context_->client_registrar()->GetRegisteredClients(&clients); + for (auto type : clients) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&NotificationSchedulerImpl::NotifyClientAfterInit, + weak_ptr_factory_.GetWeakPtr(), type, success)); + } + } + + void NotifyClientAfterInit(SchedulerClientType type, bool success) { + std::vector<const NotificationEntry*> notifications; + context_->notification_manager()->GetNotifications(type, ¬ifications); + std::set<std::string> guids; + for (const auto* notification : notifications) { + DCHECK(notification); + guids.emplace(notification->guid); + } + + auto* client = context_->client_registrar()->GetClient(type); + DCHECK(client); + client->OnSchedulerInitialized(success, std::move(guids)); } // NotificationBackgroundTaskScheduler::Handler implementation. @@ -184,8 +210,6 @@ task_start_time, std::move(notifications), std::move(client_states), &results); - // TODO(xingliu): Update impression data after notification shown. - // See https://crbug.com/965133. for (const auto& guid : results) { context_->notification_manager()->DisplayNotification(guid); }
diff --git a/chrome/browser/notifications/scheduler/internal/webui_client.cc b/chrome/browser/notifications/scheduler/internal/webui_client.cc index 5cc401e..9543f028 100644 --- a/chrome/browser/notifications/scheduler/internal/webui_client.cc +++ b/chrome/browser/notifications/scheduler/internal/webui_client.cc
@@ -12,7 +12,7 @@ WebUIClient::~WebUIClient() = default; -void WebUIClient::ShowNotification( +void WebUIClient::BeforeShowNotification( std::unique_ptr<NotificationData> notification_data, NotificationDataCallback callback) { NOTIMPLEMENTED();
diff --git a/chrome/browser/notifications/scheduler/internal/webui_client.h b/chrome/browser/notifications/scheduler/internal/webui_client.h index a5936e5e..d57540c 100644 --- a/chrome/browser/notifications/scheduler/internal/webui_client.h +++ b/chrome/browser/notifications/scheduler/internal/webui_client.h
@@ -21,8 +21,9 @@ private: // NotificationSchedulerClient implementation. - void ShowNotification(std::unique_ptr<NotificationData> notification_data, - NotificationDataCallback callback) override; + void BeforeShowNotification( + std::unique_ptr<NotificationData> notification_data, + NotificationDataCallback callback) override; void OnSchedulerInitialized(bool success, std::set<std::string> guids) override; void OnUserAction(UserActionType action_type,
diff --git a/chrome/browser/notifications/scheduler/public/notification_scheduler_client.h b/chrome/browser/notifications/scheduler/public/notification_scheduler_client.h index a653d0de..b1b7359 100644 --- a/chrome/browser/notifications/scheduler/public/notification_scheduler_client.h +++ b/chrome/browser/notifications/scheduler/public/notification_scheduler_client.h
@@ -22,35 +22,16 @@ // The client interface to receive events from notification scheduler. class NotificationSchedulerClient { public: - // Defines user actions type. - enum class UserActionType { - // The user clicks on the notification body. - kClick = 0, - // The user clicks on the notification button. - kButtonClick = 1, - // The user dismisses the notification. - kDismiss = 2, - }; - - // Information about button clicks. - struct ButtonClickInfo { - // Unique id of the button. - std::string button_id; - - // Associate impression type for the button. - ActionButtonType type = ActionButtonType::kUnknownAction; - }; - using NotificationDataCallback = base::OnceCallback<void(std::unique_ptr<NotificationData>)>; NotificationSchedulerClient() = default; virtual ~NotificationSchedulerClient() = default; - // Called when the notification should be displayed to the user. The clients + // Called before the notification should be displayed to the user. The clients // can overwrite data in |notification_data| and return the updated data in // |callback|. - virtual void ShowNotification( + virtual void BeforeShowNotification( std::unique_ptr<NotificationData> notification_data, NotificationDataCallback callback) = 0;
diff --git a/chrome/browser/notifications/scheduler/public/notification_scheduler_types.h b/chrome/browser/notifications/scheduler/public/notification_scheduler_types.h index 7c7a59d..959fb2a 100644 --- a/chrome/browser/notifications/scheduler/public/notification_scheduler_types.h +++ b/chrome/browser/notifications/scheduler/public/notification_scheduler_types.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_PUBLIC_NOTIFICATION_SCHEDULER_TYPES_H_ #define CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_PUBLIC_NOTIFICATION_SCHEDULER_TYPES_H_ +#include <string> + namespace notifications { // Enum to describe the time to process scheduled notification data. @@ -68,6 +70,16 @@ kMaxValue = kNeutral }; +// Defines user actions type. +enum class UserActionType { + // The user clicks on the notification body. + kClick = 0, + // The user clicks on the notification button. + kButtonClick = 1, + // The user dismisses the notification. + kDismiss = 2, +}; + // Categorizes type of notification buttons. Different type of button clicks // may result in change of notification shown frequency. enum class ActionButtonType { @@ -81,6 +93,15 @@ kUnhelpful = 2, }; +// Information about button clicks. +struct ButtonClickInfo { + // Unique id of the button. + std::string button_id; + + // Associate impression type for the button. + ActionButtonType type = ActionButtonType::kUnknownAction; +}; + } // namespace notifications #endif // CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_PUBLIC_NOTIFICATION_SCHEDULER_TYPES_H_
diff --git a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer.cc index 1ffbc77..53387233f 100644 --- a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer.cc
@@ -90,6 +90,7 @@ DataReductionProxyMetricsObserver::FlushMetricsOnAppEnterBackground( const page_load_metrics::mojom::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info) { + LOG(ERROR) << "FlushMetricsOnAppEnterBackground " << info.url; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // FlushMetricsOnAppEnterBackground is invoked on Android in cases where the // app is about to be backgrounded, as part of the Activity.onPause() @@ -105,6 +106,7 @@ void DataReductionProxyMetricsObserver::OnComplete( const page_load_metrics::mojom::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info) { + LOG(ERROR) << "OnComplete " << info.url; DataReductionProxyMetricsObserverBase::OnComplete(timing, info); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); RecordPageSizeUMA();
diff --git a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.cc b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.cc index 5f1bff1..fc70152 100644 --- a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.cc +++ b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.cc
@@ -267,6 +267,7 @@ const page_load_metrics::mojom::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info, bool app_background_occurred) { + LOG(ERROR) << "send pingback"; // TODO(ryansturm): Move to OnFirstBackgroundEvent to handle some fast // shutdown cases. crbug.com/618072 if (!browser_context_ || !data_)
diff --git a/chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.cc b/chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.cc index 4e1e4b9..60140a61 100644 --- a/chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.cc +++ b/chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.cc
@@ -45,7 +45,8 @@ const uint64_t& candidate_new_size) { DCHECK(inout_timing); const ContentfulPaintTimingInfo new_candidate( - candidate_new_time, candidate_new_size, inout_timing->Type()); + candidate_new_time, candidate_new_size, inout_timing->Type(), + inout_timing->InMainFrame()); const ContentfulPaintTimingInfo& merged_candidate = MergeTimingsBySizeAndTime(new_candidate, *inout_timing); inout_timing->Reset(merged_candidate.Time(), merged_candidate.Size()); @@ -70,13 +71,18 @@ } // namespace ContentfulPaintTimingInfo::ContentfulPaintTimingInfo( - PageLoadMetricsObserver::LargestContentType type) - : time_(base::Optional<base::TimeDelta>()), size_(0), type_(type) {} + PageLoadMetricsObserver::LargestContentType type, + bool in_main_frame) + : time_(base::Optional<base::TimeDelta>()), + size_(0), + type_(type), + in_main_frame_(in_main_frame) {} ContentfulPaintTimingInfo::ContentfulPaintTimingInfo( const base::Optional<base::TimeDelta>& time, const uint64_t& size, - const page_load_metrics::PageLoadMetricsObserver::LargestContentType type) - : time_(time), size_(size), type_(type) {} + const page_load_metrics::PageLoadMetricsObserver::LargestContentType type, + bool in_main_frame) + : time_(time), size_(size), type_(type), in_main_frame_(in_main_frame) {} ContentfulPaintTimingInfo::ContentfulPaintTimingInfo( const ContentfulPaintTimingInfo& other) = default; @@ -88,6 +94,7 @@ data->SetInteger("durationInMilliseconds", time_.value().InMilliseconds()); data->SetInteger("size", size_); data->SetString("type", TypeInString()); + data->SetBoolean("inMainFrame", InMainFrame()); return data; } @@ -115,15 +122,19 @@ time_ = time; } -ContentfulPaint::ContentfulPaint() - : text_(PageLoadMetricsObserver::LargestContentType::kText), - image_(PageLoadMetricsObserver::LargestContentType::kImage) {} +ContentfulPaint::ContentfulPaint(bool in_main_frame) + : text_(PageLoadMetricsObserver::LargestContentType::kText, in_main_frame), + image_(PageLoadMetricsObserver::LargestContentType::kImage, + in_main_frame) {} const ContentfulPaintTimingInfo& ContentfulPaint::MergeTextAndImageTiming() { return MergeTimingsBySizeAndTime(text_, image_); } -LargestContentfulPaintHandler::LargestContentfulPaintHandler() = default; +LargestContentfulPaintHandler::LargestContentfulPaintHandler() + : main_frame_contentful_paint_(true /*in_main_frame*/), + subframe_contentful_paint_(false /*in_main_frame*/) {} + LargestContentfulPaintHandler::~LargestContentfulPaintHandler() = default; void LargestContentfulPaintHandler::RecordTiming(
diff --git a/chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.h b/chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.h index 1af18aa2..6a11714 100644 --- a/chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.h +++ b/chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.h
@@ -16,16 +16,17 @@ class ContentfulPaintTimingInfo { public: explicit ContentfulPaintTimingInfo( - page_load_metrics::PageLoadMetricsObserver::LargestContentType); + page_load_metrics::PageLoadMetricsObserver::LargestContentType, + bool in_main_frame); explicit ContentfulPaintTimingInfo( const base::Optional<base::TimeDelta>&, const uint64_t& size, - const page_load_metrics::PageLoadMetricsObserver::LargestContentType); + const page_load_metrics::PageLoadMetricsObserver::LargestContentType, + bool in_main_frame); explicit ContentfulPaintTimingInfo(const ContentfulPaintTimingInfo& other); void Reset(const base::Optional<base::TimeDelta>&, const uint64_t& size); - base::Optional<base::TimeDelta> Time() const { - return time_; - } + base::Optional<base::TimeDelta> Time() const { return time_; } + bool InMainFrame() const { return in_main_frame_; } uint64_t Size() const { return size_; } page_load_metrics::PageLoadMetricsObserver::LargestContentType Type() const { return type_; @@ -44,11 +45,12 @@ base::Optional<base::TimeDelta> time_; uint64_t size_; page_load_metrics::PageLoadMetricsObserver::LargestContentType type_; + bool in_main_frame_; }; class ContentfulPaint { public: - ContentfulPaint(); + explicit ContentfulPaint(bool in_main_frame); ContentfulPaintTimingInfo& Text() { return text_; } ContentfulPaintTimingInfo& Image() { return image_; } const ContentfulPaintTimingInfo& MergeTextAndImageTiming();
diff --git a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc index 7b6b7f7..a7dc8f6 100644 --- a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc
@@ -319,9 +319,6 @@ largest_contentful_paint_handler_.MergeMainFrameAndSubframes(); if (!paint.IsEmpty() && WasStartedInForegroundOptionalEventInForeground(paint.Time(), info)) { - TRACE_EVENT_INSTANT1( - "loading", "NavStartToLargestContentfulPaint::AllFrames::UKM", - TRACE_EVENT_SCOPE_THREAD, "data", paint.DataAsTraceValue()); builder .SetExperimental_PaintTiming_NavigationToLargestContentPaintAllFrames( paint.Time().value().InMilliseconds()); @@ -624,6 +621,23 @@ const page_load_metrics::PageLoadExtraInfo& extra_info) { largest_contentful_paint_handler_.RecordTiming(timing.paint_timing, subframe_rfh); + bool loading_enabled; + TRACE_EVENT_CATEGORY_GROUP_ENABLED("loading", &loading_enabled); + if (!loading_enabled) + return; + const page_load_metrics::ContentfulPaintTimingInfo& paint = + largest_contentful_paint_handler_.MergeMainFrameAndSubframes(); + if (!paint.IsEmpty()) { + TRACE_EVENT_INSTANT1( + "loading", + "NavStartToLargestContentfulPaint::Candidate::AllFrames::UKM", + TRACE_EVENT_SCOPE_THREAD, "data", paint.DataAsTraceValue()); + } else { + TRACE_EVENT_INSTANT0("loading", + "NavStartToLargestContentfulPaint::" + "Invalidate::AllFrames::UKM", + TRACE_EVENT_SCOPE_THREAD); + } } void UkmPageLoadMetricsObserver::OnCpuTimingUpdate(
diff --git a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc index 08fac2ee9..eb9f63d 100644 --- a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc
@@ -443,8 +443,8 @@ } auto analyzer = trace_analyzer::Stop(); trace_analyzer::TraceEventVector events; - Query q = - Query::EventNameIs("NavStartToLargestContentfulPaint::AllFrames::UKM"); + Query q = Query::EventNameIs( + "NavStartToLargestContentfulPaint::Candidate::AllFrames::UKM"); analyzer->FindEvents(q, &events); EXPECT_EQ(1u, events.size()); EXPECT_EQ("loading", events[0]->category); @@ -464,6 +464,48 @@ EXPECT_EQ("text", type); } +TEST_F(UkmPageLoadMetricsObserverTest, + LargestContentPaint_Trace_InvalidateCandidate) { + using trace_analyzer::Query; + trace_analyzer::Start("loading"); + { + page_load_metrics::mojom::PageLoadTiming timing; + page_load_metrics::InitPageLoadTimingForTest(&timing); + timing.navigation_start = base::Time::FromDoubleT(1); + timing.paint_timing->largest_text_paint = + base::TimeDelta::FromMilliseconds(600); + timing.paint_timing->largest_text_paint_size = 1000; + PopulateRequiredTimingFields(&timing); + + NavigateAndCommit(GURL(kTestUrl1)); + SimulateTimingUpdate(timing); + + timing.paint_timing->largest_text_paint = base::Optional<base::TimeDelta>(); + timing.paint_timing->largest_text_paint_size = 0; + PopulateRequiredTimingFields(&timing); + + SimulateTimingUpdate(timing); + + // Simulate closing the tab. + DeleteContents(); + } + auto analyzer = trace_analyzer::Stop(); + + trace_analyzer::TraceEventVector candidate_events; + Query candidate_query = Query::EventNameIs( + "NavStartToLargestContentfulPaint::Candidate::AllFrames::UKM"); + analyzer->FindEvents(candidate_query, &candidate_events); + EXPECT_EQ(1u, candidate_events.size()); + + trace_analyzer::TraceEventVector invalidate_events; + Query invalidate_query = Query::EventNameIs( + "NavStartToLargestContentfulPaint::" + "Invalidate::AllFrames::UKM"); + analyzer->FindEvents(invalidate_query, &invalidate_events); + EXPECT_EQ(1u, invalidate_events.size()); + EXPECT_EQ("loading", invalidate_events[0]->category); +} + TEST_F(UkmPageLoadMetricsObserverTest, LargestContentPaint_OnlyText) { page_load_metrics::mojom::PageLoadTiming timing; page_load_metrics::InitPageLoadTimingForTest(&timing);
diff --git a/chrome/browser/page_load_metrics/page_load_tracker.cc b/chrome/browser/page_load_metrics/page_load_tracker.cc index 9876f490..ac2fa91 100644 --- a/chrome/browser/page_load_metrics/page_load_tracker.cc +++ b/chrome/browser/page_load_metrics/page_load_tracker.cc
@@ -206,6 +206,7 @@ } PageLoadTracker::~PageLoadTracker() { + LOG(ERROR) << "~PageLoadTracker"; if (app_entered_background_) { RecordAppBackgroundPageLoadCompleted(true); } @@ -240,6 +241,7 @@ } const PageLoadExtraInfo info = ComputePageLoadExtraInfo(); + LOG(ERROR) << "OnComplete " << info.url << " " << did_commit_; for (const auto& observer : observers_) { if (failed_provisional_load_info_) { observer->OnFailedProvisionalLoad(*failed_provisional_load_info_, info);
diff --git a/chrome/browser/plugins/chrome_plugin_service_filter.cc b/chrome/browser/plugins/chrome_plugin_service_filter.cc index 0e9b524..55801ac0 100644 --- a/chrome/browser/plugins/chrome_plugin_service_filter.cc +++ b/chrome/browser/plugins/chrome_plugin_service_filter.cc
@@ -8,18 +8,17 @@ #include "base/bind.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/plugins/flash_temporary_permission_tracker.h" #include "chrome/browser/plugins/plugin_finder.h" #include "chrome/browser/plugins/plugin_metadata.h" #include "chrome/browser/plugins/plugin_utils.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/common/chrome_features.h" #include "chrome/common/render_messages.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" +#include "content/public/browser/notification_types.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -249,8 +248,6 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, content::NotificationService::AllSources()); - registrar_.Add(this, chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, - content::NotificationService::AllSources()); } ChromePluginServiceFilter::~ChromePluginServiceFilter() {} @@ -260,28 +257,12 @@ const content::NotificationSource& source, const content::NotificationDetails& details) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - switch (type) { - case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { - int render_process_id = - content::Source<content::RenderProcessHost>(source).ptr()->GetID(); + DCHECK_EQ(content::NOTIFICATION_RENDERER_PROCESS_CLOSED, type); + int render_process_id = + content::Source<content::RenderProcessHost>(source).ptr()->GetID(); - base::AutoLock auto_lock(lock_); - plugin_details_.erase(render_process_id); - break; - } - case chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED: { - Profile* profile = content::Source<Profile>(source).ptr(); - PluginService::GetInstance()->PurgePluginListCache(profile, false); - if (profile && profile->HasOffTheRecordProfile()) { - PluginService::GetInstance()->PurgePluginListCache( - profile->GetOffTheRecordProfile(), false); - } - break; - } - default: { - NOTREACHED(); - } - } + base::AutoLock auto_lock(lock_); + plugin_details_.erase(render_process_id); } ChromePluginServiceFilter::ProcessDetails*
diff --git a/chrome/browser/plugins/plugin_prefs.cc b/chrome/browser/plugins/plugin_prefs.cc index 8ea5764..4b8d3b9 100644 --- a/chrome/browser/plugins/plugin_prefs.cc +++ b/chrome/browser/plugins/plugin_prefs.cc
@@ -17,7 +17,6 @@ #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/plugins/plugin_finder.h" #include "chrome/browser/plugins/plugin_metadata.h" #include "chrome/browser/plugins/plugin_prefs_factory.h" @@ -29,8 +28,6 @@ #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/scoped_user_pref_update.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" #include "content/public/browser/plugin_service.h" #include "content/public/common/webplugininfo.h" @@ -65,7 +62,6 @@ PluginPrefs::PolicyStatus PluginPrefs::PolicyStatusForPlugin( const base::string16& name) const { - base::AutoLock auto_lock(lock_); // Special handling for PDF based on its specific policy. if (IsPDFViewerPlugin(name) && always_open_pdf_externally_) @@ -94,11 +90,14 @@ } void PluginPrefs::UpdatePdfPolicy(const std::string& pref_name) { - base::AutoLock auto_lock(lock_); always_open_pdf_externally_ = prefs_->GetBoolean(prefs::kPluginsAlwaysOpenPdfExternally); - NotifyPluginStatusChanged(); + content::PluginService::GetInstance()->PurgePluginListCache(profile_, false); + if (profile_->HasOffTheRecordProfile()) { + content::PluginService::GetInstance()->PurgePluginListCache( + profile_->GetOffTheRecordProfile(), false); + } } void PluginPrefs::SetPrefs(PrefService* prefs) { @@ -175,44 +174,22 @@ } } // Scoped update of prefs::kPluginsPluginsList. - always_open_pdf_externally_ = - prefs_->GetBoolean(prefs::kPluginsAlwaysOpenPdfExternally); - + UpdatePdfPolicy(prefs::kPluginsAlwaysOpenPdfExternally); registrar_.Init(prefs_); - - // Because pointers to our own members will remain unchanged for the - // lifetime of |registrar_| (which we also own), we can bind their - // pointer values directly in the callbacks to avoid string-based - // lookups at notification time. registrar_.Add(prefs::kPluginsAlwaysOpenPdfExternally, base::Bind(&PluginPrefs::UpdatePdfPolicy, base::Unretained(this))); - - NotifyPluginStatusChanged(); } void PluginPrefs::ShutdownOnUIThread() { - prefs_ = NULL; + prefs_ = nullptr; registrar_.RemoveAll(); } -PluginPrefs::PluginPrefs() : always_open_pdf_externally_(false), - profile_(NULL), - prefs_(NULL) { -} - -PluginPrefs::~PluginPrefs() { -} +PluginPrefs::PluginPrefs() = default; +PluginPrefs::~PluginPrefs() = default; void PluginPrefs::SetAlwaysOpenPdfExternallyForTests( bool always_open_pdf_externally) { always_open_pdf_externally_ = always_open_pdf_externally; } - -void PluginPrefs::NotifyPluginStatusChanged() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, - content::Source<Profile>(profile_), - content::NotificationService::NoDetails()); -}
diff --git a/chrome/browser/plugins/plugin_prefs.h b/chrome/browser/plugins/plugin_prefs.h index 7d57bccc..607fb32 100644 --- a/chrome/browser/plugins/plugin_prefs.h +++ b/chrome/browser/plugins/plugin_prefs.h
@@ -10,7 +10,6 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/strings/string16.h" -#include "base/synchronization/lock.h" #include "components/keyed_service/core/refcounted_keyed_service.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" @@ -74,19 +73,12 @@ // Allows unit tests to directly set the AlwaysOpenPdfExternally pref. void SetAlwaysOpenPdfExternallyForTests(bool always_open_pdf_externally); - // Sends the notification that plugin data has changed. - void NotifyPluginStatusChanged(); + bool always_open_pdf_externally_ = false; - // Guards access to the following data structures. - mutable base::Lock lock_; - - bool always_open_pdf_externally_; - - // Weak pointer, owns us. Only used as a notification source. - Profile* profile_; + Profile* profile_ = nullptr; // Weak pointer, owned by the profile. - PrefService* prefs_; + PrefService* prefs_ = nullptr; PrefChangeRegistrar registrar_;
diff --git a/chrome/browser/plugins/plugin_status_pref_setter.cc b/chrome/browser/plugins/plugin_status_pref_setter.cc deleted file mode 100644 index 90202e2..0000000 --- a/chrome/browser/plugins/plugin_status_pref_setter.cc +++ /dev/null
@@ -1,69 +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/plugins/plugin_status_pref_setter.h" - -#include "base/bind.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/pepper_flash_settings_manager.h" -#include "chrome/browser/plugins/plugin_data_remover_helper.h" -#include "chrome/browser/plugins/plugin_prefs.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/pref_names.h" -#include "components/prefs/pref_service.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/plugin_service.h" -#include "content/public/common/webplugininfo.h" - -using content::BrowserThread; -using content::PluginService; - -PluginStatusPrefSetter::PluginStatusPrefSetter() - : profile_(NULL), - factory_(this) {} - -PluginStatusPrefSetter::~PluginStatusPrefSetter() { -} - -void PluginStatusPrefSetter::Init( - Profile* profile, - const BooleanPrefMember::NamedChangeCallback& observer) { - clear_plugin_lso_data_enabled_.Init(prefs::kClearPluginLSODataEnabled, - profile->GetPrefs(), observer); - pepper_flash_settings_enabled_.Init(prefs::kPepperFlashSettingsEnabled, - profile->GetPrefs(), observer); - profile_ = profile; - registrar_.Add(this, chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, - content::Source<Profile>(profile)); - StartUpdate(); -} - -void PluginStatusPrefSetter::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, type); - StartUpdate(); -} - -void PluginStatusPrefSetter::StartUpdate() { - PluginService::GetInstance()->GetPlugins( - base::BindOnce(&PluginStatusPrefSetter::GotPlugins, factory_.GetWeakPtr(), - PluginPrefs::GetForProfile(profile_))); -} - -void PluginStatusPrefSetter::GotPlugins( - scoped_refptr<PluginPrefs> plugin_prefs, - const std::vector<content::WebPluginInfo>& plugins) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - // Set the values on the PrefService instead of through the PrefMembers to - // notify observers if they changed. - profile_->GetPrefs()->SetBoolean( - clear_plugin_lso_data_enabled_.GetPrefName().c_str(), - PluginDataRemoverHelper::IsSupported(plugin_prefs.get())); - profile_->GetPrefs()->SetBoolean( - pepper_flash_settings_enabled_.GetPrefName().c_str(), - PepperFlashSettingsManager::IsPepperFlashInUse(plugin_prefs.get(), NULL)); -}
diff --git a/chrome/browser/plugins/plugin_status_pref_setter.h b/chrome/browser/plugins/plugin_status_pref_setter.h deleted file mode 100644 index 4c6bb84..0000000 --- a/chrome/browser/plugins/plugin_status_pref_setter.h +++ /dev/null
@@ -1,73 +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_PLUGINS_PLUGIN_STATUS_PREF_SETTER_H_ -#define CHROME_BROWSER_PLUGINS_PLUGIN_STATUS_PREF_SETTER_H_ - -#include <vector> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "components/prefs/pref_member.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" - -class PluginPrefs; -class PrefService; -class Profile; - -namespace content { -struct WebPluginInfo; -} - -// Helper class modeled after BooleanPrefMember to (asynchronously) update -// preferences related to plugin enable status. -// It should only be used from the UI thread. The client has to make sure that -// the passed profile outlives this object. -class PluginStatusPrefSetter : public content::NotificationObserver { - public: - PluginStatusPrefSetter(); - ~PluginStatusPrefSetter() override; - - // Binds the preferences in the profile's PrefService, notifying |observer| if - // any value changes. - // This asynchronously calls the PluginService to get the list of installed - // plugins. - void Init(Profile* profile, - const BooleanPrefMember::NamedChangeCallback& observer); - - bool IsClearPluginLSODataEnabled() const { - return clear_plugin_lso_data_enabled_.GetValue(); - } - - bool IsPepperFlashSettingsEnabled() const { - return pepper_flash_settings_enabled_.GetValue(); - } - - // content::NotificationObserver methods: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - - private: - void StartUpdate(); - void GotPlugins(scoped_refptr<PluginPrefs> plugin_prefs, - const std::vector<content::WebPluginInfo>& plugins); - - content::NotificationRegistrar registrar_; - // Weak pointer. - Profile* profile_; - - // Whether clearing LSO data is supported. - BooleanPrefMember clear_plugin_lso_data_enabled_; - // Whether we should show Pepper Flash-specific settings. - BooleanPrefMember pepper_flash_settings_enabled_; - - base::WeakPtrFactory<PluginStatusPrefSetter> factory_; - - DISALLOW_COPY_AND_ASSIGN(PluginStatusPrefSetter); -}; - -#endif // CHROME_BROWSER_PLUGINS_PLUGIN_STATUS_PREF_SETTER_H_
diff --git a/chrome/browser/predictors/loading_data_collector.cc b/chrome/browser/predictors/loading_data_collector.cc index 8573069..c2ac8a6b 100644 --- a/chrome/browser/predictors/loading_data_collector.cc +++ b/chrome/browser/predictors/loading_data_collector.cc
@@ -7,8 +7,10 @@ #include <string> #include <utility> +#include "chrome/browser/browser_features.h" #include "chrome/browser/predictors/loading_data_collector.h" #include "chrome/browser/predictors/loading_stats_collector.h" +#include "chrome/browser/predictors/predictors_features.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h" #include "chrome/browser/profiles/profile.h" @@ -186,7 +188,7 @@ if (nav_it == inflight_navigations_.end()) return; - if (!ShouldRecordResourceLoad(resource_load_info)) + if (!ShouldRecordResourceLoad(navigation_id, resource_load_info)) return; auto& page_request_summary = *nav_it->second; @@ -228,9 +230,9 @@ nav_it->second->first_contentful_paint = first_contentful_paint; } -// static bool LoadingDataCollector::ShouldRecordResourceLoad( - const content::mojom::ResourceLoadInfo& resource_load_info) { + const NavigationID& navigation_id, + const content::mojom::ResourceLoadInfo& resource_load_info) const { const GURL& url = resource_load_info.url; if (!url.is_valid() || !url.SchemeIsHTTPOrHTTPS()) return false; @@ -238,9 +240,21 @@ if (!g_allow_port_in_urls && url.has_port()) return false; - return IsHandledResourceType(resource_load_info.resource_type, - resource_load_info.mime_type) && - resource_load_info.method == "GET"; + // Guard behind feature: All delayable requests are considered low priority. + if (base::FeatureList::IsEnabled( + features::kLoadingOnlyLearnHighPriorityResources) && + resource_load_info.request_priority < net::MEDIUM) { + return false; + } + + if (!IsHandledResourceType(resource_load_info.resource_type, + resource_load_info.mime_type)) { + return false; + } + if (resource_load_info.method != "GET") + return false; + + return true; } // static
diff --git a/chrome/browser/predictors/loading_data_collector.h b/chrome/browser/predictors/loading_data_collector.h index f4fb67b..419b6cd 100644 --- a/chrome/browser/predictors/loading_data_collector.h +++ b/chrome/browser/predictors/loading_data_collector.h
@@ -96,6 +96,8 @@ FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest, HandledResourceTypes); FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest, ShouldRecordMainFrameLoad); FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest, + ShouldRecordSubresourceLoadAfterFCP); + FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest, ShouldRecordSubresourceLoad); FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest, SimpleNavigation); FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest, SimpleRedirect); @@ -108,8 +110,9 @@ static void SetAllowPortInUrlsForTesting(bool state); - static bool ShouldRecordResourceLoad( - const content::mojom::ResourceLoadInfo& resource_load_info); + bool ShouldRecordResourceLoad( + const NavigationID& navigation_id, + const content::mojom::ResourceLoadInfo& resource_load_info) const; // Returns true if the subresource has a supported type. static bool IsHandledResourceType(content::ResourceType resource_type,
diff --git a/chrome/browser/predictors/loading_data_collector_unittest.cc b/chrome/browser/predictors/loading_data_collector_unittest.cc index 10c19644..cd1d8c7 100644 --- a/chrome/browser/predictors/loading_data_collector_unittest.cc +++ b/chrome/browser/predictors/loading_data_collector_unittest.cc
@@ -10,9 +10,11 @@ #include <vector> #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/predictors/loading_predictor_config.h" #include "chrome/browser/predictors/loading_test_util.h" +#include "chrome/browser/predictors/predictors_features.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_utils.h" @@ -77,80 +79,112 @@ } TEST_F(LoadingDataCollectorTest, ShouldRecordMainFrameLoad) { + const SessionID kTabId = SessionID::FromSerializedValue(1); + auto navigation_id = CreateNavigationID(kTabId, "http://www.google.com"); auto http_request = CreateResourceLoadInfo("http://www.google.com"); - EXPECT_TRUE(LoadingDataCollector::ShouldRecordResourceLoad(*http_request)); + EXPECT_TRUE( + collector_->ShouldRecordResourceLoad(navigation_id, *http_request)); auto https_request = CreateResourceLoadInfo("https://www.google.com"); - EXPECT_TRUE(LoadingDataCollector::ShouldRecordResourceLoad(*https_request)); + EXPECT_TRUE( + collector_->ShouldRecordResourceLoad(navigation_id, *https_request)); auto file_request = CreateResourceLoadInfo("file://www.google.com"); - EXPECT_FALSE(LoadingDataCollector::ShouldRecordResourceLoad(*file_request)); + EXPECT_FALSE( + collector_->ShouldRecordResourceLoad(navigation_id, *file_request)); auto https_request_with_port = CreateResourceLoadInfo("https://www.google.com:666"); - EXPECT_FALSE( - LoadingDataCollector::ShouldRecordResourceLoad(*https_request_with_port)); + EXPECT_FALSE(collector_->ShouldRecordResourceLoad(navigation_id, + *https_request_with_port)); } -TEST_F(LoadingDataCollectorTest, ShouldRecordSubresourceLoad) { +// Resource loaded after FCP event is recorded by default. +TEST_F(LoadingDataCollectorTest, ShouldRecordSubresourceLoadAfterFCP) { + const SessionID kTabId = SessionID::FromSerializedValue(1); + auto navigation_id = CreateNavigationID(kTabId, "http://www.google.com"); + + collector_->RecordStartNavigation(navigation_id); + collector_->RecordFirstContentfulPaint(navigation_id, base::TimeTicks::Now()); + // Protocol. auto http_image_request = CreateResourceLoadInfo( "http://www.google.com/cat.png", content::ResourceType::kImage); EXPECT_TRUE( - LoadingDataCollector::ShouldRecordResourceLoad(*http_image_request)); + collector_->ShouldRecordResourceLoad(navigation_id, *http_image_request)); +} + +TEST_F(LoadingDataCollectorTest, ShouldRecordSubresourceLoad) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kLoadingOnlyLearnHighPriorityResources); + const SessionID kTabId = SessionID::FromSerializedValue(1); + auto navigation_id = CreateNavigationID(kTabId, "http://www.google.com"); + + // Protocol. + auto low_priority_http_image_request = CreateLowPriorityResourceLoadInfo( + "http://www.google.com/cat.png", content::ResourceType::kImage); + EXPECT_FALSE(collector_->ShouldRecordResourceLoad( + navigation_id, *low_priority_http_image_request)); + + auto http_image_request = CreateResourceLoadInfo( + "http://www.google.com/cat.png", content::ResourceType::kImage); + EXPECT_TRUE( + collector_->ShouldRecordResourceLoad(navigation_id, *http_image_request)); auto https_image_request = CreateResourceLoadInfo( "https://www.google.com/cat.png", content::ResourceType::kImage); - EXPECT_TRUE( - LoadingDataCollector::ShouldRecordResourceLoad(*https_image_request)); + EXPECT_TRUE(collector_->ShouldRecordResourceLoad(navigation_id, + *https_image_request)); auto https_image_request_with_port = CreateResourceLoadInfo( "https://www.google.com:666/cat.png", content::ResourceType::kImage); - EXPECT_FALSE(LoadingDataCollector::ShouldRecordResourceLoad( - *https_image_request_with_port)); + EXPECT_FALSE(collector_->ShouldRecordResourceLoad( + navigation_id, *https_image_request_with_port)); auto file_image_request = CreateResourceLoadInfo( "file://www.google.com/cat.png", content::ResourceType::kImage); EXPECT_FALSE( - LoadingDataCollector::ShouldRecordResourceLoad(*file_image_request)); + collector_->ShouldRecordResourceLoad(navigation_id, *file_image_request)); // ResourceType. auto sub_frame_request = CreateResourceLoadInfo( "http://www.google.com/frame.html", content::ResourceType::kSubFrame); EXPECT_FALSE( - LoadingDataCollector::ShouldRecordResourceLoad(*sub_frame_request)); + collector_->ShouldRecordResourceLoad(navigation_id, *sub_frame_request)); auto font_request = CreateResourceLoadInfo("http://www.google.com/comic-sans-ms.woff", content::ResourceType::kFontResource); - EXPECT_TRUE(LoadingDataCollector::ShouldRecordResourceLoad(*font_request)); + EXPECT_TRUE( + collector_->ShouldRecordResourceLoad(navigation_id, *font_request)); // From MIME Type. auto prefetch_image_request = CreateResourceLoadInfo( "http://www.google.com/cat.png", content::ResourceType::kPrefetch); prefetch_image_request->mime_type = "image/png"; - EXPECT_TRUE( - LoadingDataCollector::ShouldRecordResourceLoad(*prefetch_image_request)); + EXPECT_TRUE(collector_->ShouldRecordResourceLoad(navigation_id, + *prefetch_image_request)); auto prefetch_unknown_image_request = CreateResourceLoadInfo( "http://www.google.com/cat.png", content::ResourceType::kPrefetch); prefetch_unknown_image_request->mime_type = "image/my-wonderful-format"; - EXPECT_FALSE(LoadingDataCollector::ShouldRecordResourceLoad( - *prefetch_unknown_image_request)); + EXPECT_FALSE(collector_->ShouldRecordResourceLoad( + navigation_id, *prefetch_unknown_image_request)); auto prefetch_font_request = CreateResourceLoadInfo("http://www.google.com/comic-sans-ms.woff", content::ResourceType::kPrefetch); prefetch_font_request->mime_type = "font/woff"; - EXPECT_TRUE( - LoadingDataCollector::ShouldRecordResourceLoad(*prefetch_font_request)); + EXPECT_TRUE(collector_->ShouldRecordResourceLoad(navigation_id, + *prefetch_font_request)); auto prefetch_unknown_font_request = CreateResourceLoadInfo("http://www.google.com/comic-sans-ms.woff", content::ResourceType::kPrefetch); prefetch_unknown_font_request->mime_type = "font/woff-woff"; - EXPECT_FALSE(LoadingDataCollector::ShouldRecordResourceLoad( - *prefetch_unknown_font_request)); + EXPECT_FALSE(collector_->ShouldRecordResourceLoad( + navigation_id, *prefetch_unknown_font_request)); } // Single navigation that will be recorded. Will check for duplicate @@ -200,6 +234,7 @@ auto summary = CreatePageRequestSummary("http://www.google.com", "http://www.google.com", resources); + EXPECT_FALSE(summary.origins.empty()); EXPECT_CALL(*mock_predictor_, RecordPageRequestSummaryProxy(testing::Pointee(summary)));
diff --git a/chrome/browser/predictors/loading_predictor.h b/chrome/browser/predictors/loading_predictor.h index 7296d34..c8dedd5 100644 --- a/chrome/browser/predictors/loading_predictor.h +++ b/chrome/browser/predictors/loading_predictor.h
@@ -145,6 +145,7 @@ friend class LoadingPredictorTest; friend class LoadingPredictorPreconnectTest; friend class LoadingPredictorTabHelperTest; + friend class LoadingPredictorTabHelperTestCollectorTest; FRIEND_TEST_ALL_PREFIXES(LoadingPredictorTest, TestMainFrameResponseCancelsHint); FRIEND_TEST_ALL_PREFIXES(LoadingPredictorTest,
diff --git a/chrome/browser/predictors/loading_predictor_browsertest.cc b/chrome/browser/predictors/loading_predictor_browsertest.cc index 5df9cbf..659665f1 100644 --- a/chrome/browser/predictors/loading_predictor_browsertest.cc +++ b/chrome/browser/predictors/loading_predictor_browsertest.cc
@@ -17,10 +17,12 @@ #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/browser_features.h" #include "chrome/browser/predictors/loading_predictor.h" #include "chrome/browser/predictors/loading_predictor_factory.h" #include "chrome/browser/predictors/loading_test_util.h" #include "chrome/browser/predictors/preconnect_manager.h" +#include "chrome/browser/predictors/predictors_features.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/common/chrome_switches.h" @@ -58,8 +60,11 @@ "0000000000000000000000000000000000000000000000000000.org"; const char kHtmlSubresourcesPath[] = "/predictors/html_subresources.html"; -const std::string kHtmlSubresourcesHosts[] = {"test.com", "baz.com", "foo.com", - "bar.com"}; +// The embedded test server runs on test.com. +// kHtmlSubresourcesPath contains high priority resources from baz.com and +// foo.com. kHtmlSubresourcesPath also contains a low priority resource from +// bar.com. +const char* const kHtmlSubresourcesHosts[] = {"test.com", "baz.com", "foo.com"}; std::string GetPathWithPortReplacement(const std::string& path, uint16_t port) { std::string string_port = base::StringPrintf("%d", port); @@ -374,6 +379,8 @@ ~LoadingPredictorBrowserTest() override {} void SetUp() override { + scoped_feature_list_.InitAndEnableFeature( + features::kLoadingOnlyLearnHighPriorityResources); ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); InProcessBrowserTest::SetUp(); } @@ -458,6 +465,7 @@ std::unique_ptr<ConnectionListener> connection_listener_; std::unique_ptr<ConnectionTracker> connection_tracker_; std::unique_ptr<TestPreconnectManagerObserver> preconnect_manager_observer_; + base::test::ScopedFeatureList scoped_feature_list_; DISALLOW_COPY_AND_ASSIGN(LoadingPredictorBrowserTest); }; @@ -581,11 +589,12 @@ // Tests that the LoadingPredictor has a prediction for a host after navigating // to it. IN_PROC_BROWSER_TEST_F(LoadingPredictorBrowserTest, LearnFromNavigation) { + base::test::ScopedFeatureList scoped_feature_list; GURL url = embedded_test_server()->GetURL( "test.com", GetPathWithPortReplacement(kHtmlSubresourcesPath, embedded_test_server()->port())); std::vector<PreconnectRequest> requests; - for (const auto& host : kHtmlSubresourcesHosts) + for (auto* const host : kHtmlSubresourcesHosts) requests.emplace_back(embedded_test_server()->GetURL(host, "/"), 1); ui_test_utils::NavigateToURL(browser(), url); @@ -597,6 +606,36 @@ testing::UnorderedElementsAreArray(requests)); } +// Tests that the LoadingPredictor has a prediction for a host after navigating +// to it. Disables kLoadingOnlyLearnHighPriorityResources. +IN_PROC_BROWSER_TEST_F( + LoadingPredictorBrowserTest, + LearnFromNavigation_DisablekLoadingOnlyLearnHighPriorityResources) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature( + features::kLoadingOnlyLearnHighPriorityResources); + + GURL url = embedded_test_server()->GetURL( + "test.com", GetPathWithPortReplacement(kHtmlSubresourcesPath, + embedded_test_server()->port())); + std::vector<PreconnectRequest> requests; + for (auto* const host : kHtmlSubresourcesHosts) + requests.emplace_back(embedded_test_server()->GetURL(host, "/"), 1); + + // When kLoadingOnlyLearnHighPriorityResources is disabled, loading data + // collector should learn the loading of low priority resources hosted on + // bar.com as well. + requests.emplace_back(embedded_test_server()->GetURL("bar.com", "/"), 1); + + ui_test_utils::NavigateToURL(browser(), url); + auto prediction = GetPreconnectPrediction(url); + ASSERT_TRUE(prediction); + EXPECT_EQ(prediction->is_redirected, false); + EXPECT_EQ(prediction->host, url.host()); + EXPECT_THAT(prediction->requests, + testing::UnorderedElementsAreArray(requests)); +} + // Tests that the LoadingPredictor correctly learns from navigations with // redirect. IN_PROC_BROWSER_TEST_F(LoadingPredictorBrowserTest, @@ -608,7 +647,7 @@ "redirect.com", base::StringPrintf("/server-redirect?%s", redirect_url.spec().c_str())); std::vector<PreconnectRequest> requests; - for (const auto& host : kHtmlSubresourcesHosts) + for (auto* const host : kHtmlSubresourcesHosts) requests.emplace_back(embedded_test_server()->GetURL(host, "/"), 1); ui_test_utils::NavigateToURL(browser(), original_url); @@ -648,8 +687,8 @@ auto observer = NavigateToURLAsync(url); EXPECT_TRUE(observer->WaitForRequestStart()); - for (const auto& host : kHtmlSubresourcesHosts) { - GURL url(base::StringPrintf("http://%s", host.c_str())); + for (auto* const host : kHtmlSubresourcesHosts) { + GURL url(base::StringPrintf("http://%s", host)); preconnect_manager_observer()->WaitUntilHostLookedUp(url.host()); EXPECT_TRUE(preconnect_manager_observer()->HostFound(url.host())); } @@ -851,7 +890,7 @@ auto observer = NavigateToURLAsync(url); EXPECT_TRUE(observer->WaitForRequestStart()); - for (const auto& host : kHtmlSubresourcesHosts) { + for (auto* const host : kHtmlSubresourcesHosts) { GURL url = embedded_test_server()->GetURL(host, "/"); preconnect_manager_observer()->WaitUntilProxyLookedUp(url); EXPECT_TRUE(preconnect_manager_observer()->ProxyFound(url));
diff --git a/chrome/browser/predictors/loading_predictor_tab_helper.cc b/chrome/browser/predictors/loading_predictor_tab_helper.cc index 7983afcc..9a01fbc 100644 --- a/chrome/browser/predictors/loading_predictor_tab_helper.cc +++ b/chrome/browser/predictors/loading_predictor_tab_helper.cc
@@ -12,6 +12,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/common/resource_type.h" using content::BrowserThread; @@ -19,6 +20,33 @@ namespace { +net::RequestPriority GetRequestPriority(content::ResourceType resource_type) { + switch (resource_type) { + case content::ResourceType::kMainFrame: + case content::ResourceType::kStylesheet: + case content::ResourceType::kFontResource: + return net::HIGHEST; + case content::ResourceType::kScript: + return net::MEDIUM; + case content::ResourceType::kSubFrame: + case content::ResourceType::kImage: + case content::ResourceType::kSubResource: + case content::ResourceType::kObject: + case content::ResourceType::kMedia: + case content::ResourceType::kWorker: + case content::ResourceType::kSharedWorker: + case content::ResourceType::kPrefetch: + case content::ResourceType::kFavicon: + case content::ResourceType::kXhr: + case content::ResourceType::kPing: + case content::ResourceType::kServiceWorker: + case content::ResourceType::kCspReport: + case content::ResourceType::kPluginResource: + case content::ResourceType::kNavigationPreload: + return net::LOWEST; + } +} + bool IsHandledNavigation(content::NavigationHandle* navigation_handle) { return navigation_handle->IsInMainFrame() && !navigation_handle->IsSameDocument() && @@ -114,6 +142,8 @@ resource_load_info.mime_type = mime_type; resource_load_info.resource_type = resource_type; resource_load_info.method = "GET"; + resource_load_info.request_priority = + GetRequestPriority(resource_load_info.resource_type); resource_load_info.network_info = content::mojom::CommonNetworkInfo::New(false, false, base::nullopt); predictor_->loading_data_collector()->RecordResourceLoadComplete(
diff --git a/chrome/browser/predictors/loading_predictor_tab_helper_unittest.cc b/chrome/browser/predictors/loading_predictor_tab_helper_unittest.cc index 41b017f..987ea4c3 100644 --- a/chrome/browser/predictors/loading_predictor_tab_helper_unittest.cc +++ b/chrome/browser/predictors/loading_predictor_tab_helper_unittest.cc
@@ -43,7 +43,7 @@ void SetUp() override; void TearDown() override; - void ExpectRecordNavigation(const std::string& url); + virtual void ExpectRecordNavigation(const std::string& url); SessionID GetTabID(); void NavigateAndCommitInFrame(const std::string& url, content::RenderFrameHost* rfh); @@ -230,4 +230,96 @@ content::ResourceType::kScript); } +class TestLoadingDataCollector : public LoadingDataCollector { + public: + explicit TestLoadingDataCollector(const LoadingPredictorConfig& config); + + void RecordStartNavigation(const NavigationID& navigation_id) override {} + void RecordFinishNavigation(const NavigationID& old_navigation_id, + const NavigationID& new_navigation_id, + bool is_error_page) override {} + void RecordResourceLoadComplete( + const NavigationID& navigation_id, + const content::mojom::ResourceLoadInfo& resource_load_info) override { + ++count_resource_loads_completed_; + EXPECT_EQ(expected_request_priority_, resource_load_info.request_priority); + } + + void RecordMainFrameLoadComplete(const NavigationID& navigation_id) override { + } + + void RecordFirstContentfulPaint( + const NavigationID& navigation_id, + const base::TimeTicks& first_contentful_paint) override {} + + void SetExpectedResourcePriority(net::RequestPriority request_priority) { + expected_request_priority_ = request_priority; + } + + size_t count_resource_loads_completed() const { + return count_resource_loads_completed_; + } + + private: + net::RequestPriority expected_request_priority_ = net::HIGHEST; + size_t count_resource_loads_completed_ = 0; +}; + +TestLoadingDataCollector::TestLoadingDataCollector( + const LoadingPredictorConfig& config) + : LoadingDataCollector(nullptr, nullptr, config) {} + +class LoadingPredictorTabHelperTestCollectorTest + : public LoadingPredictorTabHelperTest { + public: + void SetUp() override; + + void ExpectRecordNavigation(const std::string& url) override {} + + protected: + TestLoadingDataCollector* test_collector_; +}; + +void LoadingPredictorTabHelperTestCollectorTest::SetUp() { + ChromeRenderViewHostTestHarness::SetUp(); + SessionTabHelper::CreateForWebContents(web_contents()); + LoadingPredictorTabHelper::CreateForWebContents(web_contents()); + tab_helper_ = LoadingPredictorTabHelper::FromWebContents(web_contents()); + + LoadingPredictorConfig config; + PopulateTestConfig(&config); + loading_predictor_ = std::make_unique<LoadingPredictor>(config, profile()); + + auto test_collector = std::make_unique<TestLoadingDataCollector>(config); + test_collector_ = test_collector.get(); + loading_predictor_->set_mock_loading_data_collector( + std::move(test_collector)); + + tab_helper_->SetLoadingPredictorForTesting(loading_predictor_->GetWeakPtr()); +} + +// Tests that a resource load is correctly recorded with the correct priority. +TEST_F(LoadingPredictorTabHelperTestCollectorTest, ResourceLoadComplete) { + ExpectRecordNavigation("http://test.org"); + NavigateAndCommitInFrame("http://test.org", main_rfh()); + + auto navigation_id = CreateNavigationID(GetTabID(), "http://test.org"); + + // Set expected priority to HIGHEST and load a HIGHEST priority resource. + test_collector_->SetExpectedResourcePriority(net::HIGHEST); + auto resource_load_info = CreateResourceLoadInfo( + "http://test.org/script.js", content::ResourceType::kScript); + tab_helper_->ResourceLoadComplete(main_rfh(), content::GlobalRequestID(), + *resource_load_info); + EXPECT_EQ(1u, test_collector_->count_resource_loads_completed()); + + // Set expected priority to LOWEST and load a LOWEST priority resource. + test_collector_->SetExpectedResourcePriority(net::LOWEST); + resource_load_info = CreateLowPriorityResourceLoadInfo( + "http://test.org/script.js", content::ResourceType::kScript); + tab_helper_->ResourceLoadComplete(main_rfh(), content::GlobalRequestID(), + *resource_load_info); + EXPECT_EQ(2u, test_collector_->count_resource_loads_completed()); +} + } // namespace predictors
diff --git a/chrome/browser/predictors/loading_test_util.cc b/chrome/browser/predictors/loading_test_util.cc index 19eb92a..8cb9ace 100644 --- a/chrome/browser/predictors/loading_test_util.cc +++ b/chrome/browser/predictors/loading_test_util.cc
@@ -106,6 +106,15 @@ resource_load_info->resource_type = resource_type; resource_load_info->network_info = content::mojom::CommonNetworkInfo::New( true, always_access_network, base::nullopt); + resource_load_info->request_priority = net::HIGHEST; + return resource_load_info; +} + +content::mojom::ResourceLoadInfoPtr CreateLowPriorityResourceLoadInfo( + const std::string& url, + content::ResourceType resource_type) { + auto resource_load_info = CreateResourceLoadInfo(url, resource_type, false); + resource_load_info->request_priority = net::LOWEST; return resource_load_info; } @@ -117,6 +126,7 @@ resource_load_info->original_url = GURL(redirect_chain.front()); resource_load_info->method = "GET"; resource_load_info->resource_type = resource_type; + resource_load_info->request_priority = net::HIGHEST; auto common_network_info = content::mojom::CommonNetworkInfo::New(true, false, base::nullopt); resource_load_info->network_info = common_network_info.Clone();
diff --git a/chrome/browser/predictors/loading_test_util.h b/chrome/browser/predictors/loading_test_util.h index d7453e1..fdfe434 100644 --- a/chrome/browser/predictors/loading_test_util.h +++ b/chrome/browser/predictors/loading_test_util.h
@@ -69,6 +69,10 @@ content::ResourceType resource_type = content::ResourceType::kMainFrame, bool always_access_network = false); +content::mojom::ResourceLoadInfoPtr CreateLowPriorityResourceLoadInfo( + const std::string& url, + content::ResourceType resource_type = content::ResourceType::kMainFrame); + content::mojom::ResourceLoadInfoPtr CreateResourceLoadInfoWithRedirects( const std::vector<std::string>& redirect_chain, content::ResourceType resource_type = content::ResourceType::kMainFrame);
diff --git a/chrome/browser/predictors/preconnect_manager.cc b/chrome/browser/predictors/preconnect_manager.cc index 8df721e7..149244a 100644 --- a/chrome/browser/predictors/preconnect_manager.cc +++ b/chrome/browser/predictors/preconnect_manager.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/bind.h" +#include "base/optional.h" #include "base/task/post_task.h" #include "base/trace_event/trace_event.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" @@ -160,8 +161,9 @@ net::LOAD_DO_NOT_SEND_AUTH_DATA; } - network_context->PreconnectSockets(num_sockets, url, load_flags, - privacy_mode); + // TODO(mmenke): Use an appropriate NetworkIsolationKey(). + network_context->PreconnectSockets(num_sockets, url, load_flags, privacy_mode, + base::nullopt); } std::unique_ptr<ResolveHostClientImpl> PreconnectManager::PreresolveUrl(
diff --git a/chrome/browser/predictors/preconnect_manager_unittest.cc b/chrome/browser/predictors/preconnect_manager_unittest.cc index ba8c90e..1aa6aa2f2 100644 --- a/chrome/browser/predictors/preconnect_manager_unittest.cc +++ b/chrome/browser/predictors/preconnect_manager_unittest.cc
@@ -19,6 +19,7 @@ #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread_bundle.h" #include "net/base/load_flags.h" +#include "net/base/network_isolation_key.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "services/network/test/test_network_context.h" #include "testing/gmock/include/gmock/gmock.h" @@ -133,11 +134,13 @@ void EnableProxyTesting() { enabled_proxy_testing_ = true; } MOCK_METHOD1(ResolveHostProxy, void(const std::string& host)); - MOCK_METHOD4(PreconnectSockets, + MOCK_METHOD5(PreconnectSockets, void(uint32_t num_streams, const GURL& url, int32_t load_flags, - bool privacy_mode_enabled)); + bool privacy_mode_enabled, + const base::Optional<net::NetworkIsolationKey>& + network_isolation_key)); private: bool IsHangingHost(const GURL& url) const { @@ -210,7 +213,9 @@ preconnect_manager_->Start(main_frame_url, {PreconnectRequest(url_to_preconnect, 1)}); EXPECT_CALL(*mock_network_context_, - PreconnectSockets(1, url_to_preconnect, kNormalLoadFlags, false)); + PreconnectSockets(1, url_to_preconnect, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url)); mock_network_context_->CompleteHostLookup(url_to_preconnect.host(), net::OK); } @@ -243,15 +248,17 @@ VerifyAndClearExpectations(); // Now, restart the preconnect request. - EXPECT_CALL( - *mock_network_context_, - PreconnectSockets(1, requests.back().origin, kNormalLoadFlags, false)); + EXPECT_CALL(*mock_network_context_, + PreconnectSockets(1, requests.back().origin, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); EXPECT_CALL(*mock_network_context_, ResolveHostProxy(requests.back().origin.host())); for (size_t i = 0; i < count; ++i) { - EXPECT_CALL( - *mock_network_context_, - PreconnectSockets(1, requests[i].origin, kNormalLoadFlags, false)); + EXPECT_CALL(*mock_network_context_, + PreconnectSockets(1, requests[i].origin, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); EXPECT_CALL(*mock_network_context_, ResolveHostProxy(requests[i].origin.host())); } @@ -286,9 +293,10 @@ } EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url_1)); for (size_t i = 0; i < count - 1; ++i) { - EXPECT_CALL( - *mock_network_context_, - PreconnectSockets(1, requests[i].origin, kNormalLoadFlags, false)); + EXPECT_CALL(*mock_network_context_, + PreconnectSockets(1, requests[i].origin, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); } preconnect_manager_->Start( @@ -326,10 +334,12 @@ EXPECT_CALL(*mock_network_context_, PreconnectSockets(1, requests[count - 1].origin, kNormalLoadFlags, - false)); - EXPECT_CALL( - *mock_network_context_, - PreconnectSockets(1, requests[count].origin, kNormalLoadFlags, false)); + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); + EXPECT_CALL(*mock_network_context_, + PreconnectSockets(1, requests[count].origin, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); mock_network_context_->CompleteHostLookup(requests[count - 1].origin.host(), net::OK); @@ -387,12 +397,14 @@ EXPECT_CALL(*mock_network_context_, ResolveHostProxy(url_to_preconnect_2.host())); EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url_2)); - EXPECT_CALL( - *mock_network_context_, - PreconnectSockets(1, url_to_preconnect_1, kNormalLoadFlags, false)); - EXPECT_CALL( - *mock_network_context_, - PreconnectSockets(1, url_to_preconnect_2, kNormalLoadFlags, false)); + EXPECT_CALL(*mock_network_context_, + PreconnectSockets(1, url_to_preconnect_1, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); + EXPECT_CALL(*mock_network_context_, + PreconnectSockets(1, url_to_preconnect_2, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); preconnect_manager_->Start(main_frame_url_2, {PreconnectRequest(url_to_preconnect_1, 1), PreconnectRequest(url_to_preconnect_2, 1)}); @@ -433,12 +445,14 @@ ResolveHostProxy(url_to_preconnect_1.host())); EXPECT_CALL(*mock_network_context_, ResolveHostProxy(url_to_preconnect_2.host())); - EXPECT_CALL( - *mock_network_context_, - PreconnectSockets(1, url_to_preconnect_1, kNormalLoadFlags, false)); - EXPECT_CALL( - *mock_network_context_, - PreconnectSockets(1, url_to_preconnect_2, kNormalLoadFlags, false)); + EXPECT_CALL(*mock_network_context_, + PreconnectSockets(1, url_to_preconnect_1, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); + EXPECT_CALL(*mock_network_context_, + PreconnectSockets(1, url_to_preconnect_2, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url)); preconnect_manager_->Start(main_frame_url, {PreconnectRequest(url_to_preconnect_1, 1), @@ -519,9 +533,10 @@ preconnect_manager_->Stop(main_frame_url2); // Stopping the second url shouldn't stop the first one. - EXPECT_CALL( - *mock_network_context_, - PreconnectSockets(1, url_to_preconnect1, kNormalLoadFlags, false)); + EXPECT_CALL(*mock_network_context_, + PreconnectSockets(1, url_to_preconnect1, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url1)); mock_network_context_->CompleteHostLookup(url_to_preconnect1.host(), net::OK); // No preconnect for the second url. @@ -546,9 +561,10 @@ preconnect_manager_->Start(main_frame_url2, {PreconnectRequest(url_to_preconnect2, 1)}); - EXPECT_CALL( - *mock_network_context_, - PreconnectSockets(1, url_to_preconnect1, kNormalLoadFlags, false)); + EXPECT_CALL(*mock_network_context_, + PreconnectSockets(1, url_to_preconnect1, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url1)); mock_network_context_->CompleteHostLookup(url_to_preconnect1.host(), net::OK); } @@ -588,7 +604,8 @@ EXPECT_CALL( *mock_network_context_, - PreconnectSockets(1, origin, kPrivateLoadFlags, !allow_credentials)); + PreconnectSockets(1, origin, kPrivateLoadFlags, !allow_credentials, + base::Optional<net::NetworkIsolationKey>())); mock_network_context_->CompleteHostLookup(origin.host(), net::OK); // Non http url shouldn't be preconnected. @@ -642,7 +659,9 @@ {PreconnectRequest(url_to_preconnect, 1)}); EXPECT_CALL(*mock_network_context_, - PreconnectSockets(1, url_to_preconnect, kNormalLoadFlags, false)); + PreconnectSockets(1, url_to_preconnect, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url)); mock_network_context_->CompleteProxyLookup(url_to_preconnect, GetIndirectProxyInfo()); @@ -669,10 +688,13 @@ Mock::VerifyAndClearExpectations(mock_network_context_.get()); EXPECT_CALL(*mock_network_context_, - PreconnectSockets(1, url_to_preconnect, kNormalLoadFlags, false)); - EXPECT_CALL( - *mock_network_context_, - PreconnectSockets(1, url_to_preconnect2, kNormalLoadFlags, false)); + PreconnectSockets(1, url_to_preconnect, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); + EXPECT_CALL(*mock_network_context_, + PreconnectSockets(1, url_to_preconnect2, kNormalLoadFlags, + false /* privacy_mode_enabled */, + base::Optional<net::NetworkIsolationKey>())); EXPECT_CALL(*mock_delegate_, PreconnectFinishedProxy(main_frame_url)); mock_network_context_->CompleteHostLookup(url_to_preconnect.host(), net::OK); mock_network_context_->CompleteHostLookup(url_to_preconnect2.host(), net::OK);
diff --git a/chrome/browser/predictors/predictors_features.cc b/chrome/browser/predictors/predictors_features.cc new file mode 100644 index 0000000..1c31975 --- /dev/null +++ b/chrome/browser/predictors/predictors_features.cc
@@ -0,0 +1,14 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/predictors/predictors_features.h" + +namespace features { + +// Modifies loading predictor so that it only learns about subresources and +// origins that are high priority. +const base::Feature kLoadingOnlyLearnHighPriorityResources{ + "LoadingOnlyLearnHighPriorityResources", base::FEATURE_DISABLED_BY_DEFAULT}; + +} // namespace features
diff --git a/chrome/browser/predictors/predictors_features.h b/chrome/browser/predictors/predictors_features.h new file mode 100644 index 0000000..5c9fd1e --- /dev/null +++ b/chrome/browser/predictors/predictors_features.h
@@ -0,0 +1,19 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PREDICTORS_PREDICTORS_FEATURES_H_ +#define CHROME_BROWSER_PREDICTORS_PREDICTORS_FEATURES_H_ + +#include "base/feature_list.h" + +namespace features { + +// All features in alphabetical order. The features should be documented +// alongside the definition of their values in the .cc file. + +extern const base::Feature kLoadingOnlyLearnHighPriorityResources; + +} // namespace features + +#endif // CHROME_BROWSER_PREDICTORS_PREDICTORS_FEATURES_H_
diff --git a/chrome/browser/previews/previews_content_util.cc b/chrome/browser/previews/previews_content_util.cc index 3337f8442..c5826e6 100644 --- a/chrome/browser/previews/previews_content_util.cc +++ b/chrome/browser/previews/previews_content_util.cc
@@ -275,6 +275,12 @@ bool should_load_page_hints = false; if (previews_decider->ShouldAllowPreviewAtNavigationStart( previews_data, url, is_reload, + previews::PreviewsType::DEFER_ALL_SCRIPT)) { + previews_state |= content::DEFER_ALL_SCRIPT_ON; + should_load_page_hints = true; + } + if (previews_decider->ShouldAllowPreviewAtNavigationStart( + previews_data, url, is_reload, previews::PreviewsType::RESOURCE_LOADING_HINTS)) { previews_state |= content::RESOURCE_LOADING_HINTS_ON; should_load_page_hints = true; @@ -383,6 +389,21 @@ // Make priority decision among allowed client preview types that can be // decided at Commit time. + + if (previews_state & content::DEFER_ALL_SCRIPT_ON) { + // DeferAllScript was allowed for the original URL but only continue with it + // if the committed URL has HTTPS scheme and is allowed by decider. + if (is_https && previews_decider && + previews_decider->ShouldCommitPreview( + previews_data, url, previews::PreviewsType::DEFER_ALL_SCRIPT)) { + LogCommittedPreview(previews_data, PreviewsType::DEFER_ALL_SCRIPT); + return content::DEFER_ALL_SCRIPT_ON; + } + // Remove DEFER_ALL_SCRIPT_ON from |previews_state| since we decided not to + // commit to it. + previews_state = previews_state & ~content::DEFER_ALL_SCRIPT_ON; + } + if (previews_state & content::RESOURCE_LOADING_HINTS_ON) { // Resource loading hints was chosen for the original URL but only continue // with it if the committed URL has HTTPS scheme and is allowed by decider. @@ -505,6 +526,8 @@ return previews::PreviewsType::LITE_PAGE_REDIRECT; if (previews_state & content::SERVER_LITE_PAGE_ON) return previews::PreviewsType::LITE_PAGE; + if (previews_state & content::DEFER_ALL_SCRIPT_ON) + return previews::PreviewsType::DEFER_ALL_SCRIPT; if (previews_state & content::RESOURCE_LOADING_HINTS_ON) return previews::PreviewsType::RESOURCE_LOADING_HINTS; if (previews_state & content::NOSCRIPT_ON)
diff --git a/chrome/browser/previews/previews_content_util_unittest.cc b/chrome/browser/previews/previews_content_util_unittest.cc index 34aa05cd..51e1ac6 100644 --- a/chrome/browser/previews/previews_content_util_unittest.cc +++ b/chrome/browser/previews/previews_content_util_unittest.cc
@@ -71,7 +71,8 @@ const GURL& url, PreviewsType type) const override { EXPECT_TRUE(type == PreviewsType::NOSCRIPT || - type == PreviewsType::RESOURCE_LOADING_HINTS); + type == PreviewsType::RESOURCE_LOADING_HINTS || + type == PreviewsType::DEFER_ALL_SCRIPT); return IsEnabled(type); } @@ -219,6 +220,31 @@ } TEST_F(PreviewsContentUtilTest, + DetermineAllowedClientPreviewsStateDeferAllScript) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitFromCommandLine("Previews,DeferAllScript", + std::string()); + PreviewsUserData user_data(1); + bool is_reload = false; + bool previews_triggering_logic_already_ran = false; + bool is_data_saver_user = true; + // Allowed for start of HTTPS navigation. + EXPECT_LT(0, + content::DEFER_ALL_SCRIPT_ON & + previews::CallDetermineAllowedClientPreviewsState( + &user_data, GURL("https://www.google.com"), is_reload, + previews_triggering_logic_already_ran, is_data_saver_user, + enabled_previews_decider(), nullptr)); + // Allowed for start of HTTP navigation. + EXPECT_LT(0, + content::DEFER_ALL_SCRIPT_ON & + previews::CallDetermineAllowedClientPreviewsState( + &user_data, GURL("http://www.google.com"), is_reload, + previews_triggering_logic_already_ran, is_data_saver_user, + enabled_previews_decider(), nullptr)); +} + +TEST_F(PreviewsContentUtilTest, DetermineAllowedClientPreviewsStateResourceLoadingHints) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitFromCommandLine("Previews,ResourceLoadingHints", @@ -322,7 +348,8 @@ TEST_F(PreviewsContentUtilTest, DetermineCommittedClientPreviewsState) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitFromCommandLine( - "Previews,NoScriptPreviews,ResourceLoadingHints", std::string()); + "Previews,NoScriptPreviews,ResourceLoadingHints,DeferAllScript", + std::string()); PreviewsUserData user_data(1); user_data.set_navigation_ect(net::EFFECTIVE_CONNECTION_TYPE_2G); base::HistogramTester histogram_tester; @@ -371,6 +398,19 @@ // Try different navigation ECT value. user_data.set_navigation_ect(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G); + // DeferAllScript has precedence over NoScript and ResourceLoadingHints. + EXPECT_EQ(content::DEFER_ALL_SCRIPT_ON, + previews::DetermineCommittedClientPreviewsState( + &user_data, GURL("https://www.google.com"), + content::DEFER_ALL_SCRIPT_ON | content::NOSCRIPT_ON | + content::RESOURCE_LOADING_HINTS_ON, + enabled_previews_decider(), nullptr)); + histogram_tester.ExpectBucketCount( + "Previews.Triggered.EffectiveConnectionType2.DeferAllScript", + static_cast<int>(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G), 1); + histogram_tester.ExpectTotalCount( + "Previews.Triggered.EffectiveConnectionType2", 4); + // RESOURCE_LOADING_HINTS has precedence over NoScript. EXPECT_EQ(content::RESOURCE_LOADING_HINTS_ON, previews::DetermineCommittedClientPreviewsState( @@ -381,7 +421,7 @@ "Previews.Triggered.EffectiveConnectionType2.ResourceLoadingHints", static_cast<int>(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G), 1); histogram_tester.ExpectTotalCount( - "Previews.Triggered.EffectiveConnectionType2", 4); + "Previews.Triggered.EffectiveConnectionType2", 5); // Only NoScript: EXPECT_EQ(content::NOSCRIPT_ON, @@ -390,6 +430,36 @@ content::NOSCRIPT_ON, enabled_previews_decider(), nullptr)); } +TEST_F(PreviewsContentUtilTest, DetermineCommittedClientPreviewsStateForHttp) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitFromCommandLine( + "Previews,NoScriptPreviews,ResourceLoadingHints,DeferAllScript", + std::string()); + PreviewsUserData user_data(1); + user_data.set_navigation_ect(net::EFFECTIVE_CONNECTION_TYPE_2G); + base::HistogramTester histogram_tester; + + // Verify that currently these previews do not commit on HTTP. + EXPECT_EQ(content::PREVIEWS_OFF, + previews::DetermineCommittedClientPreviewsState( + &user_data, GURL("http://www.google.com"), + content::NOSCRIPT_ON | content::RESOURCE_LOADING_HINTS_ON | + content::DEFER_ALL_SCRIPT_ON, + enabled_previews_decider(), nullptr)); + histogram_tester.ExpectTotalCount( + "Previews.Triggered.EffectiveConnectionType2", 0); + + // Ensure one does commit on HTTPS (to confirm test setup). + EXPECT_NE(content::PREVIEWS_OFF, + previews::DetermineCommittedClientPreviewsState( + &user_data, GURL("https://www.google.com"), + content::NOSCRIPT_ON | content::RESOURCE_LOADING_HINTS_ON | + content::DEFER_ALL_SCRIPT_ON, + enabled_previews_decider(), nullptr)); + histogram_tester.ExpectTotalCount( + "Previews.Triggered.EffectiveConnectionType2", 1); +} + TEST_F(PreviewsContentUtilTest, DetermineCommittedClientPreviewsStateNoScriptCheckIfStillAllowed) { base::test::ScopedFeatureList scoped_feature_list; @@ -437,6 +507,8 @@ previews::GetMainFramePreviewsType(content::RESOURCE_LOADING_HINTS_ON)); EXPECT_EQ(previews::PreviewsType::LITE_PAGE_REDIRECT, previews::GetMainFramePreviewsType(content::LITE_PAGE_REDIRECT_ON)); + EXPECT_EQ(previews::PreviewsType::DEFER_ALL_SCRIPT, + previews::GetMainFramePreviewsType(content::DEFER_ALL_SCRIPT_ON)); // NONE cases: EXPECT_EQ(previews::PreviewsType::NONE, @@ -456,10 +528,14 @@ EXPECT_EQ(previews::PreviewsType::RESOURCE_LOADING_HINTS, previews::GetMainFramePreviewsType( content::NOSCRIPT_ON | content::RESOURCE_LOADING_HINTS_ON)); + EXPECT_EQ(previews::PreviewsType::DEFER_ALL_SCRIPT, + previews::GetMainFramePreviewsType( + content::NOSCRIPT_ON | content::RESOURCE_LOADING_HINTS_ON | + content::DEFER_ALL_SCRIPT_ON)); EXPECT_EQ(previews::PreviewsType::LITE_PAGE_REDIRECT, previews::GetMainFramePreviewsType( content::NOSCRIPT_ON | content::RESOURCE_LOADING_HINTS_ON | - content::LITE_PAGE_REDIRECT_ON)); + content::DEFER_ALL_SCRIPT_ON | content::LITE_PAGE_REDIRECT_ON)); } class PreviewsContentSimulatedNavigationTest
diff --git a/chrome/browser/previews/previews_top_host_provider_impl.cc b/chrome/browser/previews/previews_top_host_provider_impl.cc index 9d0700e..8a2408a1 100644 --- a/chrome/browser/previews/previews_top_host_provider_impl.cc +++ b/chrome/browser/previews/previews_top_host_provider_impl.cc
@@ -7,6 +7,7 @@ #include "base/metrics/histogram_macros.h" #include "base/values.h" #include "chrome/browser/engagement/site_engagement_details.mojom.h" +#include "chrome/browser/engagement/site_engagement_score.h" #include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" #include "components/prefs/pref_service.h" @@ -203,6 +204,13 @@ for (const auto& detail : engagement_details) { if (top_hosts.size() >= max_sites) return top_hosts; + // Once the engagement score is less than the initial engagement score for a + // newly navigated host, return the current set of top hosts. This threshold + // prevents hosts that have not been engaged recently from having hints + // requested for them. The engagement_details are sorted above in descending + // order by engagement score. + if (detail.total_score <= GetMinTopHostEngagementThreshold()) + return top_hosts; // TODO(b/968542): Skip origins that are local hosts (e.g., IP addresses, // localhost:8080 etc.). if (detail.origin.SchemeIs(url::kHttpsScheme) && @@ -214,4 +222,13 @@ return top_hosts; } +size_t PreviewsTopHostProviderImpl::GetMinTopHostEngagementThreshold() const { + // The base score for the first navigation of a host when added to the site + // engagement service. The threshold corresponds to the minimum score that a + // host is considered to be a top host, hosts with a lower score have not + // been navigated to recently. + return SiteEngagementScore::GetNavigationPoints() + + SiteEngagementScore::GetFirstDailyEngagementPoints(); +} + } // namespace previews
diff --git a/chrome/browser/previews/previews_top_host_provider_impl.h b/chrome/browser/previews/previews_top_host_provider_impl.h index dd13886..0c19316 100644 --- a/chrome/browser/previews/previews_top_host_provider_impl.h +++ b/chrome/browser/previews/previews_top_host_provider_impl.h
@@ -50,6 +50,10 @@ optimization_guide::prefs::HintsFetcherTopHostBlacklistState GetCurrentBlacklistState() const; + // The minimum engagement score that a host must have to be considered a top + // host by |this|. + size_t GetMinTopHostEngagementThreshold() const; + // Transition the current HintsFetcherTopHostBlacklist state to |state| and // validate the transition. The updated state is persisted in the // |kHintsFetcherTopHostBlacklistState| pref.
diff --git a/chrome/browser/previews/previews_top_host_provider_impl_unittest.cc b/chrome/browser/previews/previews_top_host_provider_impl_unittest.cc index c1d20ea3..f6ad6914 100644 --- a/chrome/browser/previews/previews_top_host_provider_impl_unittest.cc +++ b/chrome/browser/previews/previews_top_host_provider_impl_unittest.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/previews/previews_top_host_provider_impl.h" #include "base/values.h" +#include "chrome/browser/engagement/site_engagement_score.h" #include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" @@ -31,8 +32,10 @@ void AddEngagedHosts(size_t num_hosts) { for (size_t i = 1; i <= num_hosts; i++) { - AddEngagedHost(GURL(base::StringPrintf("https://domain%zu.com", i)), - static_cast<int>(i)); + AddEngagedHost( + GURL(base::StringPrintf("https://domain%zu.com", i)), + static_cast<int>( + i + SiteEngagementScore::GetFirstDailyEngagementPoints())); } } @@ -326,4 +329,37 @@ EXPECT_FALSE(IsHostBlacklisted(base::StringPrintf("domain%u.com", 1u))); } +TEST_F(PreviewsTopHostProviderImplTest, TopHostsFilteredByEngagementThreshold) { + size_t engaged_hosts = + previews::params::MaxHintsFetcherTopHostBlacklistSize() + 1; + size_t max_top_hosts = + previews::params::MaxHintsFetcherTopHostBlacklistSize() + 1; + + AddEngagedHosts(engaged_hosts); + // Add two hosts with very low engagement scores that should not be returned + // by the top host provider. + AddEngagedHost(GURL("https://lowengagement.com"), 1); + AddEngagedHost(GURL("https://lowengagement2.com"), 1); + + // Blacklist should be populated on the first request. + std::vector<std::string> hosts = + top_host_provider()->GetTopHosts(max_top_hosts); + EXPECT_EQ(hosts.size(), 0u); + + hosts = top_host_provider()->GetTopHosts(max_top_hosts); + EXPECT_EQ( + hosts.size(), + engaged_hosts - previews::params::MaxHintsFetcherTopHostBlacklistSize()); + EXPECT_EQ(GetCurrentTopHostBlacklistState(), + optimization_guide::prefs::HintsFetcherTopHostBlacklistState:: + kInitialized); + + // The hosts with engagement scores below the minimum threshold should not be + // returned. + EXPECT_EQ(std::find(hosts.begin(), hosts.end(), "lowengagement.com"), + hosts.end()); + EXPECT_EQ(std::find(hosts.begin(), hosts.end(), "lowengagement2.com"), + hosts.end()); +} + } // namespace previews
diff --git a/chrome/browser/resources/chromeos/login/gaia_button.css b/chrome/browser/resources/chromeos/login/gaia_button.css index e4c3375..1424655 100644 --- a/chrome/browser/resources/chromeos/login/gaia_button.css +++ b/chrome/browser/resources/chromeos/login/gaia_button.css
@@ -6,38 +6,25 @@ display: inline-block; } -paper-button { - background-color: var(--google-blue-500); - color: white; - font-size: 14px; - min-width: 90px; -} - -:host([type='link']) paper-button, -:host([type='dialog']) paper-button { +:host([link]) cr-button { background-color: transparent; + border: none; + border-radius: 0; + box-shadow: none; color: var(--google-blue-600); - margin: 0; + font-weight: 400; + margin: 0 -0.57em; min-width: 0; } -:host([type='link']) paper-button[focused], -:host([type='dialog']) paper-button[focused] { +:host([link]) cr-button:focus { background-color: rgba(66, 133, 244, 0.12); } -:host([type='link']) paper-button[disabled], -:host([type='dialog']) paper-button[disabled] { - color: rgb(168,168,168); +:host-context(.focus-outline-visible):host([link]) cr-button:focus { + font-weight: 500; } -:host([type='dialog']) paper-button { - padding: 8px 12px; -} - -:host([type='link']) paper-button { - border-radius: 0; - margin-left: -0.57em; - margin-right: -0.57em; - text-transform: none; +:host([link]) cr-button[disabled] { + color: rgb(168, 168, 168); }
diff --git a/chrome/browser/resources/chromeos/login/gaia_buttons.html b/chrome/browser/resources/chromeos/login/gaia_buttons.html index b231cfa..855db8a 100644 --- a/chrome/browser/resources/chromeos/login/gaia_buttons.html +++ b/chrome/browser/resources/chromeos/login/gaia_buttons.html
@@ -4,32 +4,29 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> <!-- Material design buttons that mimic GAIA's buttons. Example: - <gaia-button type="dialog"></gaia-button> + <gaia-button link></gaia-button> Attributes: - 'type' - there are three kinds of button: regular blue button (none type - provided), dialog button (type="dialog") and a button that looks - more like a link (type="link"). + 'link' - there are two kinds of button: regular blue button and a button + that looks more like a link. 'disabled' - button is disabled when the attribute is set. --> <dom-module id="gaia-button"> <link rel="stylesheet" href="gaia_button.css"> <template> - <div on-click="onClick_" on-tap="onClick_"> - <paper-button id="button" disabled="[[disabled]]" - on-focused-changed="focusedChanged_"> - <slot></slot> - </paper-button> - </div> + <cr-button id="button" disabled="[[disabled]]" on-click="onClick_" + noink$="[[link]]"> + <slot></slot> + </cr-button> </template> </dom-module>
diff --git a/chrome/browser/resources/chromeos/login/gaia_buttons.js b/chrome/browser/resources/chromeos/login/gaia_buttons.js index c241f22..f8d2936f 100644 --- a/chrome/browser/resources/chromeos/login/gaia_buttons.js +++ b/chrome/browser/resources/chromeos/login/gaia_buttons.js
@@ -2,26 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/** @enum {string} */ -const GaiaButtonType = { - NONE: '', - LINK: 'link', - DIALOG: 'dialog', -}; - Polymer({ is: 'gaia-button', properties: { - disabled: {type: Boolean, value: false, reflectToAttribute: true}, - - /** @type GaiaButtonType */ - type: { - type: String, - value: GaiaButtonType.NONE, + disabled: { + type: Boolean, + value: false, reflectToAttribute: true, - observer: 'typeChanged_' - } + }, + + link: { + type: Boolean, + value: false, + reflectToAttribute: true, + observer: 'onLinkChanged_', + }, }, focus: function() { @@ -29,45 +25,47 @@ }, /** @private */ - focusedChanged_: function() { - if (this.type == GaiaButtonType.LINK || this.type == GaiaButtonType.DIALOG) - return; - this.$.button.raised = this.$.button.focused; + onLinkChanged_: function() { + this.$.button.classList.toggle('action-button', !this.link); }, - /** @private */ - typeChanged_: function() { - if (this.type == GaiaButtonType.LINK) - this.$.button.setAttribute('noink', ''); - else - this.$.button.removeAttribute('noink'); - }, - - /** @private */ + /** + * @param {!Event} e + * @private + */ onClick_: function(e) { - if (this.disabled) + if (this.disabled) { e.stopPropagation(); - } + } + }, }); Polymer({ is: 'gaia-icon-button', properties: { - disabled: {type: Boolean, value: false, reflectToAttribute: true}, + disabled: { + type: Boolean, + value: false, + reflectToAttribute: true, + }, icon: String, - ariaLabel: String + ariaLabel: String, }, focus: function() { this.$.iconButton.focus(); }, - /** @private */ + /** + * @param {!Event} e + * @private + */ onClick_: function(e) { - if (this.disabled) + if (this.disabled) { e.stopPropagation(); - } + } + }, });
diff --git a/chrome/browser/resources/chromeos/login/gaia_input_form.html b/chrome/browser/resources/chromeos/login/gaia_input_form.html index 81abfc6..9067bbb 100644 --- a/chrome/browser/resources/chromeos/login/gaia_input_form.html +++ b/chrome/browser/resources/chromeos/login/gaia_input_form.html
@@ -31,7 +31,7 @@ <div on-keydown="onKeyDown_"> <slot id="inputs" name="inputs"></slot> <div class="horizontal-reverse justified layout center"> - <gaia-button id="button" on-tap="onButtonClicked_" class="self-end" + <gaia-button id="button" on-click="onButtonClicked_" class="self-end" hidden="[[!buttonText]]"> <span>[[buttonText]]</span> </gaia-button>
diff --git a/chrome/browser/resources/chromeos/login/gaia_password_changed.html b/chrome/browser/resources/chromeos/login/gaia_password_changed.html index 974db4a..9d7d6f6 100644 --- a/chrome/browser/resources/chromeos/login/gaia_password_changed.html +++ b/chrome/browser/resources/chromeos/login/gaia_password_changed.html
@@ -66,10 +66,9 @@ <div slot="label" i18n-content="oldPasswordHint"></div> <div slot="error" i18n-content="oldPasswordIncorrect"></div> </gaia-input> - <gaia-button id="forgot-password-link" type="link" - on-tap="onForgotPasswordClicked_" - i18n-content="forgotOldPasswordButtonText"> - </gaia-button> + <gaia-button id="forgot-password-link" + on-click="onForgotPasswordClicked_" + i18n-content="forgotOldPasswordButtonText" link></gaia-button> </gaia-input-form> </gaia-card> </neon-animatable> @@ -84,13 +83,10 @@ </p> </div> <div class="horizontal layout justified center"> - <gaia-button id="try-again-link" type="link" - on-tap="onTryAgainClicked_" - i18n-content="passwordChangedTryAgain"> - </gaia-button> - <gaia-button id="proceedAnywayBtn" on-tap="onProceedClicked_" - i18n-content="proceedAnywayButton"> - </gaia-button> + <gaia-button id="try-again-link" on-click="onTryAgainClicked_" + i18n-content="passwordChangedTryAgain" link></gaia-button> + <gaia-button id="proceedAnywayBtn" on-click="onProceedClicked_" + i18n-content="proceedAnywayButton"></gaia-button> </div> </div> </gaia-card>
diff --git a/chrome/browser/resources/chromeos/login/notification_card.html b/chrome/browser/resources/chromeos/login/notification_card.html index f1e36c6..c11da97 100644 --- a/chrome/browser/resources/chromeos/login/notification_card.html +++ b/chrome/browser/resources/chromeos/login/notification_card.html
@@ -55,7 +55,7 @@ </div> </div> <div class="self-stretch horizontal-reverse layout justified center"> - <gaia-button id="submitButton" on-tap="buttonClicked_" + <gaia-button id="submitButton" on-click="buttonClicked_" hidden$="[[!buttonLabel]]"> <span>[[buttonLabel]]</span> </gaia-button>
diff --git a/chrome/browser/resources/chromeos/login/offline_ad_login.html b/chrome/browser/resources/chromeos/login/offline_ad_login.html index b731571f..6453138 100644 --- a/chrome/browser/resources/chromeos/login/offline_ad_login.html +++ b/chrome/browser/resources/chromeos/login/offline_ad_login.html
@@ -135,9 +135,8 @@ error-message="[[i18nDynamic(locale, 'adLoginInvalidPassword')]]"> </cr-input> <div class="flex layout horizontal start-justified"> - <gaia-button id="moreOptionsBtn" type="link" - on-tap="onMoreOptionsClicked_" hidden="[[!isDomainJoin]]" - disabled="[[disabled]]"> + <gaia-button id="moreOptionsBtn" on-click="onMoreOptionsClicked_" + hidden="[[!isDomainJoin]]" disabled="[[disabled]]" link> [[i18nDynamic(locale, 'adJoinMoreOptions')]] </gaia-button> </div>
diff --git a/chrome/browser/resources/chromeos/login/offline_gaia.html b/chrome/browser/resources/chromeos/login/offline_gaia.html index 1a9ef89..ef64cd6 100644 --- a/chrome/browser/resources/chromeos/login/offline_gaia.html +++ b/chrome/browser/resources/chromeos/login/offline_gaia.html
@@ -97,7 +97,7 @@ [[i18nDynamic(locale, 'offlineLoginInvalidPassword')]] </div> </gaia-input> - <gaia-button type="link" on-tap="onForgotPasswordClicked_"> + <gaia-button on-click="onForgotPasswordClicked_" link> [[i18nDynamic(locale, 'offlineLoginForgotPasswordBtn')]] </gaia-button> </gaia-input-form>
diff --git a/chrome/browser/resources/chromeos/login/saml_interstitial.html b/chrome/browser/resources/chromeos/login/saml_interstitial.html index 76c9f43c..4d74ab4 100644 --- a/chrome/browser/resources/chromeos/login/saml_interstitial.html +++ b/chrome/browser/resources/chromeos/login/saml_interstitial.html
@@ -56,10 +56,9 @@ <gaia-input-form id="samlInterstitialForm" on-submit="onSamlPageNextClicked_" i18n-values="button-text:samlInterstitialNextBtn"> - <gaia-button id="changeAccountLink" type="link" - on-tap="onSamlPageChangeAccountClicked_" - i18n-content="samlInterstitialChangeAccountLink"> - </gaia-button> + <gaia-button id="changeAccountLink" + on-click="onSamlPageChangeAccountClicked_" + i18n-content="samlInterstitialChangeAccountLink" link></gaia-button> </gaia-input-form> <img id="logo-img" src="chrome://theme/IDR_LOGO_GOOGLE_COLOR_90"
diff --git a/chrome/browser/resources/local_ntp/customize.js b/chrome/browser/resources/local_ntp/customize.js index 8224f65b2..7b5a97e 100644 --- a/chrome/browser/resources/local_ntp/customize.js +++ b/chrome/browser/resources/local_ntp/customize.js
@@ -303,7 +303,7 @@ const attributions = $(customize.IDS.ATTRIBUTIONS); attributions.removeAttribute('href'); attributions.className = ''; - attributions.style.cursor = 'none'; + attributions.style.cursor = 'default'; while (attributions.firstChild) { attributions.removeChild(attributions.firstChild); }
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.html b/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.html index 66fec66..43cbd7a 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.html +++ b/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.html
@@ -132,7 +132,7 @@ </a> <!-- TODO(jamescook): Rename path to "/assistant". --> <a href="/search" hidden="[[!showAssistant]]"> - <iron-icon icon="cr:search"></iron-icon> + <iron-icon icon="settings:assistant"></iron-icon> $i18n{osAssistantPageTitle} </a> <a href="/apps" hidden="[[!showApps]]">
diff --git a/chrome/browser/resources/settings/icons.html b/chrome/browser/resources/settings/icons.html index 01400a0..b160fae 100644 --- a/chrome/browser/resources/settings/icons.html +++ b/chrome/browser/resources/settings/icons.html
@@ -40,6 +40,7 @@ <if expr="chromeos"> <!-- Icons from http://icons/ --> + <g id="assistant"><path d="M18.636 6.364a1.364 1.364 0 1 1 .001-2.729 1.364 1.364 0 0 1 0 2.729zm-4.09 4.545a2.727 2.727 0 1 1 0-5.454 2.727 2.727 0 0 1 0 5.454zm0 7.273a3.182 3.182 0 1 1 0-6.364 3.182 3.182 0 0 1 0 6.364zM10.908 5.455a5.455 5.455 0 1 1-10.91 0 5.455 5.455 0 0 1 10.91 0z"></path></g> <g id="play-prism"><path fill="#5A5A5A" d="M20.18 10.88l-3.06-1.74L14.26 12l2.86 2.86 3.06-1.74c.55-.31.82-.71.82-1.12 0-.41-.27-.81-.82-1.12zM4.71 2.45l8.42 8.42 2.55-2.55-10.7-6.06c-.07-.04-.14-.07-.21-.1-.17-.07-.3.05-.15.21.03.02.06.05.09.08zm0 19.1l-.08.08c-.15.15-.02.28.15.21.07-.03.14-.06.21-.1l10.69-6.06-2.55-2.55s-7.2 7.21-8.42 8.42zM12 12L3.38 3.38c-.19-.19-.38-.07-.38.19v16.86c0 .26.19.38.38.19L12 12z"></path></g> <!-- Apps icon for Settings drawer -->
diff --git a/chrome/browser/resources/settings/people_page/people_page.html b/chrome/browser/resources/settings/people_page/people_page.html index c73ed57..4f37839 100644 --- a/chrome/browser/resources/settings/people_page/people_page.html +++ b/chrome/browser/resources/settings/people_page/people_page.html
@@ -115,22 +115,16 @@ right: 0; } - settings-sync-account-control[showing-promo] { - --promo-banner: { - /* Make the banner image stay within setting-section's card border - radius. */ - border-top-left-radius: var(--cr-card-border-radius); - border-top-right-radius: var(--cr-card-border-radius); - } - /* When showing promo in this page, text should be larger. */ - --promo-description: { - font-size: 0.9rem; - line-height: 1.625rem; - } - --promo-title: { - font-size: 1.1rem; - line-height: 1.625rem; - } + settings-sync-account-control[showing-promo]::part(banner) { + /* Make the banner image stay within setting-section's card border + radius. */ + border-top-left-radius: var(--cr-card-border-radius); + border-top-right-radius: var(--cr-card-border-radius); + } + + settings-sync-account-control[showing-promo]::part(title) { + font-size: 1.1rem; + line-height: 1.625rem; } </if> </style>
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.html b/chrome/browser/resources/settings/people_page/sync_account_control.html index fb7b90dc..e299214 100644 --- a/chrome/browser/resources/settings/people_page/sync_account_control.html +++ b/chrome/browser/resources/settings/people_page/sync_account_control.html
@@ -126,8 +126,6 @@ background-size: 100% auto; display: none; padding-top: calc(120 / 680 * 100%); /* Keep background ratio. */ - - @apply --promo-banner; } @media (prefers-color-scheme: dark) { @@ -139,21 +137,13 @@ :host([showing-promo]) #banner { display: block; } - - :host([showing-promo]) #promo-title { - @apply --promo-title; - } - - :host([showing-promo]) #promo-description { - @apply --promo-description; - } </style> - <div id="banner" hidden="[[syncStatus.signedIn]]"></div> + <div id="banner" hidden="[[syncStatus.signedIn]]" part="banner"></div> <div class$="settings-box first [[getPromoHeaderClass_(subLabel_)]]" id="promo-header" hidden="[[syncStatus.signedIn]]"> <div class="start settings-box-text"> - <div id="promo-title"> + <div id="promo-title" part="title"> [[getLabel_(promoLabelWithAccount, promoLabelWithNoAccount, shownAccount_)]] </div>
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn index 67f3c6e..c11f85d 100644 --- a/chrome/browser/safe_browsing/BUILD.gn +++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -103,6 +103,7 @@ "//components/safe_browsing/password_protection", "//components/safe_browsing/triggers", "//components/safe_browsing/triggers:ad_popup_trigger", + "//components/safe_browsing/triggers:ad_redirect_trigger", "//components/safe_browsing/triggers:ad_sampler_trigger", "//components/safe_browsing/triggers:suspicious_site_trigger", "//components/safe_browsing/triggers:trigger_throttler",
diff --git a/chrome/browser/safe_browsing/ad_redirect_trigger_browsertest.cc b/chrome/browser/safe_browsing/ad_redirect_trigger_browsertest.cc new file mode 100644 index 0000000..aa4ea56 --- /dev/null +++ b/chrome/browser/safe_browsing/ad_redirect_trigger_browsertest.cc
@@ -0,0 +1,230 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/bind.h" +#include "base/memory/ref_counted.h" +#include "base/strings/strcat.h" +#include "base/strings/utf_string_conversions.h" +#include "base/test/metrics/histogram_tester.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/safe_browsing/trigger_creator.h" +#include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/prefs/testing_pref_service.h" +#include "components/safe_browsing/common/safe_browsing_prefs.h" +#include "components/safe_browsing/features.h" +#include "components/safe_browsing/triggers/ad_redirect_trigger.h" +#include "components/safe_browsing/triggers/mock_trigger_manager.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/content_browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace safe_browsing { + +class AdRedirectTriggerBrowserTest : public InProcessBrowserTest, + public UrlListManager::Observer { + public: + AdRedirectTriggerBrowserTest() = default; + + // InProcessBrowserTest: + void SetUpOnMainThread() override { + scoped_feature_list_.InitAndEnableFeature(kAdRedirectTriggerFeature); + + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(embedded_test_server()->Start()); + current_browser_ = InProcessBrowserTest::browser(); + FramebustBlockTabHelper::FromWebContents(GetWebContents()) + ->manager() + ->AddObserver(this); + } + + // UrlListManager::Observer: + void BlockedUrlAdded(int32_t id, const GURL& blocked_url) override { + if (!blocked_url_added_closure_.is_null()) + std::move(blocked_url_added_closure_).Run(); + } + + content::WebContents* GetWebContents() { + return browser()->tab_strip_model()->GetActiveWebContents(); + } + + FramebustBlockTabHelper* GetFramebustTabHelper() { + return FramebustBlockTabHelper::FromWebContents(GetWebContents()); + } + + Browser* browser() { return current_browser_; } + + void CreateAndSetBrowser() { + current_browser_ = CreateBrowser(browser()->profile()); + } + + bool NavigateIframeToUrlWithoutGesture(content::WebContents* contents, + const std::string iframe_id, + const GURL& url) { + const char kScript[] = R"( + var iframe = document.getElementById('%s'); + iframe.src='%s' + )"; + content::TestNavigationObserver load_observer(contents); + bool result = content::ExecuteScriptWithoutUserGesture( + contents, + base::StringPrintf(kScript, iframe_id.c_str(), url.spec().c_str())); + load_observer.Wait(); + return result; + } + + void CreateTrigger() { + Profile* profile = + Profile::FromBrowserContext(GetWebContents()->GetBrowserContext()); + + profile->GetPrefs()->SetBoolean( + prefs::kSafeBrowsingExtendedReportingOptInAllowed, true); + profile->GetPrefs()->SetBoolean(prefs::kSafeBrowsingScoutReportingEnabled, + true); + + safe_browsing::TriggerCreator::MaybeCreateTriggersForWebContents( + profile, GetWebContents()); + safe_browsing::AdRedirectTrigger* ad_redirect_trigger = + safe_browsing::AdRedirectTrigger::FromWebContents(GetWebContents()); + ad_redirect_trigger->SetDelayForTest(0, 0); + } + + protected: + base::test::ScopedFeatureList scoped_feature_list_; + base::OnceClosure blocked_url_added_closure_; + Browser* current_browser_; +}; + +// Check that a report is sent when the source of a blocked redirect is an ad. +IN_PROC_BROWSER_TEST_F(AdRedirectTriggerBrowserTest, + BlockRedirectNavigation_FromAd) { + base::HistogramTester histogram_tester; + CreateTrigger(); + ui_test_utils::NavigateToURL(browser(), + embedded_test_server()->GetURL("/iframe.html")); + + // Sets the Iframe that will cause the blocked redirect to a google ad. + GURL child_url = + embedded_test_server()->GetURL("tpc.googlesyndication.com", "/safeframe"); + NavigateIframeToUrlWithoutGesture(GetWebContents(), "test", child_url); + + content::RenderFrameHost* child = + content::ChildFrameAt(GetWebContents()->GetMainFrame(), 0); + EXPECT_EQ(child_url, child->GetLastCommittedURL()); + + GURL redirect_url = embedded_test_server()->GetURL("b.com", "/title1.html"); + + base::RunLoop block_waiter; + blocked_url_added_closure_ = block_waiter.QuitWhenIdleClosure(); + child->ExecuteJavaScriptForTests( + base::ASCIIToUTF16(base::StringPrintf("window.top.location = '%s';", + redirect_url.spec().c_str())), + base::NullCallback()); + // Navigate away - this will trigger logging of the UMA. + ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); + + block_waiter.RunUntilIdle(); + + histogram_tester.ExpectBucketCount(kAdRedirectTriggerActionMetricName, + AdRedirectTriggerAction::REDIRECT_CHECK, + 1); + histogram_tester.ExpectBucketCount(kAdRedirectTriggerActionMetricName, + AdRedirectTriggerAction::AD_REDIRECT, 1); +} + +// Blocked redirect navigation will not trigger a report if the source of the +// redirect is not an ad frame, even if an ad frame exists on the same page. +IN_PROC_BROWSER_TEST_F(AdRedirectTriggerBrowserTest, + BlockRedirectNavigation_NotFromAdFrameOnPageWithAd) { + base::HistogramTester histogram_tester; + CreateTrigger(); + ui_test_utils::NavigateToURL(browser(), + embedded_test_server()->GetURL("/iframe.html")); + + // Create an ad subframe. + GetWebContents()->GetMainFrame()->ExecuteJavaScriptForTests( + base::ASCIIToUTF16("f = document.createElement('google_ads_iframe');" + "f.srcdoc = '<script>var x = 1</script>';" + "document.body.appendChild(f);"), + base::NullCallback()); + + // Cause blocked redirect + GURL child_url = embedded_test_server()->GetURL("a.com", "/title1.html"); + NavigateIframeToUrlWithoutGesture(GetWebContents(), "test", child_url); + + content::RenderFrameHost* child = + content::ChildFrameAt(GetWebContents()->GetMainFrame(), 0); + EXPECT_EQ(child_url, child->GetLastCommittedURL()); + + GURL redirect_url = embedded_test_server()->GetURL("b.com", "/title1.html"); + + base::RunLoop block_waiter; + blocked_url_added_closure_ = block_waiter.QuitClosure(); + child->ExecuteJavaScriptForTests( + base::ASCIIToUTF16(base::StringPrintf("window.top.location = '%s';", + redirect_url.spec().c_str())), + base::NullCallback()); + block_waiter.Run(); + + EXPECT_TRUE( + base::Contains(GetFramebustTabHelper()->blocked_urls(), redirect_url)); + + // Navigate away - this will trigger logging of the UMA. + ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); + histogram_tester.ExpectBucketCount(kAdRedirectTriggerActionMetricName, + AdRedirectTriggerAction::REDIRECT_CHECK, + 1); + histogram_tester.ExpectBucketCount( + kAdRedirectTriggerActionMetricName, + AdRedirectTriggerAction::REDIRECT_NO_GOOGLE_AD, 1); +} + +// Blocked redirect navigation will not trigger a report if the source of the +// redirect is not an ad frame. +IN_PROC_BROWSER_TEST_F(AdRedirectTriggerBrowserTest, + BlockRedirectNavigation_NoAdsOnPage) { + base::HistogramTester histogram_tester; + CreateTrigger(); + ui_test_utils::NavigateToURL(browser(), + embedded_test_server()->GetURL("/iframe.html")); + + // Cause blocked redirect + GURL child_url = embedded_test_server()->GetURL("a.com", "/title1.html"); + NavigateIframeToUrlWithoutGesture(GetWebContents(), "test", child_url); + + content::RenderFrameHost* child = + content::ChildFrameAt(GetWebContents()->GetMainFrame(), 0); + EXPECT_EQ(child_url, child->GetLastCommittedURL()); + + GURL redirect_url = embedded_test_server()->GetURL("b.com", "/title1.html"); + + base::RunLoop block_waiter; + blocked_url_added_closure_ = block_waiter.QuitClosure(); + child->ExecuteJavaScriptForTests( + base::ASCIIToUTF16(base::StringPrintf("window.top.location = '%s';", + redirect_url.spec().c_str())), + base::NullCallback()); + block_waiter.Run(); + + EXPECT_TRUE( + base::Contains(GetFramebustTabHelper()->blocked_urls(), redirect_url)); + + // Navigate away - this will trigger logging of the UMA. + ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); + histogram_tester.ExpectBucketCount(kAdRedirectTriggerActionMetricName, + AdRedirectTriggerAction::REDIRECT_CHECK, + 1); + histogram_tester.ExpectBucketCount( + kAdRedirectTriggerActionMetricName, + AdRedirectTriggerAction::REDIRECT_NO_GOOGLE_AD, 1); +} + +} // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/trigger_creator.cc b/chrome/browser/safe_browsing/trigger_creator.cc index 3208dc2..c494757 100644 --- a/chrome/browser/safe_browsing/trigger_creator.cc +++ b/chrome/browser/safe_browsing/trigger_creator.cc
@@ -11,6 +11,7 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/features.h" #include "components/safe_browsing/triggers/ad_popup_trigger.h" +#include "components/safe_browsing/triggers/ad_redirect_trigger.h" #include "components/safe_browsing/triggers/ad_sampler_trigger.h" #include "components/safe_browsing/triggers/suspicious_site_trigger.h" #include "components/safe_browsing/triggers/trigger_manager.h" @@ -66,6 +67,14 @@ HistoryServiceFactory::GetForProfile( profile, ServiceAccessType::EXPLICIT_ACCESS)); } + if (base::FeatureList::IsEnabled(kAdRedirectTriggerFeature) && + trigger_manager->CanStartDataCollection(options, + TriggerType::AD_REDIRECT)) { + safe_browsing::AdRedirectTrigger::CreateForWebContents( + web_contents, trigger_manager, profile->GetPrefs(), url_loader_factory, + HistoryServiceFactory::GetForProfile( + profile, ServiceAccessType::EXPLICIT_ACCESS)); + } TriggerManagerReason reason; if (trigger_manager->CanStartDataCollectionWithReason( options, TriggerType::SUSPICIOUS_SITE, &reason) ||
diff --git a/chrome/browser/ssl/security_state_tab_helper.cc b/chrome/browser/ssl/security_state_tab_helper.cc index 703c2e6..fd896e8 100644 --- a/chrome/browser/ssl/security_state_tab_helper.cc +++ b/chrome/browser/ssl/security_state_tab_helper.cc
@@ -210,6 +210,7 @@ case safe_browsing::SB_THREAT_TYPE_CSD_WHITELIST: case safe_browsing::SB_THREAT_TYPE_AD_SAMPLE: case safe_browsing::SB_THREAT_TYPE_BLOCKED_AD_POPUP: + case safe_browsing::SB_THREAT_TYPE_BLOCKED_AD_REDIRECT: case safe_browsing::SB_THREAT_TYPE_SUSPICIOUS_SITE: case safe_browsing::SB_THREAT_TYPE_APK_DOWNLOAD: case safe_browsing::SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST:
diff --git a/chrome/browser/ssl/ssl_client_certificate_selector.h b/chrome/browser/ssl/ssl_client_certificate_selector.h index 26dc9f1..b40fc45 100644 --- a/chrome/browser/ssl/ssl_client_certificate_selector.h +++ b/chrome/browser/ssl/ssl_client_certificate_selector.h
@@ -27,7 +27,10 @@ // |cert_request_info|. When the user has made a selection, the dialog will // report back to |delegate|. If the dialog is closed with no selection, // |delegate| will simply be destroyed. -void ShowSSLClientCertificateSelector( +// +// Returns a UI-thread callback that will cancel the dialog. The callback may be +// null depending on the implementation and is not required to be run. +base::OnceClosure ShowSSLClientCertificateSelector( content::WebContents* contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs,
diff --git a/chrome/browser/sync/test/integration/bookmarks_helper.cc b/chrome/browser/sync/test/integration/bookmarks_helper.cc index 02d9c9a..9c0d8328 100644 --- a/chrome/browser/sync/test/integration/bookmarks_helper.cc +++ b/chrome/browser/sync/test/integration/bookmarks_helper.cc
@@ -436,10 +436,10 @@ const BookmarkNode* foreign_node, const BookmarkNode** result) { // Climb the tree. - base::stack<int> path; + base::stack<size_t> path; const BookmarkNode* walker = foreign_node; while (walker != foreign_model->root_node()) { - path.push(walker->parent()->GetIndexOf(walker)); + path.push(size_t{walker->parent()->GetIndexOf(walker)}); walker = walker->parent(); } @@ -449,8 +449,8 @@ // Climb down. while (!path.empty()) { ASSERT_TRUE(walker->is_folder()); - ASSERT_LT(path.top(), walker->child_count()); - walker = walker->GetChild(path.top()); + ASSERT_LT(path.top(), walker->children().size()); + walker = walker->children()[path.top()].get(); path.pop(); } @@ -759,10 +759,10 @@ void RemoveAll(int profile) { if (sync_datatype_helper::test()->use_verifier()) { const BookmarkNode* root_node = GetVerifierBookmarkModel()->root_node(); - for (int i = 0; i < root_node->child_count(); ++i) { - const BookmarkNode* permanent_node = root_node->GetChild(i); - for (int j = permanent_node->child_count() - 1; j >= 0; --j) { - GetVerifierBookmarkModel()->Remove(permanent_node->GetChild(j)); + for (const auto& permanent_node : root_node->children()) { + while (!permanent_node->children().empty()) { + GetVerifierBookmarkModel()->Remove( + permanent_node->children().back().get()); } } }
diff --git a/chrome/browser/sync/test/integration/performance/bookmarks_sync_perf_test.cc b/chrome/browser/sync/test/integration/performance/bookmarks_sync_perf_test.cc index c6880c3..2b224106 100644 --- a/chrome/browser/sync/test/integration/performance/bookmarks_sync_perf_test.cc +++ b/chrome/browser/sync/test/integration/performance/bookmarks_sync_perf_test.cc
@@ -19,14 +19,14 @@ using sync_timing_helper::PrintResult; using sync_timing_helper::TimeMutualSyncCycle; -static const int kNumBookmarks = 150; +static const size_t kNumBookmarks = 150; class BookmarksSyncPerfTest : public SyncTest { public: BookmarksSyncPerfTest() : SyncTest(TWO_CLIENT) {} // Adds |num_urls| new unique bookmarks to the bookmark bar for |profile|. - void AddURLs(int profile, int num_urls); + void AddURLs(int profile, size_t num_urls); // Updates the URL for all bookmarks in the bookmark bar for |profile|. void UpdateURLs(int profile); @@ -35,7 +35,7 @@ void RemoveURLs(int profile); // Returns the number of bookmarks stored in the bookmark bar for |profile|. - int GetURLCount(int profile); + size_t GetURLCount(int profile); private: // Returns a new unique bookmark URL. @@ -49,21 +49,16 @@ DISALLOW_COPY_AND_ASSIGN(BookmarksSyncPerfTest); }; -void BookmarksSyncPerfTest::AddURLs(int profile, int num_urls) { - for (int i = 0; i < num_urls; ++i) { +void BookmarksSyncPerfTest::AddURLs(int profile, size_t num_urls) { + for (size_t i = 0; i < num_urls; ++i) { ASSERT_TRUE(AddURL(profile, 0, NextIndexedURLTitle(), GURL(NextIndexedURL())) != nullptr); } } void BookmarksSyncPerfTest::UpdateURLs(int profile) { - for (int i = 0; - i < GetBookmarkBarNode(profile)->child_count(); - ++i) { - ASSERT_TRUE(SetURL(profile, - GetBookmarkBarNode(profile)->GetChild(i), - GURL(NextIndexedURL()))); - } + for (const auto& child : GetBookmarkBarNode(profile)->children()) + ASSERT_TRUE(SetURL(profile, child.get(), GURL(NextIndexedURL()))); } void BookmarksSyncPerfTest::RemoveURLs(int profile) { @@ -72,8 +67,8 @@ } } -int BookmarksSyncPerfTest::GetURLCount(int profile) { - return GetBookmarkBarNode(profile)->child_count(); +size_t BookmarksSyncPerfTest::GetURLCount(int profile) { + return GetBookmarkBarNode(profile)->children().size(); } std::string BookmarksSyncPerfTest::NextIndexedURL() { @@ -99,6 +94,6 @@ RemoveURLs(0); dt = TimeMutualSyncCycle(GetClient(0), GetClient(1)); - ASSERT_EQ(0, GetURLCount(1)); + ASSERT_EQ(0u, GetURLCount(1)); PrintResult("bookmarks", "delete_bookmarks", dt); }
diff --git a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc index 0799ba7..376689c 100644 --- a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
@@ -192,7 +192,7 @@ UpdatedProgressMarkerChecker(GetSyncService(kSingleProfileIndex)).Wait()); ASSERT_TRUE(ModelMatchesVerifier(kSingleProfileIndex)); - ASSERT_EQ(tier1_a_url0->id(), top->GetChild(top->child_count() - 1)->id()); + ASSERT_EQ(tier1_a_url0->id(), top->children().back()->id()); Remove(kSingleProfileIndex, top, top->children().size() - 1); Move(kSingleProfileIndex, wired, tier1_b, 0); Move(kSingleProfileIndex, porsche, bar, 3); @@ -404,8 +404,8 @@ ASSERT_TRUE( UpdatedProgressMarkerChecker(GetSyncService(kSingleProfileIndex)).Wait()); // Verify other node has no children now. - EXPECT_EQ(0, GetOtherNode(kSingleProfileIndex)->child_count()); - EXPECT_EQ(0, GetBookmarkBarNode(kSingleProfileIndex)->child_count()); + EXPECT_TRUE(GetOtherNode(kSingleProfileIndex)->children().empty()); + EXPECT_TRUE(GetBookmarkBarNode(kSingleProfileIndex)->children().empty()); // Verify model matches verifier. ASSERT_TRUE(ModelMatchesVerifier(kSingleProfileIndex)); } @@ -688,7 +688,7 @@ EXPECT_EQ(1u, CountFoldersWithTitlesMatching(kSingleProfileIndex, title2)); const BookmarkNode* bar = GetBookmarkBarNode(kSingleProfileIndex); - ASSERT_EQ(3, bar->child_count()); + ASSERT_EQ(3u, bar->children().size()); EXPECT_EQ(base::ASCIIToUTF16(title0), bar->GetChild(0)->GetTitle()); EXPECT_EQ(base::ASCIIToUTF16(title1), bar->GetChild(1)->GetTitle()); EXPECT_EQ(base::ASCIIToUTF16(title2), bar->GetChild(2)->GetTitle()); @@ -739,7 +739,7 @@ base::HistogramTester histogram_tester; ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; - ASSERT_EQ(1, GetBookmarkBarNode(kSingleProfileIndex)->child_count()); + ASSERT_EQ(1u, GetBookmarkBarNode(kSingleProfileIndex)->children().size()); EXPECT_NE( 0, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange3.BOOKMARK", @@ -756,7 +756,7 @@ base::HistogramTester histogram_tester; ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; - ASSERT_EQ(1, GetBookmarkBarNode(kSingleProfileIndex)->child_count()); + ASSERT_EQ(1u, GetBookmarkBarNode(kSingleProfileIndex)->children().size()); #if defined(CHROMEOS) // identity::SetRefreshTokenForPrimaryAccount() is needed on ChromeOS in order
diff --git a/chrome/browser/sync/test/integration/sync_auth_test.cc b/chrome/browser/sync/test/integration/sync_auth_test.cc index efdcf77..0bd2ee8 100644 --- a/chrome/browser/sync/test/integration/sync_auth_test.cc +++ b/chrome/browser/sync/test/integration/sync_auth_test.cc
@@ -443,7 +443,7 @@ // Delete the bookmark and the pref. // Note that AttemptToTriggerAuthError() also creates bookmarks, so the index // of our test bookmark might have changed. - ASSERT_EQ(bar->GetChild(bar->child_count() - 1), bookmark); + ASSERT_EQ(bar->children().back().get(), bookmark); bookmarks_helper::Remove(0, bar, bar->children().size() - 1); ASSERT_FALSE(bookmarks_helper::HasNodeWithURL(0, kTestURL)); pref_service->ClearPref(prefs::kHomePageIsNewTabPage);
diff --git a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc index 7732357..7949111 100644 --- a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc
@@ -2083,8 +2083,8 @@ ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1))); // Verify other node has no children now. - EXPECT_EQ(0, GetOtherNode(0)->child_count()); - EXPECT_EQ(0, GetBookmarkBarNode(0)->child_count()); + EXPECT_TRUE(GetOtherNode(0)->children().empty()); + EXPECT_TRUE(GetBookmarkBarNode(0)->children().empty()); ASSERT_TRUE(AllModelsMatch()); } @@ -2121,8 +2121,8 @@ GURL google_url("http://www.google.com"); ASSERT_NE(nullptr, AddURL(0, "Google", google_url)); ASSERT_TRUE(BookmarksMatchVerifierChecker().Wait()); - ASSERT_EQ(1, bar_node0->child_count()); - ASSERT_EQ(1, bar_node1->child_count()); + ASSERT_EQ(1u, bar_node0->children().size()); + ASSERT_EQ(1u, bar_node1->children().size()); // Set the ManagedBookmarks policy for the first Profile, // which will add one new managed bookmark. @@ -2147,12 +2147,12 @@ // Verify that the managed bookmark exists in the local model of the first // Profile, and has a child node. - ASSERT_EQ(1, managed_node0->child_count()); + ASSERT_EQ(1u, managed_node0->children().size()); ASSERT_TRUE(managed_node0->IsVisible()); EXPECT_EQ(GURL("http://youtube.com/"), managed_node0->GetChild(0)->url()); // Verify that the second Profile didn't get this node. - ASSERT_EQ(0, managed_node1->child_count()); + ASSERT_EQ(0u, managed_node1->children().size()); } IN_PROC_BROWSER_TEST_P(TwoClientBookmarksSyncTestIncludingUssTests,
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 6cbb609f..4bc8f03 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -477,6 +477,7 @@ "//components/safe_browsing/db:util", "//components/safe_browsing/password_protection", "//components/safe_browsing/triggers:ad_popup_trigger", + "//components/safe_browsing/triggers:ad_redirect_trigger", "//components/safe_browsing/web_ui", "//components/search", "//components/search_engines",
diff --git a/chrome/browser/ui/android/ssl_client_certificate_request.cc b/chrome/browser/ui/android/ssl_client_certificate_request.cc index 05bea07..9665976 100644 --- a/chrome/browser/ui/android/ssl_client_certificate_request.cc +++ b/chrome/browser/ui/android/ssl_client_certificate_request.cc
@@ -51,13 +51,19 @@ std::unique_ptr<content::ClientCertificateDelegate> delegate) : pending_requests_(pending_requests), cert_request_info_(cert_request_info), - delegate_(std::move(delegate)) {} + delegate_(std::move(delegate)), + weak_factory_(this) {} - ~ClientCertRequest() {} + base::OnceClosure GetCancellationCallback() { + return base::BindOnce(&ClientCertRequest::OnCancel, + weak_factory_.GetWeakPtr()); + } void CertificateSelected(scoped_refptr<net::X509Certificate> cert, scoped_refptr<net::SSLPrivateKey> key); + void OnCancel(); + net::SSLCertRequestInfo* cert_request_info() const { return cert_request_info_.get(); } @@ -66,6 +72,7 @@ base::WeakPtr<SSLClientCertPendingRequests> pending_requests_; scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; std::unique_ptr<content::ClientCertificateDelegate> delegate_; + base::WeakPtrFactory<ClientCertRequest> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ClientCertRequest); }; @@ -291,6 +298,13 @@ } } +void ClientCertRequest::OnCancel() { + // When we receive an OnCancel message, we remove this ClientCertRequest from + // the queue of pending requests. + auto should_keep = [this](auto* req) { return req != this; }; + pending_requests_->FilterPendingRequests(should_keep); +} + } // namespace namespace android { @@ -370,7 +384,7 @@ } // namespace android -void ShowSSLClientCertificateSelector( +base::OnceClosure ShowSSLClientCertificateSelector( content::WebContents* contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList unused_client_certs, @@ -380,15 +394,19 @@ if (vr::VrTabHelper::IsUiSuppressedInVr( contents, vr::UiSuppressedElement::kSslClientCertificate)) { delegate->ContinueWithCertificate(nullptr, nullptr); - return; + return base::OnceClosure(); } SSLClientCertPendingRequests::CreateForWebContents(contents); SSLClientCertPendingRequests* active_requests = SSLClientCertPendingRequests::FromWebContents(contents); - active_requests->AddRequest(std::make_unique<ClientCertRequest>( - active_requests->GetWeakPtr(), cert_request_info, std::move(delegate))); + auto client_cert_request = std::make_unique<ClientCertRequest>( + active_requests->GetWeakPtr(), cert_request_info, std::move(delegate)); + base::OnceClosure cancellation_callback = + client_cert_request->GetCancellationCallback(); + active_requests->AddRequest(std::move(client_cert_request)); + return cancellation_callback; } } // namespace chrome
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_test_util.h b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_test_util.h index 3381fe9..2376206d 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_test_util.h +++ b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_test_util.h
@@ -229,10 +229,9 @@ last_score, last_num_updates); -DEFINE_EQUIVTO_PROTO_LITE_1(ZeroStateHourBinPredictorProto, - binned_frequency_table); +DEFINE_EQUIVTO_PROTO_LITE_1(HourBinPredictorProto, binned_frequency_table); -DEFINE_EQUIVTO_PROTO_LITE_2(ZeroStateHourBinPredictorProto_FrequencyTable, +DEFINE_EQUIVTO_PROTO_LITE_2(HourBinPredictorProto_FrequencyTable, total_counts, frequency); @@ -245,7 +244,7 @@ DEFINE_EQUIVTO_PROTO_LITE_2(RecurrencePredictorProto, fake_predictor, - zero_state_frecency_predictor); + frecency_predictor); DEFINE_EQUIVTO_PROTO_LITE_2(RecurrenceRankerProto, config_hash, predictor); @@ -257,11 +256,9 @@ num_of_trains_at_last_update, last_score); -DEFINE_EQUIVTO_PROTO_LITE_2(ZeroStateFrecencyPredictorProto, - targets, - num_updates); +DEFINE_EQUIVTO_PROTO_LITE_2(FrecencyPredictorProto, targets, num_updates); -DEFINE_EQUIVTO_PROTO_LITE_2(ZeroStateFrecencyPredictorProto_TargetData, +DEFINE_EQUIVTO_PROTO_LITE_2(FrecencyPredictorProto_TargetData, last_score, last_num_updates);
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h b/chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h index 8cfac201..5007fc9 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h +++ b/chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h
@@ -29,9 +29,9 @@ kTargetsMissingError = 5, kConditionsMissingError = 6, kFakePredictorLoadingError = 7, - kZeroStateFrecencyPredictorLoadingError = 8, - kZeroStateHourBinnedPredictorLoadingError = 9, - kMaxValue = kZeroStateHourBinnedPredictorLoadingError, + kFrecencyPredictorLoadingError = 8, + kHourBinnedPredictorLoadingError = 9, + kMaxValue = kHourBinnedPredictorLoadingError, }; // Represents errors where a RecurrenceRanker is used in a way not supported by
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.cc b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.cc index 111524bf..e344dd86 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.cc
@@ -15,29 +15,6 @@ } // namespace -void RecurrencePredictor::Train(unsigned int target) { - LogUsageError(UsageError::kInvalidTrainCall); - NOTREACHED(); -} - -void RecurrencePredictor::Train(unsigned int target, unsigned int condition) { - LogUsageError(UsageError::kInvalidTrainCall); - NOTREACHED(); -} - -base::flat_map<unsigned int, float> RecurrencePredictor::Rank() { - LogUsageError(UsageError::kInvalidRankCall); - NOTREACHED(); - return {}; -} - -base::flat_map<unsigned int, float> RecurrencePredictor::Rank( - unsigned int condition) { - LogUsageError(UsageError::kInvalidRankCall); - NOTREACHED(); - return {}; -} - FakePredictor::FakePredictor(const FakePredictorConfig& config) { // The fake predictor should only be used for testing, not in production. // Record an error so we know if it is being used. @@ -51,11 +28,12 @@ return kPredictorName; } -void FakePredictor::Train(unsigned int target) { +void FakePredictor::Train(unsigned int target, unsigned int condition) { counts_[target] += 1.0f; } -base::flat_map<unsigned int, float> FakePredictor::Rank() { +base::flat_map<unsigned int, float> FakePredictor::Rank( + unsigned int condition) { return counts_; } @@ -70,15 +48,23 @@ LogSerializationError(SerializationError::kFakePredictorLoadingError); return; } - auto predictor = proto.fake_predictor(); - for (const auto& pair : predictor.counts()) + for (const auto& pair : proto.fake_predictor().counts()) counts_[pair.first] = pair.second; } DefaultPredictor::DefaultPredictor(const DefaultPredictorConfig& config) {} DefaultPredictor::~DefaultPredictor() {} +void DefaultPredictor::Train(unsigned int target, unsigned int condition) {} + +base::flat_map<unsigned int, float> DefaultPredictor::Rank( + unsigned int condition) { + LogUsageError(UsageError::kInvalidRankCall); + NOTREACHED(); + return {}; +} + const char DefaultPredictor::kPredictorName[] = "DefaultPredictor"; const char* DefaultPredictor::GetPredictorName() const { return kPredictorName; @@ -88,25 +74,24 @@ void DefaultPredictor::FromProto(const RecurrencePredictorProto& proto) {} -ZeroStateFrecencyPredictor::ZeroStateFrecencyPredictor( - const ZeroStateFrecencyPredictorConfig& config) +FrecencyPredictor::FrecencyPredictor(const FrecencyPredictorConfig& config) : decay_coeff_(config.decay_coeff()) {} -ZeroStateFrecencyPredictor::~ZeroStateFrecencyPredictor() = default; +FrecencyPredictor::~FrecencyPredictor() = default; -const char ZeroStateFrecencyPredictor::kPredictorName[] = - "ZeroStateFrecencyPredictor"; -const char* ZeroStateFrecencyPredictor::GetPredictorName() const { +const char FrecencyPredictor::kPredictorName[] = "FrecencyPredictor"; +const char* FrecencyPredictor::GetPredictorName() const { return kPredictorName; } -void ZeroStateFrecencyPredictor::Train(unsigned int target) { +void FrecencyPredictor::Train(unsigned int target, unsigned int condition) { ++num_updates_; TargetData& data = targets_[target]; DecayScore(&data); data.last_score += 1.0f - decay_coeff_; } -base::flat_map<unsigned int, float> ZeroStateFrecencyPredictor::Rank() { +base::flat_map<unsigned int, float> FrecencyPredictor::Rank( + unsigned int condition) { base::flat_map<unsigned int, float> result; for (auto& pair : targets_) { DecayScore(&pair.second); @@ -115,9 +100,8 @@ return result; } -void ZeroStateFrecencyPredictor::ToProto( - RecurrencePredictorProto* proto) const { - auto* predictor = proto->mutable_zero_state_frecency_predictor(); +void FrecencyPredictor::ToProto(RecurrencePredictorProto* proto) const { + auto* predictor = proto->mutable_frecency_predictor(); predictor->set_num_updates(num_updates_); @@ -129,14 +113,12 @@ } } -void ZeroStateFrecencyPredictor::FromProto( - const RecurrencePredictorProto& proto) { - if (!proto.has_zero_state_frecency_predictor()) { - LogSerializationError( - SerializationError::kZeroStateFrecencyPredictorLoadingError); +void FrecencyPredictor::FromProto(const RecurrencePredictorProto& proto) { + if (!proto.has_frecency_predictor()) { + LogSerializationError(SerializationError::kFrecencyPredictorLoadingError); return; } - const auto& predictor = proto.zero_state_frecency_predictor(); + const auto& predictor = proto.frecency_predictor(); num_updates_ = predictor.num_updates(); @@ -148,7 +130,7 @@ targets_.swap(targets); } -void ZeroStateFrecencyPredictor::DecayScore(TargetData* data) { +void FrecencyPredictor::DecayScore(TargetData* data) { int time_since_update = num_updates_ - data->last_num_updates; if (time_since_update > 0) { @@ -157,25 +139,22 @@ } } -ZeroStateHourBinPredictor::ZeroStateHourBinPredictor( - const ZeroStateHourBinPredictorConfig& config) +HourBinPredictor::HourBinPredictor(const HourBinPredictorConfig& config) : config_(config) { if (!proto_.has_last_decay_timestamp()) SetLastDecayTimestamp( base::Time::Now().ToDeltaSinceWindowsEpoch().InDays()); } -ZeroStateHourBinPredictor::~ZeroStateHourBinPredictor() = default; +HourBinPredictor::~HourBinPredictor() = default; -const char ZeroStateHourBinPredictor::kPredictorName[] = - "ZeroStateHourBinPredictor"; +const char HourBinPredictor::kPredictorName[] = "HourBinPredictor"; -const char* ZeroStateHourBinPredictor::GetPredictorName() const { +const char* HourBinPredictor::GetPredictorName() const { return kPredictorName; } -int ZeroStateHourBinPredictor::GetBinFromHourDifference( - int hour_difference) const { +int HourBinPredictor::GetBinFromHourDifference(int hour_difference) const { base::Time shifted_time = base::Time::Now() + base::TimeDelta::FromHours(hour_difference); base::Time::Exploded exploded_time; @@ -193,18 +172,19 @@ } } -int ZeroStateHourBinPredictor::GetBin() const { +int HourBinPredictor::GetBin() const { return GetBinFromHourDifference(0); } -void ZeroStateHourBinPredictor::Train(unsigned int target) { +void HourBinPredictor::Train(unsigned int target, unsigned int condition) { int hour = GetBin(); auto& frequency_table = (*proto_.mutable_binned_frequency_table())[hour]; frequency_table.set_total_counts(frequency_table.total_counts() + 1); (*frequency_table.mutable_frequency())[target] += 1; } -base::flat_map<unsigned int, float> ZeroStateHourBinPredictor::Rank() { +base::flat_map<unsigned int, float> HourBinPredictor::Rank( + unsigned int condition) { base::flat_map<unsigned int, float> ranks; const auto& frequency_table_map = proto_.binned_frequency_table(); for (const auto& hour_and_weight : config_.bin_weights_map()) { @@ -229,27 +209,26 @@ return ranks; } -void ZeroStateHourBinPredictor::ToProto(RecurrencePredictorProto* proto) const { - *proto->mutable_zero_state_hour_bin_predictor() = proto_; +void HourBinPredictor::ToProto(RecurrencePredictorProto* proto) const { + *proto->mutable_hour_bin_predictor() = proto_; } -void ZeroStateHourBinPredictor::FromProto( - const RecurrencePredictorProto& proto) { - if (!proto.has_zero_state_hour_bin_predictor()) +void HourBinPredictor::FromProto(const RecurrencePredictorProto& proto) { + if (!proto.has_hour_bin_predictor()) return; - proto_ = proto.zero_state_hour_bin_predictor(); + proto_ = proto.hour_bin_predictor(); if (ShouldDecay()) DecayAll(); } -bool ZeroStateHourBinPredictor::ShouldDecay() { +bool HourBinPredictor::ShouldDecay() { const int today = base::Time::Now().ToDeltaSinceWindowsEpoch().InDays(); // Check if we should decay the frequency return today - proto_.last_decay_timestamp() > 7; } -void ZeroStateHourBinPredictor::DecayAll() { +void HourBinPredictor::DecayAll() { SetLastDecayTimestamp(base::Time::Now().ToDeltaSinceWindowsEpoch().InDays()); auto& frequency_table_map = *proto_.mutable_binned_frequency_table(); for (auto it_table = frequency_table_map.begin();
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.h b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.h index eec8ae99..382adaa 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.h +++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.h
@@ -19,10 +19,10 @@ using FakePredictorConfig = RecurrenceRankerConfigProto::FakePredictorConfig; using DefaultPredictorConfig = RecurrenceRankerConfigProto::DefaultPredictorConfig; -using ZeroStateFrecencyPredictorConfig = - RecurrenceRankerConfigProto::ZeroStateFrecencyPredictorConfig; -using ZeroStateHourBinPredictorConfig = - RecurrenceRankerConfigProto::ZeroStateHourBinPredictorConfig; +using FrecencyPredictorConfig = + RecurrenceRankerConfigProto::FrecencyPredictorConfig; +using HourBinPredictorConfig = + RecurrenceRankerConfigProto::HourBinPredictorConfig; // |RecurrencePredictor| is the interface for all predictors used by // |RecurrenceRanker| to drive rankings. If a predictor has some form of @@ -34,16 +34,12 @@ // Train the predictor on an occurrence of |target| coinciding with // |condition|. The predictor will collect its own contextual information, eg. - // time of day, as part of training. Zero-state predictors should use the - // one-argument version. - virtual void Train(unsigned int target); - virtual void Train(unsigned int target, unsigned int condition); + // time of day, as part of training. + virtual void Train(unsigned int target, unsigned int condition) = 0; // Return a map of all known targets to their scores for the given condition - // under this predictor. Scores must be within the range [0,1]. Zero-state - // predictors should use the zero-argument version. - virtual base::flat_map<unsigned int, float> Rank(); - virtual base::flat_map<unsigned int, float> Rank(unsigned int condition); + // under this predictor. Scores must be within the range [0,1]. + virtual base::flat_map<unsigned int, float> Rank(unsigned int condition) = 0; virtual void ToProto(RecurrencePredictorProto* proto) const = 0; virtual void FromProto(const RecurrencePredictorProto& proto) = 0; @@ -62,8 +58,8 @@ ~FakePredictor() override; // RecurrencePredictor: - void Train(unsigned int target) override; - base::flat_map<unsigned int, float> Rank() override; + void Train(unsigned int target, unsigned int condition) override; + base::flat_map<unsigned int, float> Rank(unsigned int condition) override; void ToProto(RecurrencePredictorProto* proto) const override; void FromProto(const RecurrencePredictorProto& proto) override; const char* GetPredictorName() const override; @@ -85,6 +81,8 @@ ~DefaultPredictor() override; // RecurrencePredictor: + void Train(unsigned int target, unsigned int condition) override; + base::flat_map<unsigned int, float> Rank(unsigned int condition) override; void ToProto(RecurrencePredictorProto* proto) const override; void FromProto(const RecurrencePredictorProto& proto) override; const char* GetPredictorName() const override; @@ -95,16 +93,15 @@ DISALLOW_COPY_AND_ASSIGN(DefaultPredictor); }; -// ZeroStateFrecencyPredictor ranks targets according to their frecency, and +// FrecencyPredictor ranks targets according to their frecency, and // can only be used for zero-state predictions. This predictor allows for // frecency-based rankings with different configuration to that of the ranker's // FrecencyStore. If frecency-based rankings with the same configuration as the // store are needed, the DefaultPredictor should be used instead. -class ZeroStateFrecencyPredictor : public RecurrencePredictor { +class FrecencyPredictor : public RecurrencePredictor { public: - explicit ZeroStateFrecencyPredictor( - const ZeroStateFrecencyPredictorConfig& config); - ~ZeroStateFrecencyPredictor() override; + explicit FrecencyPredictor(const FrecencyPredictorConfig& config); + ~FrecencyPredictor() override; // Records all information about a target: its id and score, along with the // number of updates that had occurred when the score was last calculated. @@ -115,8 +112,8 @@ }; // RecurrencePredictor: - void Train(unsigned int target) override; - base::flat_map<unsigned int, float> Rank() override; + void Train(unsigned int target, unsigned int condition) override; + base::flat_map<unsigned int, float> Rank(unsigned int condition) override; void ToProto(RecurrencePredictorProto* proto) const override; void FromProto(const RecurrencePredictorProto& proto) override; const char* GetPredictorName() const override; @@ -139,23 +136,22 @@ // This stores all the data of the frecency predictor. // TODO(tby): benchmark which map is best in practice for our use. - base::flat_map<unsigned int, ZeroStateFrecencyPredictor::TargetData> targets_; + base::flat_map<unsigned int, FrecencyPredictor::TargetData> targets_; - DISALLOW_COPY_AND_ASSIGN(ZeroStateFrecencyPredictor); + DISALLOW_COPY_AND_ASSIGN(FrecencyPredictor); }; -// |ZeroStateHourBinPredictor| ranks targets according to their frequency during +// |HourBinPredictor| ranks targets according to their frequency during // the current and neighbor hour bins. It can only be used for zero-state // predictions. -class ZeroStateHourBinPredictor : public RecurrencePredictor { +class HourBinPredictor : public RecurrencePredictor { public: - explicit ZeroStateHourBinPredictor( - const ZeroStateHourBinPredictorConfig& config); - ~ZeroStateHourBinPredictor() override; + explicit HourBinPredictor(const HourBinPredictorConfig& config); + ~HourBinPredictor() override; // RecurrencePredictor: - void Train(unsigned int target) override; - base::flat_map<unsigned int, float> Rank() override; + void Train(unsigned int target, unsigned int condition) override; + base::flat_map<unsigned int, float> Rank(unsigned int condition) override; void ToProto(RecurrencePredictorProto* proto) const override; void FromProto(const RecurrencePredictorProto& proto) override; const char* GetPredictorName() const override; @@ -163,13 +159,11 @@ static const char kPredictorName[]; private: - FRIEND_TEST_ALL_PREFIXES(ZeroStateHourBinPredictorTest, GetTheRightBin); - FRIEND_TEST_ALL_PREFIXES(ZeroStateHourBinPredictorTest, - TrainAndRankSingleBin); - FRIEND_TEST_ALL_PREFIXES(ZeroStateHourBinPredictorTest, - TrainAndRankMultipleBin); - FRIEND_TEST_ALL_PREFIXES(ZeroStateHourBinPredictorTest, ToProto); - FRIEND_TEST_ALL_PREFIXES(ZeroStateHourBinPredictorTest, FromProtoDecays); + FRIEND_TEST_ALL_PREFIXES(HourBinPredictorTest, GetTheRightBin); + FRIEND_TEST_ALL_PREFIXES(HourBinPredictorTest, TrainAndRankSingleBin); + FRIEND_TEST_ALL_PREFIXES(HourBinPredictorTest, TrainAndRankMultipleBin); + FRIEND_TEST_ALL_PREFIXES(HourBinPredictorTest, ToProto); + FRIEND_TEST_ALL_PREFIXES(HourBinPredictorTest, FromProtoDecays); // Return the bin index that is |hour_difference| away from the current bin // index. int GetBinFromHourDifference(int hour_difference) const; @@ -182,9 +176,9 @@ void SetLastDecayTimestamp(float value) { proto_.set_last_decay_timestamp(value); } - ZeroStateHourBinPredictorProto proto_; - ZeroStateHourBinPredictorConfig config_; - DISALLOW_COPY_AND_ASSIGN(ZeroStateHourBinPredictor); + HourBinPredictorProto proto_; + HourBinPredictorConfig config_; + DISALLOW_COPY_AND_ASSIGN(HourBinPredictor); }; } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.proto b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.proto index 935ba48..7d9bfe5a 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.proto +++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor.proto
@@ -14,8 +14,7 @@ map<uint32, float> counts = 1; } -// Zero-state frecency predictor. -message ZeroStateFrecencyPredictorProto { +message FrecencyPredictorProto { // Field 1 (targets) has been deleted. reserved 1; @@ -34,8 +33,7 @@ required uint32 num_updates = 5; } -// Zero-state hour bin predictor -message ZeroStateHourBinPredictorProto { +message HourBinPredictorProto { // Records all data related to a single hour bin. message FrequencyTable { // Total number of training counts in a bin. @@ -53,7 +51,7 @@ message RecurrencePredictorProto { oneof predictor { FakePredictorProto fake_predictor = 1; - ZeroStateFrecencyPredictorProto zero_state_frecency_predictor = 2; - ZeroStateHourBinPredictorProto zero_state_hour_bin_predictor = 3; + FrecencyPredictorProto frecency_predictor = 2; + HourBinPredictorProto hour_bin_predictor = 3; } }
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor_unittest.cc b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor_unittest.cc index a9923d2f..a6d44fa 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor_unittest.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_predictor_unittest.cc
@@ -29,41 +29,38 @@ RecurrencePredictorProto MakeTestingProto() { RecurrencePredictorProto proto; - auto* zero_state_hour_bin_proto = - proto.mutable_zero_state_hour_bin_predictor(); - zero_state_hour_bin_proto->set_last_decay_timestamp(365); + auto* hour_bin_proto = proto.mutable_hour_bin_predictor(); + hour_bin_proto->set_last_decay_timestamp(365); - ZeroStateHourBinPredictorProto::FrequencyTable frequency_table; + HourBinPredictorProto::FrequencyTable frequency_table; (*frequency_table.mutable_frequency())[1u] = 3; (*frequency_table.mutable_frequency())[2u] = 1; frequency_table.set_total_counts(4); - (*zero_state_hour_bin_proto->mutable_binned_frequency_table())[10] = - frequency_table; + (*hour_bin_proto->mutable_binned_frequency_table())[10] = frequency_table; - frequency_table = ZeroStateHourBinPredictorProto::FrequencyTable(); + frequency_table = HourBinPredictorProto::FrequencyTable(); (*frequency_table.mutable_frequency())[1u] = 1; (*frequency_table.mutable_frequency())[3u] = 1; frequency_table.set_total_counts(2); - (*zero_state_hour_bin_proto->mutable_binned_frequency_table())[11] = - frequency_table; + (*hour_bin_proto->mutable_binned_frequency_table())[11] = frequency_table; return proto; } -class ZeroStateFrecencyPredictorTest : public testing::Test { +class FrecencyPredictorTest : public testing::Test { protected: void SetUp() override { Test::SetUp(); config_.set_decay_coeff(0.5f); - predictor_ = std::make_unique<ZeroStateFrecencyPredictor>(config_); + predictor_ = std::make_unique<FrecencyPredictor>(config_); } - ZeroStateFrecencyPredictorConfig config_; - std::unique_ptr<ZeroStateFrecencyPredictor> predictor_; + FrecencyPredictorConfig config_; + std::unique_ptr<FrecencyPredictor> predictor_; }; -class ZeroStateHourBinPredictorTest : public testing::Test { +class HourBinPredictorTest : public testing::Test { protected: void SetUp() override { Test::SetUp(); @@ -74,7 +71,7 @@ (*config_.mutable_bin_weights_map())[2] = 0.05; (*config_.mutable_bin_weights_map())[-1] = 0.15; (*config_.mutable_bin_weights_map())[-2] = 0.05; - predictor_ = std::make_unique<ZeroStateHourBinPredictor>(config_); + predictor_ = std::make_unique<HourBinPredictor>(config_); } // Sets local time according to |day_of_week| and |hour_of_day|. @@ -88,8 +85,8 @@ } base::ScopedMockClockOverride time_; - ZeroStateHourBinPredictorConfig config_; - std::unique_ptr<ZeroStateHourBinPredictor> predictor_; + HourBinPredictorConfig config_; + std::unique_ptr<HourBinPredictor> predictor_; private: // Advances time to be 0am next Sunday. @@ -107,58 +104,58 @@ } }; -TEST_F(ZeroStateFrecencyPredictorTest, RankWithNoTargets) { - EXPECT_TRUE(predictor_->Rank().empty()); +TEST_F(FrecencyPredictorTest, RankWithNoTargets) { + EXPECT_TRUE(predictor_->Rank(0u).empty()); } -TEST_F(ZeroStateFrecencyPredictorTest, RecordAndRankSimple) { - predictor_->Train(2u); - predictor_->Train(4u); - predictor_->Train(6u); +TEST_F(FrecencyPredictorTest, RecordAndRankSimple) { + predictor_->Train(2u, 0u); + predictor_->Train(4u, 0u); + predictor_->Train(6u, 0u); EXPECT_THAT( - predictor_->Rank(), + predictor_->Rank(0u), UnorderedElementsAre(Pair(2u, FloatEq(0.125f)), Pair(4u, FloatEq(0.25f)), Pair(6u, FloatEq(0.5f)))); } -TEST_F(ZeroStateFrecencyPredictorTest, RecordAndRankComplex) { - predictor_->Train(2u); - predictor_->Train(4u); - predictor_->Train(6u); - predictor_->Train(4u); - predictor_->Train(2u); +TEST_F(FrecencyPredictorTest, RecordAndRankComplex) { + predictor_->Train(2u, 0u); + predictor_->Train(4u, 0u); + predictor_->Train(6u, 0u); + predictor_->Train(4u, 0u); + predictor_->Train(2u, 0u); // Ranks should be deterministic. for (int i = 0; i < 3; ++i) { - EXPECT_THAT(predictor_->Rank(), + EXPECT_THAT(predictor_->Rank(0u), UnorderedElementsAre(Pair(2u, FloatEq(0.53125f)), Pair(4u, FloatEq(0.3125f)), Pair(6u, FloatEq(0.125f)))); } } -TEST_F(ZeroStateFrecencyPredictorTest, ToAndFromProto) { - predictor_->Train(1u); - predictor_->Train(3u); - predictor_->Train(5u); +TEST_F(FrecencyPredictorTest, ToAndFromProto) { + predictor_->Train(1u, 0u); + predictor_->Train(3u, 0u); + predictor_->Train(5u, 0u); RecurrencePredictorProto proto; predictor_->ToProto(&proto); - ZeroStateFrecencyPredictor new_predictor(config_); + FrecencyPredictor new_predictor(config_); new_predictor.FromProto(proto); - EXPECT_TRUE(proto.has_zero_state_frecency_predictor()); - EXPECT_EQ(proto.zero_state_frecency_predictor().num_updates(), 3u); - EXPECT_EQ(predictor_->Rank(), new_predictor.Rank()); + EXPECT_TRUE(proto.has_frecency_predictor()); + EXPECT_EQ(proto.frecency_predictor().num_updates(), 3u); + EXPECT_EQ(predictor_->Rank(0u), new_predictor.Rank(0u)); } -TEST_F(ZeroStateHourBinPredictorTest, RankWithNoTargets) { - EXPECT_TRUE(predictor_->Rank().empty()); +TEST_F(HourBinPredictorTest, RankWithNoTargets) { + EXPECT_TRUE(predictor_->Rank(0u).empty()); } -TEST_F(ZeroStateHourBinPredictorTest, GetTheRightBin) { +TEST_F(HourBinPredictorTest, GetTheRightBin) { // Monday. for (int i = 0; i <= 23; ++i) { SetLocalTime(1, i); @@ -200,64 +197,64 @@ EXPECT_EQ(predictor_->GetBinFromHourDifference(-5), 22); } -TEST_F(ZeroStateHourBinPredictorTest, TrainAndRankSingleBin) { +TEST_F(HourBinPredictorTest, TrainAndRankSingleBin) { base::flat_map<int, float> weights( predictor_->config_.bin_weights_map().begin(), predictor_->config_.bin_weights_map().end()); SetLocalTime(1, 10); - predictor_->Train(1u); + predictor_->Train(1u, 0u); SetLocalTime(2, 10); - predictor_->Train(1u); + predictor_->Train(1u, 0u); SetLocalTime(3, 10); - predictor_->Train(2u); + predictor_->Train(2u, 0u); SetLocalTime(4, 10); - predictor_->Train(1u); + predictor_->Train(1u, 0u); SetLocalTime(5, 10); - predictor_->Train(2u); + predictor_->Train(2u, 0u); // Train on weekend doesn't affect the result during the week SetLocalTime(0, 10); - predictor_->Train(1u); + predictor_->Train(1u, 0u); SetLocalTime(0, 10); - predictor_->Train(2u); + predictor_->Train(2u, 0u); SetLocalTime(1, 10); - EXPECT_THAT(predictor_->Rank(), + EXPECT_THAT(predictor_->Rank(0u), UnorderedElementsAre(Pair(1u, FloatEq(weights[0] * 0.6)), Pair(2u, FloatEq((weights)[0] * 0.4)))); } -TEST_F(ZeroStateHourBinPredictorTest, TrainAndRankMultipleBin) { +TEST_F(HourBinPredictorTest, TrainAndRankMultipleBin) { base::flat_map<int, float> weights( predictor_->config_.bin_weights_map().begin(), predictor_->config_.bin_weights_map().end()); // For bin 10 SetLocalTime(1, 10); - predictor_->Train(1u); - predictor_->Train(1u); + predictor_->Train(1u, 0u); + predictor_->Train(1u, 0u); SetLocalTime(2, 10); - predictor_->Train(2u); + predictor_->Train(2u, 0u); // For bin 11 SetLocalTime(3, 11); - predictor_->Train(1u); - predictor_->Train(2u); + predictor_->Train(1u, 0u); + predictor_->Train(2u, 0u); // For bin 12 SetLocalTime(5, 12); - predictor_->Train(2u); + predictor_->Train(2u, 0u); // Train on weekend. SetLocalTime(6, 10); - predictor_->Train(1u); - predictor_->Train(2u); + predictor_->Train(1u, 0u); + predictor_->Train(2u, 0u); SetLocalTime(0, 11); - predictor_->Train(2u); + predictor_->Train(2u, 0u); // Check workdays. SetLocalTime(1, 10); EXPECT_THAT( - predictor_->Rank(), + predictor_->Rank(0u), UnorderedElementsAre( Pair(1u, FloatEq((weights)[0] * 2.0 / 3.0 + weights[1] * 0.5)), Pair(2u, FloatEq(weights[0] * 1.0 / 3.0 + weights[1] * 0.5 + @@ -265,28 +262,28 @@ // Check weekends. SetLocalTime(0, 9); - EXPECT_THAT(predictor_->Rank(), + EXPECT_THAT(predictor_->Rank(0u), UnorderedElementsAre( Pair(1u, FloatEq(weights[1] * 1.0 / 2.0)), Pair(2u, FloatEq(weights[1] * 1.0 / 2.0 + weights[2])))); } -TEST_F(ZeroStateHourBinPredictorTest, FromProto) { +TEST_F(HourBinPredictorTest, FromProto) { RecurrencePredictorProto proto = MakeTestingProto(); predictor_->FromProto(proto); SetLocalTime(1, 11); EXPECT_THAT( - predictor_->Rank(), + predictor_->Rank(0u), UnorderedElementsAre(Pair(1u, FloatEq(0.4125)), Pair(2u, FloatEq(0.0375)), Pair(3u, FloatEq(0.3)))); } -TEST_F(ZeroStateHourBinPredictorTest, FromProtoDecays) { +TEST_F(HourBinPredictorTest, FromProtoDecays) { RecurrencePredictorProto proto = MakeTestingProto(); - proto.mutable_zero_state_hour_bin_predictor()->set_last_decay_timestamp(350); + proto.mutable_hour_bin_predictor()->set_last_decay_timestamp(350); predictor_->FromProto(proto); SetLocalTime(1, 11); - EXPECT_THAT(predictor_->Rank(), + EXPECT_THAT(predictor_->Rank(0u), UnorderedElementsAre(Pair(1u, FloatEq(0.15)))); // Check if empty items got deleted during decay. @@ -299,25 +296,25 @@ 1); } -TEST_F(ZeroStateHourBinPredictorTest, ToProto) { +TEST_F(HourBinPredictorTest, ToProto) { RecurrencePredictorProto proto; SetLocalTime(1, 10); - predictor_->Train(1u); - predictor_->Train(1u); - predictor_->Train(1u); - predictor_->Train(2u); + predictor_->Train(1u, 0u); + predictor_->Train(1u, 0u); + predictor_->Train(1u, 0u); + predictor_->Train(2u, 0u); SetLocalTime(1, 11); - predictor_->Train(1u); - predictor_->Train(3u); + predictor_->Train(1u, 0u); + predictor_->Train(3u, 0u); predictor_->SetLastDecayTimestamp(365); predictor_->ToProto(&proto); RecurrencePredictorProto target_proto = MakeTestingProto(); - EXPECT_TRUE(proto.has_zero_state_hour_bin_predictor()); + EXPECT_TRUE(proto.has_hour_bin_predictor()); - EXPECT_TRUE(EquivToProtoLite(proto.zero_state_hour_bin_predictor(), - target_proto.zero_state_hour_bin_predictor())); + EXPECT_TRUE(EquivToProtoLite(proto.hour_bin_predictor(), + target_proto.hour_bin_predictor())); } } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.cc b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.cc index 0a078ae..8dfcdaa 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.cc
@@ -81,12 +81,10 @@ return std::make_unique<FakePredictor>(config.fake_predictor()); if (config.has_default_predictor()) return std::make_unique<DefaultPredictor>(config.default_predictor()); - if (config.has_zero_state_frecency_predictor()) - return std::make_unique<ZeroStateFrecencyPredictor>( - config.zero_state_frecency_predictor()); - if (config.has_zero_state_hour_bin_predictor()) - return std::make_unique<ZeroStateHourBinPredictor>( - config.zero_state_hour_bin_predictor()); + if (config.has_frecency_predictor()) + return std::make_unique<FrecencyPredictor>(config.frecency_predictor()); + if (config.has_hour_bin_predictor()) + return std::make_unique<HourBinPredictor>(config.hour_bin_predictor()); LogConfigurationError(ConfigurationError::kInvalidPredictor); NOTREACHED(); @@ -215,34 +213,12 @@ LogSerializationError(SerializationError::kConditionsMissingError); } -void RecurrenceRanker::Record(const std::string& target) { - if (!load_from_disk_completed_) - return; - - if (predictor_->GetPredictorName() == DefaultPredictor::kPredictorName) { - targets_->Update(target); - } else { - predictor_->Train(targets_->Update(target)); - } - - MaybeSave(); -} - void RecurrenceRanker::Record(const std::string& target, const std::string& condition) { if (!load_from_disk_completed_) return; - if (predictor_->GetPredictorName() == DefaultPredictor::kPredictorName) { - // TODO(921444): The default predictor does not support queries, so we fail - // here. Once we have a suitable query-based default predictor implemented, - // change this. - LogUsageError(UsageError::kInvalidTrainCall); - NOTREACHED(); - } else { - predictor_->Train(targets_->Update(target), conditions_->Update(condition)); - } - + predictor_->Train(targets_->Update(target), conditions_->Update(condition)); MaybeSave(); } @@ -282,43 +258,23 @@ MaybeSave(); } -base::flat_map<std::string, float> RecurrenceRanker::Rank() { - if (!load_from_disk_completed_) - return {}; - - if (predictor_->GetPredictorName() == DefaultPredictor::kPredictorName) - return GetScoresFromFrecencyStore(targets_->GetAll()); - return ZipTargetsWithScores(targets_->GetAll(), predictor_->Rank()); -} - base::flat_map<std::string, float> RecurrenceRanker::Rank( const std::string& condition) { if (!load_from_disk_completed_) return {}; + // Special case the default predictor, and return the scores from the target + // frecency store. + if (predictor_->GetPredictorName() == DefaultPredictor::kPredictorName) + return GetScoresFromFrecencyStore(targets_->GetAll()); base::Optional<unsigned int> condition_id = conditions_->GetId(condition); if (condition_id == base::nullopt) return {}; - if (predictor_->GetPredictorName() == DefaultPredictor::kPredictorName) { - // TODO(921444): The default predictor does not support queries, so we fail - // here. Once we have a suitable query-based default predictor implemented, - // change this. - LogUsageError(UsageError::kInvalidRankCall); - NOTREACHED(); - return {}; - } return ZipTargetsWithScores(targets_->GetAll(), predictor_->Rank(condition_id.value())); } -std::vector<std::pair<std::string, float>> RecurrenceRanker::RankTopN(int n) { - if (!load_from_disk_completed_) - return {}; - - return SortAndTruncateRanks(n, Rank()); -} - std::vector<std::pair<std::string, float>> RecurrenceRanker::RankTopN( int n, const std::string& condition) {
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h index 1c350dd..e6c6f91 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h +++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h
@@ -33,12 +33,11 @@ bool is_ephemeral_user); ~RecurrenceRanker(); - // Record the use of a given target, and train the predictor on it. The - // one-argument version should be used for zero-state predictions, and the - // two-argument version for condition-based predictions. This may save to - // disk, but is not guaranteed to. - void Record(const std::string& target); - void Record(const std::string& target, const std::string& condition); + // Record the use of a given target, and train the predictor on it. This may + // save to disk, but is not guaranteed to. The user-supplied |condition| can + // be ignored if it isn't needed. + void Record(const std::string& target, + const std::string& condition = std::string()); // Rename a target, while keeping learned information on it. This may save to // disk, but is not guaranteed to. @@ -56,22 +55,19 @@ // Returns a map of target to score. // - Higher scores are better. // - Score are guaranteed to be in the range [0,1]. - // The zero-argument version should be used for zero-state predictions, and - // the one-argument version for condition-based predictions. - base::flat_map<std::string, float> Rank(); - base::flat_map<std::string, float> Rank(const std::string& condition); + // The user-supplied |condition| can be ignored if it isn't needed. + base::flat_map<std::string, float> Rank( + const std::string& condition = std::string()); // Returns a sorted vector of <target, score> pairs. // - Higher scores are better. // - Score are guaranteed to be in the range [0,1]. // - Pairs are sorted in descending order of score. // - At most n results will be returned. - // The zero-argument version should be used for zero-state predictions, and - // the one-argument version for condition-based predictions. - std::vector<std::pair<std::string, float>> RankTopN(int n); + // The user-supplied |condition| can be ignored if it isn't needed. std::vector<std::pair<std::string, float>> RankTopN( int n, - const std::string& condition); + const std::string& condition = std::string()); // TODO(921444): Create a system for cleaning up internal predictor state that // is stored indepent of the target/condition frecency stores.
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_config.proto b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_config.proto index 2d5a700..69ed406e 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_config.proto +++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_config.proto
@@ -28,14 +28,14 @@ message DefaultPredictorConfig {} // Config for a frecency predictor. - message ZeroStateFrecencyPredictorConfig { + message FrecencyPredictorConfig { // The frecency parameter used to control the frequency-recency tradeoff // that determines when targets are removed. Must be in [0.5, 1.0], with 0.5 // meaning only-recency and 1.0 meaning only-frequency. required float decay_coeff = 1; } - message ZeroStateHourBinPredictorConfig { + message HourBinPredictorConfig { // The decay coeffficient number that control the decay rate. The decay is // once a week. required float weekly_decay_coeff = 1; @@ -45,8 +45,8 @@ // The choice of which kind of predictor to use, and its configuration. oneof predictor_config { FakePredictorConfig fake_predictor = 10001; - ZeroStateFrecencyPredictorConfig zero_state_frecency_predictor = 10002; + FrecencyPredictorConfig frecency_predictor = 10002; DefaultPredictorConfig default_predictor = 10003; - ZeroStateHourBinPredictorConfig zero_state_hour_bin_predictor = 10004; + HourBinPredictorConfig hour_bin_predictor = 10004; } }
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc index 2a91d27..c187700 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc
@@ -104,13 +104,19 @@ value_data.set_last_num_updates(4); (*target_values)["C"] = value_data; - // Make empty conditions frecency store. + // Make conditions frecency store. auto* conditions = proto.mutable_conditions(); - conditions->set_value_limit(0u); - conditions->set_decay_coeff(0.0f); + conditions->set_value_limit(10u); + conditions->set_decay_coeff(0.5f); conditions->set_num_updates(0); conditions->set_next_id(0); - conditions->mutable_values(); + + auto* condition_values = conditions->mutable_values(); + + value_data.set_id(0u); + value_data.set_last_score(0.5f); + value_data.set_last_num_updates(1); + (*condition_values)[""] = value_data; // Make FakePredictor counts. auto* counts = @@ -369,7 +375,7 @@ TEST_F(RecurrenceRankerTest, IntegrationWithZeroStateFrecencyPredictor) { RecurrenceRankerConfigProto config; PartiallyPopulateConfig(&config); - auto* predictor = config.mutable_zero_state_frecency_predictor(); + auto* predictor = config.mutable_frecency_predictor(); predictor->set_decay_coeff(0.5f); RecurrenceRanker ranker(ranker_filepath_, config, false);
diff --git a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc index 102e036..f2ab6064 100644 --- a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc +++ b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc
@@ -330,11 +330,11 @@ controller.reset(new BookmarkContextMenuController( NULL, NULL, NULL, profile_.get(), NULL, BOOKMARK_LAUNCH_LOCATION_NONE, nodes[0]->parent(), nodes)); - int old_count = bb_node->child_count(); + size_t old_count = bb_node->children().size(); controller->ExecuteCommand(IDC_PASTE, 0); ASSERT_TRUE(bb_node->GetChild(1)->is_url()); - ASSERT_EQ(old_count + 1, bb_node->child_count()); + ASSERT_EQ(old_count + 1, bb_node->children().size()); ASSERT_EQ(bb_node->GetChild(0)->url(), bb_node->GetChild(1)->url()); controller.reset(new BookmarkContextMenuController( @@ -344,7 +344,7 @@ controller->ExecuteCommand(IDC_CUT, 0); ASSERT_TRUE(bb_node->GetChild(0)->is_url()); ASSERT_TRUE(bb_node->GetChild(1)->is_folder()); - ASSERT_EQ(old_count, bb_node->child_count()); + ASSERT_EQ(old_count, bb_node->children().size()); } TEST_F(BookmarkContextMenuControllerTest,
diff --git a/chrome/browser/ui/bookmarks/bookmark_utils.cc b/chrome/browser/ui/bookmarks/bookmark_utils.cc index 15c8b36..da93cf8 100644 --- a/chrome/browser/ui/bookmarks/bookmark_utils.cc +++ b/chrome/browser/ui/bookmarks/bookmark_utils.cc
@@ -94,7 +94,7 @@ return BOOKMARK_SHORTCUT_DISPOSITION_UNCHANGED; } -#if defined(TOOLKIT_VIEWS) && !defined(OS_WIN) +#if defined(TOOLKIT_VIEWS) && !defined(OS_WIN) && !defined(OS_MACOSX) gfx::ImageSkia GetFolderIcon(const gfx::VectorIcon& icon, SkColor text_color) { return gfx::CreateVectorIcon(icon, color_utils::DeriveDefaultIconColor(text_color)); @@ -317,6 +317,13 @@ #if defined(OS_WIN) return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_BOOKMARK_BAR_FOLDER_MANAGED); +#elif defined(OS_MACOSX) + int resource_id = color_utils::IsDark(text_color) + ? IDR_BOOKMARK_BAR_FOLDER_MANAGED + : IDR_BOOKMARK_BAR_FOLDER_MANAGED_WHITE; + return *ui::ResourceBundle::GetSharedInstance() + .GetNativeImageNamed(resource_id) + .ToImageSkia(); #else return GetFolderIcon(ui::MaterialDesignController::touch_ui() ? vector_icons::kFolderManagedTouchIcon
diff --git a/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc b/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc index aec6d0d..ed43c8e 100644 --- a/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc +++ b/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/bookmarks/bookmark_utils_desktop.h" +#include <numeric> + #include "base/strings/string_number_conversions.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/profiles/profile.h" @@ -52,9 +54,7 @@ } else { // If the node is not a URL, it is a folder. We want to add those of its // children which are URLs. - for (int child_index = 0; child_index < node->child_count(); - ++child_index) { - const BookmarkNode* child = node->GetChild(child_index); + for (const auto& child : node->children()) { if (child->is_url()) AddUrlIfLegal(child->url()); } @@ -80,14 +80,13 @@ // Returns the total number of descendants nodes. int ChildURLCountTotal(const BookmarkNode* node) { - int result = 0; - for (int i = 0; i < node->child_count(); ++i) { - const BookmarkNode* child = node->GetChild(i); - result++; + const auto count_children = [](int total, const auto& child) { if (child->is_folder()) - result += ChildURLCountTotal(child); - } - return result; + total += ChildURLCountTotal(child.get()); + return total + 1; + }; + return std::accumulate(node->children().cbegin(), node->children().cend(), 0, + count_children); } #if !defined(OS_ANDROID)
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 081d341a..19661ffc 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -173,6 +173,7 @@ #include "components/keep_alive_registry/scoped_keep_alive.h" #include "components/omnibox/browser/location_bar_model_impl.h" #include "components/prefs/pref_service.h" +#include "components/safe_browsing/triggers/ad_redirect_trigger.h" #include "components/search/search.h" #include "components/security_state/content/content_utils.h" #include "components/security_state/core/security_state.h" @@ -216,6 +217,7 @@ #include "extensions/common/extension.h" #include "extensions/common/manifest_handlers/background_info.h" #include "net/base/filename_util.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/window_open_disposition.h" #include "ui/gfx/geometry/point.h" @@ -1271,16 +1273,24 @@ return false; } -void Browser::OnDidBlockFramebust(content::WebContents* web_contents, - const GURL& url) { - if (auto* framebust_helper = - FramebustBlockTabHelper::FromWebContents(web_contents)) { - auto on_click = [](const GURL& url, size_t index, size_t total_elements) { - UMA_HISTOGRAM_ENUMERATION( - "WebCore.Framebust.ClickThroughPosition", - GetListItemPositionFromDistance(index, total_elements)); - }; - framebust_helper->AddBlockedUrl(url, base::BindOnce(on_click)); +void Browser::OnDidBlockNavigation(content::WebContents* web_contents, + const GURL& blocked_url, + const GURL& initiator_url, + blink::NavigationBlockedReason reason) { + if (reason == blink::NavigationBlockedReason::kRedirectWithNoUserGesture) { + if (auto* framebust_helper = + FramebustBlockTabHelper::FromWebContents(web_contents)) { + auto on_click = [](const GURL& url, size_t index, size_t total_elements) { + UMA_HISTOGRAM_ENUMERATION( + "WebCore.Framebust.ClickThroughPosition", + GetListItemPositionFromDistance(index, total_elements)); + }; + framebust_helper->AddBlockedUrl(blocked_url, base::BindOnce(on_click)); + } + } + if (auto* trigger = + safe_browsing::AdRedirectTrigger::FromWebContents(web_contents)) { + trigger->OnDidBlockNavigation(initiator_url); } }
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 961ce64..1d825ffd 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -46,6 +46,7 @@ #include "content/public/common/page_zoom.h" #include "extensions/buildflags/buildflags.h" #include "printing/buildflags/buildflags.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" #include "ui/base/page_transition_types.h" #include "ui/base/ui_base_types.h" #include "ui/base/window_open_disposition.h" @@ -551,8 +552,10 @@ bool allowed_per_prefs, const url::Origin& origin, const GURL& resource_url) override; - void OnDidBlockFramebust(content::WebContents* web_contents, - const GURL& url) override; + void OnDidBlockNavigation(content::WebContents* web_contents, + const GURL& blocked_url, + const GURL& initiator_url, + blink::NavigationBlockedReason reason) override; content::PictureInPictureResult EnterPictureInPicture( content::WebContents* web_contents, const viz::SurfaceId&,
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm index cc2e8b7..0295b81 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm
@@ -19,16 +19,14 @@ @implementation BookmarkFolderAppleScript - (NSArray*)bookmarkFolders { - NSMutableArray* bookmarkFolders = [NSMutableArray - arrayWithCapacity:bookmarkNode_->child_count()]; + NSMutableArray* bookmarkFolders = + [NSMutableArray arrayWithCapacity:bookmarkNode_->children().size()]; - for (int i = 0; i < bookmarkNode_->child_count(); ++i) { - const BookmarkNode* node = bookmarkNode_->GetChild(i); - + for (const auto& node : bookmarkNode_->children()) { if (!node->is_folder()) continue; base::scoped_nsobject<BookmarkFolderAppleScript> bookmarkFolder( - [[BookmarkFolderAppleScript alloc] initWithBookmarkNode:node]); + [[BookmarkFolderAppleScript alloc] initWithBookmarkNode:node.get()]); [bookmarkFolder setContainer:self property:AppleScript::kBookmarkFoldersProperty]; [bookmarkFolders addObject:bookmarkFolder]; @@ -46,9 +44,8 @@ if (!model) return; - const BookmarkNode* node = model->AddFolder(bookmarkNode_, - bookmarkNode_->child_count(), - base::string16()); + const BookmarkNode* node = model->AddFolder( + bookmarkNode_, bookmarkNode_->children().size(), base::string16()); if (!node) { AppleScript::SetError(AppleScript::errCreateBookmarkFolder); return; @@ -90,16 +87,14 @@ } - (NSArray*)bookmarkItems { - NSMutableArray* bookmarkItems = [NSMutableArray - arrayWithCapacity:bookmarkNode_->child_count()]; + NSMutableArray* bookmarkItems = + [NSMutableArray arrayWithCapacity:bookmarkNode_->children().size()]; - for (int i = 0; i < bookmarkNode_->child_count(); ++i) { - const BookmarkNode* node = bookmarkNode_->GetChild(i); - + for (const auto& node : bookmarkNode_->children()) { if (!node->is_url()) continue; base::scoped_nsobject<BookmarkItemAppleScript> bookmarkItem( - [[BookmarkItemAppleScript alloc] initWithBookmarkNode:node]); + [[BookmarkItemAppleScript alloc] initWithBookmarkNode:node.get()]); [bookmarkItem setContainer:self property:AppleScript::kBookmarkItemsProperty]; [bookmarkItems addObject:bookmarkItem]; @@ -124,10 +119,8 @@ return; } - const BookmarkNode* node = model->AddURL(bookmarkNode_, - bookmarkNode_->child_count(), - base::string16(), - url); + const BookmarkNode* node = model->AddURL( + bookmarkNode_, bookmarkNode_->children().size(), base::string16(), url); if (!node) { AppleScript::SetError(AppleScript::errCreateBookmarkItem); return;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm index d871cc3..f639b1b9 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm
@@ -266,8 +266,7 @@ // TODO(jrg): limit the number of bookmarks in the menubar? void BookmarkMenuBridge::AddNodeToMenu(const BookmarkNode* node, NSMenu* menu) { - int child_count = node->child_count(); - if (child_count == 0) { + if (node->children().empty()) { NSString* empty_string = l10n_util::GetNSString(IDS_MENU_EMPTY_SUBMENU); base::scoped_nsobject<NSMenuItem> item([[NSMenuItem alloc] initWithTitle:empty_string @@ -277,17 +276,16 @@ return; } - for (int i = 0; i < child_count; i++) { - const BookmarkNode* child = node->GetChild(i); + for (const auto& child : node->children()) { if (child->is_folder()) { - AddNodeAsSubmenu(menu, child, folder_image_); + AddNodeAsSubmenu(menu, child.get(), folder_image_); } else { base::scoped_nsobject<NSMenuItem> item([[NSMenuItem alloc] - initWithTitle:MenuTitleForNode(child) + initWithTitle:MenuTitleForNode(child.get()) action:nil keyEquivalent:@""]); - bookmark_nodes_[child] = item; - ConfigureMenuItem(child, item, false); + bookmark_nodes_[child.get()] = item; + ConfigureMenuItem(child.get(), item, false); [menu addItem:item]; } }
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm index 8606563..f19dfb7 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm
@@ -276,9 +276,9 @@ EXPECT_TRUE(MenuItemForNode(bridge_.get(), folder->GetChild(1))); const BookmarkNode* removed_node = folder->GetChild(0); - EXPECT_EQ(2, folder->child_count()); + EXPECT_EQ(2u, folder->children().size()); model->Remove(folder->GetChild(0)); - EXPECT_EQ(1, folder->child_count()); + EXPECT_EQ(1u, folder->children().size()); EXPECT_FALSE(menu_is_valid()); UpdateRootMenu();
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc index ac813a6..6c9858c 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -315,9 +315,11 @@ ASSERT_FALSE(IsWindowFullscreenForTabOrPending()); } +// Disabled due to flakiness. +// TODO(crbug.com/976883): Fix and re-enable this. // Tests mouse lock and fullscreen modes can be escaped with ESC key. IN_PROC_BROWSER_TEST_F(FullscreenControllerInteractiveTest, - EscapingMouseLockAndFullscreen) { + DISABLED_EscapingMouseLockAndFullscreen) { ASSERT_TRUE(embedded_test_server()->Start()); ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL(kFullscreenMouseLockHTML));
diff --git a/chrome/browser/ui/page_info/page_info.cc b/chrome/browser/ui/page_info/page_info.cc index 9139967..270d75c3 100644 --- a/chrome/browser/ui/page_info/page_info.cc +++ b/chrome/browser/ui/page_info/page_info.cc
@@ -555,12 +555,12 @@ content::WebContents* web_contents) { #if defined(FULL_SAFE_BROWSING) DCHECK(password_protection_service_); - DCHECK(safe_browsing_status_ == SAFE_BROWSING_STATUS_SIGN_IN_PASSWORD_REUSE || - safe_browsing_status_ == - SAFE_BROWSING_STATUS_ENTERPRISE_PASSWORD_REUSE); + DCHECK(site_identity_status_ == SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE || + site_identity_status_ == + SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE); password_protection_service_->OnUserAction( web_contents, - safe_browsing_status_ == SAFE_BROWSING_STATUS_SIGN_IN_PASSWORD_REUSE + site_identity_status_ == SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE ? PasswordReuseEvent::SIGN_IN_PASSWORD : PasswordReuseEvent::ENTERPRISE_PASSWORD, safe_browsing::WarningUIType::PAGE_INFO, @@ -572,12 +572,12 @@ content::WebContents* web_contents) { #if defined(FULL_SAFE_BROWSING) DCHECK(password_protection_service_); - DCHECK(safe_browsing_status_ == SAFE_BROWSING_STATUS_SIGN_IN_PASSWORD_REUSE || - safe_browsing_status_ == - SAFE_BROWSING_STATUS_ENTERPRISE_PASSWORD_REUSE); + DCHECK(site_identity_status_ == SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE || + site_identity_status_ == + SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE); password_protection_service_->OnUserAction( web_contents, - safe_browsing_status_ == SAFE_BROWSING_STATUS_SIGN_IN_PASSWORD_REUSE + site_identity_status_ == SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE ? PasswordReuseEvent::SIGN_IN_PASSWORD : PasswordReuseEvent::ENTERPRISE_PASSWORD, safe_browsing::WarningUIType::PAGE_INFO, @@ -609,7 +609,7 @@ // All about: URLs except about:blank are redirected. DCHECK_EQ(url::kAboutBlankURL, url.spec()); site_identity_status_ = SITE_IDENTITY_STATUS_NO_CERT; - site_details_message_ = + site_identity_details_ = l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY); site_connection_status_ = SITE_CONNECTION_STATUS_UNENCRYPTED; site_connection_details_ = l10n_util::GetStringFUTF16( @@ -620,7 +620,7 @@ if (url.SchemeIs(content::kChromeUIScheme) || is_chrome_ui_native_scheme) { site_identity_status_ = SITE_IDENTITY_STATUS_INTERNAL_PAGE; - site_details_message_ = + site_identity_details_ = l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE); site_connection_status_ = SITE_CONNECTION_STATUS_INTERNAL_PAGE; return; @@ -629,14 +629,36 @@ // Identity section. certificate_ = visible_security_state.certificate; - if (certificate_ && - (!net::IsCertStatusError(visible_security_state.cert_status) || - net::IsCertStatusMinorError(visible_security_state.cert_status))) { + if (visible_security_state.malicious_content_status != + security_state::MALICIOUS_CONTENT_STATUS_NONE) { + // The site has been flagged by Safe Browsing as dangerous. + GetSiteIdentityByMaliciousContentStatus( + visible_security_state.malicious_content_status, &site_identity_status_, + &site_identity_details_); +#if defined(FULL_SAFE_BROWSING) + bool old_show_change_pw_buttons = show_change_password_buttons_; +#endif + show_change_password_buttons_ = + (visible_security_state.malicious_content_status == + security_state::MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE || + visible_security_state.malicious_content_status == + security_state:: + MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE); +#if defined(FULL_SAFE_BROWSING) + // Only record password reuse when adding the button, not on updates. + if (show_change_password_buttons_ && !old_show_change_pw_buttons) { + RecordPasswordReuseEvent(); + } +#endif + } else if (certificate_ && + (!net::IsCertStatusError(visible_security_state.cert_status) || + net::IsCertStatusMinorError( + visible_security_state.cert_status))) { // HTTPS with no or minor errors. if (security_level == security_state::SECURE_WITH_POLICY_INSTALLED_CERT) { #if defined(OS_CHROMEOS) site_identity_status_ = SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT; - site_details_message_ = l10n_util::GetStringFUTF16( + site_identity_details_ = l10n_util::GetStringFUTF16( IDS_CERT_POLICY_PROVIDED_CERT_MESSAGE, UTF8ToUTF16(url.host())); #else DCHECK(false) << "Policy certificates exist only on ChromeOS"; @@ -651,17 +673,17 @@ IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); } - site_details_message_.assign(l10n_util::GetStringFUTF16( + site_identity_details_.assign(l10n_util::GetStringFUTF16( IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_VERIFIED, issuer_name)); - site_details_message_ += ASCIIToUTF16("\n\n"); + site_identity_details_ += ASCIIToUTF16("\n\n"); if (visible_security_state.cert_status & net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION) { - site_details_message_ += l10n_util::GetStringUTF16( + site_identity_details_ += l10n_util::GetStringUTF16( IDS_PAGE_INFO_SECURITY_TAB_UNABLE_TO_CHECK_REVOCATION); } else if (visible_security_state.cert_status & net::CERT_STATUS_NO_REVOCATION_MECHANISM) { - site_details_message_ += l10n_util::GetStringUTF16( + site_identity_details_ += l10n_util::GetStringUTF16( IDS_PAGE_INFO_SECURITY_TAB_NO_REVOCATION_MECHANISM); } else { NOTREACHED() << "Need to specify string for this warning"; @@ -678,7 +700,7 @@ // state is "if any". DCHECK(!certificate_->subject().locality_name.empty()); DCHECK(!certificate_->subject().country_name.empty()); - site_details_message_.assign(l10n_util::GetStringFUTF16( + site_identity_details_.assign(l10n_util::GetStringFUTF16( IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_EV_VERIFIED, organization_name_, UTF8ToUTF16(certificate_->subject().country_name))); @@ -692,13 +714,13 @@ IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); } - site_details_message_.assign(l10n_util::GetStringFUTF16( + site_identity_details_.assign(l10n_util::GetStringFUTF16( IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_VERIFIED, issuer_name)); } if (security_state::IsSHA1InChain(visible_security_state)) { site_identity_status_ = SITE_IDENTITY_STATUS_DEPRECATED_SIGNATURE_ALGORITHM; - site_details_message_ += + site_identity_details_ += UTF8ToUTF16("\n\n") + l10n_util::GetStringUTF16( IDS_PAGE_INFO_SECURITY_TAB_DEPRECATED_SIGNATURE_ALGORITHM); @@ -706,7 +728,7 @@ } } else { // HTTP or HTTPS with errors (not warnings). - site_details_message_.assign(l10n_util::GetStringUTF16( + site_identity_details_.assign(l10n_util::GetStringUTF16( IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY)); if (!security_state::IsSchemeCryptographic(visible_security_state.url) || !visible_security_state.certificate) { @@ -720,40 +742,17 @@ ssl_errors::ErrorInfo::GetErrorsForCertStatus( certificate_, visible_security_state.cert_status, url, &errors); for (size_t i = 0; i < errors.size(); ++i) { - site_details_message_ += bullet; - site_details_message_ += errors[i].short_description(); + site_identity_details_ += bullet; + site_identity_details_ += errors[i].short_description(); } if (visible_security_state.cert_status & net::CERT_STATUS_NON_UNIQUE_NAME) { - site_details_message_ += ASCIIToUTF16("\n\n"); - site_details_message_ += + site_identity_details_ += ASCIIToUTF16("\n\n"); + site_identity_details_ += l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_NON_UNIQUE_NAME); } } - if (visible_security_state.malicious_content_status != - security_state::MALICIOUS_CONTENT_STATUS_NONE) { - // The site has been flagged by Safe Browsing. Takes precedence over TLS. - GetSafeBrowsingStatusByMaliciousContentStatus( - visible_security_state.malicious_content_status, &safe_browsing_status_, - &site_details_message_); -#if defined(FULL_SAFE_BROWSING) - bool old_show_change_pw_buttons = show_change_password_buttons_; -#endif - show_change_password_buttons_ = - (visible_security_state.malicious_content_status == - security_state::MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE || - visible_security_state.malicious_content_status == - security_state:: - MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE); -#if defined(FULL_SAFE_BROWSING) - // Only record password reuse when adding the button, not on updates. - if (show_change_password_buttons_ && !old_show_change_pw_buttons) { - RecordPasswordReuseEvent(); - } -#endif - } - // Site Connection // We consider anything less than 80 bits encryption to be weak encryption. // TODO(wtc): Bug 1198735: report mixed/unsafe content for unencrypted and @@ -841,13 +840,8 @@ ChromeSSLHostStateDelegateFactory::GetForProfile(profile_); DCHECK(delegate); // Only show an SSL decision revoke button if the user has chosen to bypass - // SSL host errors for this host in the past, and we're not presently on a - // Safe Browsing error (since otherwise it's confusing which warning you're - // re-enabling). - show_ssl_decision_revoke_button_ = - delegate->HasAllowException(url.host()) && - visible_security_state.malicious_content_status == - security_state::MALICIOUS_CONTENT_STATUS_NONE; + // SSL host errors for this host in the past. + show_ssl_decision_revoke_button_ = delegate->HasAllowException(url.host()); } void PageInfo::PresentSitePermissions() { @@ -961,8 +955,7 @@ info.connection_status = site_connection_status_; info.connection_status_description = UTF16ToUTF8(site_connection_details_); info.identity_status = site_identity_status_; - info.safe_browsing_status = safe_browsing_status_; - info.identity_status_description = UTF16ToUTF8(site_details_message_); + info.identity_status_description = UTF16ToUTF8(site_identity_details_); info.certificate = certificate_; info.show_ssl_decision_revoke_button = show_ssl_decision_revoke_button_; info.show_change_password_buttons = show_change_password_buttons_; @@ -983,7 +976,7 @@ return; } - if (safe_browsing_status_ == SAFE_BROWSING_STATUS_SIGN_IN_PASSWORD_REUSE) { + if (site_identity_status_ == SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE) { safe_browsing::LogWarningAction( safe_browsing::WarningUIType::PAGE_INFO, safe_browsing::WarningAction::SHOWN, @@ -1013,31 +1006,31 @@ return permission_list; } -void PageInfo::GetSafeBrowsingStatusByMaliciousContentStatus( +void PageInfo::GetSiteIdentityByMaliciousContentStatus( security_state::MaliciousContentStatus malicious_content_status, - PageInfo::SafeBrowsingStatus* status, + PageInfo::SiteIdentityStatus* status, base::string16* details) { switch (malicious_content_status) { case security_state::MALICIOUS_CONTENT_STATUS_NONE: NOTREACHED(); break; case security_state::MALICIOUS_CONTENT_STATUS_MALWARE: - *status = PageInfo::SAFE_BROWSING_STATUS_MALWARE; + *status = PageInfo::SITE_IDENTITY_STATUS_MALWARE; *details = l10n_util::GetStringUTF16(IDS_PAGE_INFO_MALWARE_DETAILS); break; case security_state::MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING: - *status = PageInfo::SAFE_BROWSING_STATUS_SOCIAL_ENGINEERING; + *status = PageInfo::SITE_IDENTITY_STATUS_SOCIAL_ENGINEERING; *details = l10n_util::GetStringUTF16(IDS_PAGE_INFO_SOCIAL_ENGINEERING_DETAILS); break; case security_state::MALICIOUS_CONTENT_STATUS_UNWANTED_SOFTWARE: - *status = PageInfo::SAFE_BROWSING_STATUS_UNWANTED_SOFTWARE; + *status = PageInfo::SITE_IDENTITY_STATUS_UNWANTED_SOFTWARE; *details = l10n_util::GetStringUTF16(IDS_PAGE_INFO_UNWANTED_SOFTWARE_DETAILS); break; case security_state::MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE: #if defined(FULL_SAFE_BROWSING) - *status = PageInfo::SAFE_BROWSING_STATUS_SIGN_IN_PASSWORD_REUSE; + *status = PageInfo::SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE; // |password_protection_service_| may be null in test. *details = password_protection_service_ ? password_protection_service_->GetWarningDetailText( @@ -1047,7 +1040,7 @@ break; case security_state::MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE: #if defined(FULL_SAFE_BROWSING) - *status = PageInfo::SAFE_BROWSING_STATUS_ENTERPRISE_PASSWORD_REUSE; + *status = PageInfo::SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE; // |password_protection_service_| maybe null in test. *details = password_protection_service_ ? password_protection_service_->GetWarningDetailText( @@ -1056,7 +1049,7 @@ #endif break; case security_state::MALICIOUS_CONTENT_STATUS_BILLING: - *status = PageInfo::SAFE_BROWSING_STATUS_BILLING; + *status = PageInfo::SITE_IDENTITY_STATUS_BILLING; *details = l10n_util::GetStringUTF16(IDS_PAGE_INFO_BILLING_DETAILS); break; }
diff --git a/chrome/browser/ui/page_info/page_info.h b/chrome/browser/ui/page_info/page_info.h index 4af18b7..3e4fc1e 100644 --- a/chrome/browser/ui/page_info/page_info.h +++ b/chrome/browser/ui/page_info/page_info.h
@@ -87,20 +87,15 @@ // The website provided a valid certificate, but the certificate or chain // is using a deprecated signature algorithm. SITE_IDENTITY_STATUS_DEPRECATED_SIGNATURE_ALGORITHM, - }; - - // Safe Browsing status of a website. - enum SafeBrowsingStatus { - SAFE_BROWSING_STATUS_NONE = 0, // The website has been flagged by Safe Browsing as dangerous for // containing malware, social engineering, unwanted software, or password // reuse on a low reputation site. - SAFE_BROWSING_STATUS_MALWARE, - SAFE_BROWSING_STATUS_SOCIAL_ENGINEERING, - SAFE_BROWSING_STATUS_UNWANTED_SOFTWARE, - SAFE_BROWSING_STATUS_SIGN_IN_PASSWORD_REUSE, - SAFE_BROWSING_STATUS_ENTERPRISE_PASSWORD_REUSE, - SAFE_BROWSING_STATUS_BILLING, + SITE_IDENTITY_STATUS_MALWARE, + SITE_IDENTITY_STATUS_SOCIAL_ENGINEERING, + SITE_IDENTITY_STATUS_UNWANTED_SOFTWARE, + SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE, + SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE, + SITE_IDENTITY_STATUS_BILLING, }; // Events for UMA. Do not reorder or change! Exposed in header so enum is @@ -197,12 +192,8 @@ return site_identity_status_; } - const SafeBrowsingStatus& safe_browsing_status() const { - return safe_browsing_status_; - } - - const base::string16& site_details_message() const { - return site_details_message_; + const base::string16& site_identity_details() const { + return site_identity_details_; } const base::string16& organization_name() const { return organization_name_; } @@ -241,12 +232,11 @@ void RecordPasswordReuseEvent(); #endif - // Helper function to get the Safe Browsing status and details by malicious - // content status. - // TODO(jdeblasio): Eliminate this and just use MaliciousContentStatus? - void GetSafeBrowsingStatusByMaliciousContentStatus( + // Helper function to get the site identification status and details by + // malicious content status. + void GetSiteIdentityByMaliciousContentStatus( security_state::MaliciousContentStatus malicious_content_status, - PageInfo::SafeBrowsingStatus* status, + PageInfo::SiteIdentityStatus* status, base::string16* details); // Retrieves all the permissions that are shown in Page Info. @@ -270,9 +260,6 @@ // Status of the website's identity verification check. SiteIdentityStatus site_identity_status_; - // Safe Browsing status of the website. - SafeBrowsingStatus safe_browsing_status_; - // For secure connection |certificate_| is set to the server certificate. scoped_refptr<net::X509Certificate> certificate_; @@ -284,9 +271,9 @@ // unnecessary UTF-8 string conversions. // Details about the website's identity. If the website's identity has been - // verified then |site_details_message_| contains who verified the identity. + // verified then |site_identity_details_| contains who verified the identity. // This string will be displayed in the UI. - base::string16 site_details_message_; + base::string16 site_identity_details_; // Set when the user has explicitly bypassed an SSL error for this host or // explicitly denied it (the latter of which is not currently possible in the
diff --git a/chrome/browser/ui/page_info/page_info_ui.cc b/chrome/browser/ui/page_info/page_info_ui.cc index 70030d6..11c54a4 100644 --- a/chrome/browser/ui/page_info/page_info_ui.cc +++ b/chrome/browser/ui/page_info/page_info_ui.cc
@@ -232,7 +232,6 @@ PageInfoUI::IdentityInfo::IdentityInfo() : identity_status(PageInfo::SITE_IDENTITY_STATUS_UNKNOWN), - safe_browsing_status(PageInfo::SAFE_BROWSING_STATUS_NONE), connection_status(PageInfo::SITE_CONNECTION_STATUS_UNKNOWN), show_ssl_decision_revoke_button(false), show_change_password_buttons(false) {} @@ -247,41 +246,6 @@ std::unique_ptr<PageInfoUI::SecurityDescription> security_description( new PageInfoUI::SecurityDescription()); - switch (identity_info.safe_browsing_status) { - case PageInfo::SAFE_BROWSING_STATUS_NONE: - break; - case PageInfo::SAFE_BROWSING_STATUS_MALWARE: - return CreateSecurityDescription(SecuritySummaryColor::RED, - IDS_PAGE_INFO_MALWARE_SUMMARY, - IDS_PAGE_INFO_MALWARE_DETAILS); - case PageInfo::SAFE_BROWSING_STATUS_SOCIAL_ENGINEERING: - return CreateSecurityDescription( - SecuritySummaryColor::RED, IDS_PAGE_INFO_SOCIAL_ENGINEERING_SUMMARY, - IDS_PAGE_INFO_SOCIAL_ENGINEERING_DETAILS); - case PageInfo::SAFE_BROWSING_STATUS_UNWANTED_SOFTWARE: - return CreateSecurityDescription(SecuritySummaryColor::RED, - IDS_PAGE_INFO_UNWANTED_SOFTWARE_SUMMARY, - IDS_PAGE_INFO_UNWANTED_SOFTWARE_DETAILS); - case PageInfo::SAFE_BROWSING_STATUS_SIGN_IN_PASSWORD_REUSE: -#if defined(FULL_SAFE_BROWSING) - return CreateSecurityDescriptionForPasswordReuse( - /*is_enterprise_password=*/false); -#endif - NOTREACHED(); - break; - case PageInfo::SAFE_BROWSING_STATUS_ENTERPRISE_PASSWORD_REUSE: -#if defined(FULL_SAFE_BROWSING) - return CreateSecurityDescriptionForPasswordReuse( - /*is_enterprise_password=*/true); -#endif - NOTREACHED(); - break; - case PageInfo::SAFE_BROWSING_STATUS_BILLING: - return CreateSecurityDescription(SecuritySummaryColor::RED, - IDS_PAGE_INFO_BILLING_SUMMARY, - IDS_PAGE_INFO_BILLING_DETAILS); - } - switch (identity_info.identity_status) { case PageInfo::SITE_IDENTITY_STATUS_INTERNAL_PAGE: #if defined(OS_ANDROID) @@ -321,6 +285,32 @@ IDS_PAGE_INFO_SECURE_SUMMARY, IDS_PAGE_INFO_SECURE_DETAILS); } + case PageInfo::SITE_IDENTITY_STATUS_MALWARE: + return CreateSecurityDescription(SecuritySummaryColor::RED, + IDS_PAGE_INFO_MALWARE_SUMMARY, + IDS_PAGE_INFO_MALWARE_DETAILS); + case PageInfo::SITE_IDENTITY_STATUS_SOCIAL_ENGINEERING: + return CreateSecurityDescription( + SecuritySummaryColor::RED, IDS_PAGE_INFO_SOCIAL_ENGINEERING_SUMMARY, + IDS_PAGE_INFO_SOCIAL_ENGINEERING_DETAILS); + case PageInfo::SITE_IDENTITY_STATUS_UNWANTED_SOFTWARE: + return CreateSecurityDescription(SecuritySummaryColor::RED, + IDS_PAGE_INFO_UNWANTED_SOFTWARE_SUMMARY, + IDS_PAGE_INFO_UNWANTED_SOFTWARE_DETAILS); + case PageInfo::SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE: +#if defined(FULL_SAFE_BROWSING) + return CreateSecurityDescriptionForPasswordReuse( + /*is_enterprise_password=*/false); +#endif + case PageInfo::SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE: +#if defined(FULL_SAFE_BROWSING) + return CreateSecurityDescriptionForPasswordReuse( + /*is_enterprise_password=*/true); +#endif + case PageInfo::SITE_IDENTITY_STATUS_BILLING: + return CreateSecurityDescription(SecuritySummaryColor::RED, + IDS_PAGE_INFO_BILLING_SUMMARY, + IDS_PAGE_INFO_BILLING_DETAILS); case PageInfo::SITE_IDENTITY_STATUS_DEPRECATED_SIGNATURE_ALGORITHM: case PageInfo::SITE_IDENTITY_STATUS_UNKNOWN: case PageInfo::SITE_IDENTITY_STATUS_NO_CERT:
diff --git a/chrome/browser/ui/page_info/page_info_ui.h b/chrome/browser/ui/page_info/page_info_ui.h index fb10769..75d32d06 100644 --- a/chrome/browser/ui/page_info/page_info_ui.h +++ b/chrome/browser/ui/page_info/page_info_ui.h
@@ -117,8 +117,6 @@ std::string site_identity; // Status of the site's identity. PageInfo::SiteIdentityStatus identity_status; - // Site's Safe Browsing status. - PageInfo::SafeBrowsingStatus safe_browsing_status; // Textual description of the site's identity status that is displayed to // the user. std::string identity_status_description;
diff --git a/chrome/browser/ui/page_info/page_info_unittest.cc b/chrome/browser/ui/page_info/page_info_unittest.cc index e4836b29..545296d 100644 --- a/chrome/browser/ui/page_info/page_info_unittest.cc +++ b/chrome/browser/ui/page_info/page_info_unittest.cc
@@ -442,8 +442,8 @@ EXPECT_EQ(PageInfo::SITE_CONNECTION_STATUS_UNENCRYPTED, page_info()->site_connection_status()); - EXPECT_EQ(PageInfo::SAFE_BROWSING_STATUS_MALWARE, - page_info()->safe_browsing_status()); + EXPECT_EQ(PageInfo::SITE_IDENTITY_STATUS_MALWARE, + page_info()->site_identity_status()); } TEST_F(PageInfoTest, SocialEngineering) { @@ -454,8 +454,8 @@ EXPECT_EQ(PageInfo::SITE_CONNECTION_STATUS_UNENCRYPTED, page_info()->site_connection_status()); - EXPECT_EQ(PageInfo::SAFE_BROWSING_STATUS_SOCIAL_ENGINEERING, - page_info()->safe_browsing_status()); + EXPECT_EQ(PageInfo::SITE_IDENTITY_STATUS_SOCIAL_ENGINEERING, + page_info()->site_identity_status()); } TEST_F(PageInfoTest, UnwantedSoftware) { @@ -466,8 +466,8 @@ EXPECT_EQ(PageInfo::SITE_CONNECTION_STATUS_UNENCRYPTED, page_info()->site_connection_status()); - EXPECT_EQ(PageInfo::SAFE_BROWSING_STATUS_UNWANTED_SOFTWARE, - page_info()->safe_browsing_status()); + EXPECT_EQ(PageInfo::SITE_IDENTITY_STATUS_UNWANTED_SOFTWARE, + page_info()->site_identity_status()); } #if defined(FULL_SAFE_BROWSING) @@ -479,8 +479,8 @@ EXPECT_EQ(PageInfo::SITE_CONNECTION_STATUS_UNENCRYPTED, page_info()->site_connection_status()); - EXPECT_EQ(PageInfo::SAFE_BROWSING_STATUS_SIGN_IN_PASSWORD_REUSE, - page_info()->safe_browsing_status()); + EXPECT_EQ(PageInfo::SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE, + page_info()->site_identity_status()); } TEST_F(PageInfoTest, EnterprisePasswordReuse) { @@ -491,8 +491,8 @@ EXPECT_EQ(PageInfo::SITE_CONNECTION_STATUS_UNENCRYPTED, page_info()->site_connection_status()); - EXPECT_EQ(PageInfo::SAFE_BROWSING_STATUS_ENTERPRISE_PASSWORD_REUSE, - page_info()->safe_browsing_status()); + EXPECT_EQ(PageInfo::SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE, + page_info()->site_identity_status()); } #endif @@ -768,7 +768,7 @@ EXPECT_EQ( base::UTF8ToUTF16( "This page has been identified as being owned by Google Inc [US]."), - page_info()->site_details_message()); + page_info()->site_identity_details()); } TEST_F(PageInfoTest, HTTPSRevocationError) {
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index a111149a..00ce699e 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -846,14 +846,6 @@ // GetToolbarActionsBar() can be null in testing. if (browser_->window() && browser_->window()->GetToolbarActionsBar() && browser_->window()->GetToolbarActionsBar()->NeedsOverflow()) { -#if defined(OS_MACOSX) - // There's a bug in AppKit menus, where if a menu item with a custom view - // (like the extensions overflow menu) is the first menu item, it is not - // highlightable or keyboard-selectable. - // Adding any menu item before it (even one which is never visible) prevents - // it, so add a bogus item here that will always be hidden. - AddItem(kEmptyMenuItemCommand, base::string16()); -#endif AddItem(IDC_EXTENSIONS_OVERFLOW_MENU, base::string16()); return true; }
diff --git a/chrome/browser/ui/views/accessibility/invert_bubble_view.cc b/chrome/browser/ui/views/accessibility/invert_bubble_view.cc index c1aefc5d..784e1679 100644 --- a/chrome/browser/ui/views/accessibility/invert_bubble_view.cc +++ b/chrome/browser/ui/views/accessibility/invert_bubble_view.cc
@@ -126,8 +126,9 @@ l10n_util::GetStringUTF16(IDS_DARK_THEME), CONTEXT_BODY_TEXT_LARGE); dark_theme->set_listener(this); - views::BoxLayout* layout = SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + views::BoxLayout* layout = + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart);
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc index 632cde7..96e6b39 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc
@@ -111,8 +111,9 @@ AppInfoDialog::AppInfoDialog(Profile* profile, const extensions::Extension* app) : profile_(profile), app_id_(app->id()) { - views::BoxLayout* layout = SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + views::BoxLayout* layout = + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); const int kHorizontalSeparatorHeight = 1; @@ -121,7 +122,7 @@ auto dialog_body_contents = std::make_unique<views::View>(); const ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); dialog_body_contents->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, provider->GetInsetsMetric(views::INSETS_DIALOG_SUBSECTION), provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); dialog_body_contents->AddChildView(
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc index d3833ba..768f0c1d 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc
@@ -36,7 +36,7 @@ ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, provider->GetInsetsMetric(views::INSETS_DIALOG_SUBSECTION), provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL)));
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc index 1265e560..5edf371 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc
@@ -53,7 +53,7 @@ ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, provider->GetInsetsMetric(views::INSETS_DIALOG_SUBSECTION), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_HORIZONTAL))); @@ -73,8 +73,8 @@ // Create a vertical container to store the app's name and link. auto vertical_info_container = std::make_unique<views::View>(); - auto vertical_container_layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + auto vertical_container_layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); vertical_container_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); vertical_info_container->SetLayoutManager(
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc index 331a029..f00106d 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc
@@ -50,7 +50,7 @@ int child_spacing) const { auto vertically_stacked_view = std::make_unique<views::View>(); vertically_stacked_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), child_spacing)); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), child_spacing)); return vertically_stacked_view; } @@ -63,7 +63,8 @@ int child_spacing) const { auto vertically_stacked_view = std::make_unique<views::View>(); vertically_stacked_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), child_spacing)); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + child_spacing)); return vertically_stacked_view; }
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.cc index 1592d56..53d9f42 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.cc
@@ -194,7 +194,7 @@ const extensions::Extension* app) : AppInfoPanel(profile, app) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL)));
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc index f730093a..e344830 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc
@@ -105,7 +105,7 @@ launch_options_combobox_(NULL), weak_ptr_factory_(this) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL))); @@ -122,7 +122,7 @@ auto description_and_labels_stack = std::make_unique<views::View>(); description_and_labels_stack->SetLayoutManager( std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), ChromeLayoutProvider::Get()->GetDistanceMetric( DISTANCE_RELATED_CONTROL_VERTICAL_SMALL)));
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/arc_app_info_links_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/arc_app_info_links_panel.cc index 616d333..e562a6c2 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/arc_app_info_links_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/arc_app_info_links_panel.cc
@@ -27,7 +27,7 @@ app_list_observer_(this), manage_link_(nullptr) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL))); auto manage_link = std::make_unique<views::Link>(
diff --git a/chrome/browser/ui/views/arc_app_dialog_view.cc b/chrome/browser/ui/views/arc_app_dialog_view.cc index 513c494e..f2c02d59 100644 --- a/chrome/browser/ui/views/arc_app_dialog_view.cc +++ b/chrome/browser/ui/views/arc_app_dialog_view.cc
@@ -114,7 +114,7 @@ ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, provider->GetDialogInsetsForContentType(views::TEXT, views::TEXT), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_HORIZONTAL))); @@ -123,8 +123,8 @@ icon_view_ = AddChildView(std::move(icon_view)); auto text_container = std::make_unique<views::View>(); - auto text_container_layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + auto text_container_layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); text_container_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); text_container_layout->set_cross_axis_alignment(
diff --git a/chrome/browser/ui/views/arc_data_removal_dialog_view.cc b/chrome/browser/ui/views/arc_data_removal_dialog_view.cc index df6f157..4009c4fb 100644 --- a/chrome/browser/ui/views/arc_data_removal_dialog_view.cc +++ b/chrome/browser/ui/views/arc_data_removal_dialog_view.cc
@@ -86,7 +86,7 @@ ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); std::unique_ptr<views::BoxLayout> layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, provider->GetDialogInsetsForContentType(views::TEXT, views::TEXT), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_HORIZONTAL)); layout->set_cross_axis_alignment(
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc index c551d495..0bed6a64 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -380,7 +380,8 @@ AutofillPopupController* controller = popup_view_->controller(); auto* layout_manager = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(0, GetHorizontalMargin()))); + views::BoxLayout::Orientation::kHorizontal, + gfx::Insets(0, GetHorizontalMargin()))); layout_manager->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter); @@ -618,7 +619,7 @@ views::BoxLayout* layout_manager = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(0, GetHorizontalMargin()))); layout_manager->set_cross_axis_alignment( @@ -828,8 +829,8 @@ views::Widget* parent_widget) : AutofillPopupBaseView(controller, parent_widget), controller_(controller) { - layout_ = SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + layout_ = SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); layout_->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); CreateChildViews(); @@ -932,8 +933,9 @@ // Create a container to wrap the "regular" (non-footer) rows. std::unique_ptr<views::View> body_container = std::make_unique<views::View>(); - views::BoxLayout* body_layout = body_container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + views::BoxLayout* body_layout = + body_container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); body_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kStart); for (auto* row : rows_) { @@ -967,8 +969,9 @@ if (has_footer) { auto* footer_container = new views::View(); - views::BoxLayout* footer_layout = footer_container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + views::BoxLayout* footer_layout = + footer_container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); footer_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kStart);
diff --git a/chrome/browser/ui/views/autofill/payments/card_unmask_prompt_views.cc b/chrome/browser/ui/views/autofill/payments/card_unmask_prompt_views.cc index cd89993..0d5cadc 100644 --- a/chrome/browser/ui/views/autofill/payments/card_unmask_prompt_views.cc +++ b/chrome/browser/ui/views/autofill/payments/card_unmask_prompt_views.cc
@@ -381,7 +381,7 @@ auto controls_container = std::make_unique<views::View>(); controls_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); controls_container_ = AddChildView(std::move(controls_container)); @@ -399,13 +399,13 @@ // the temporary error label. They are separated by a related distance. auto input_container = std::make_unique<views::View>(); input_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); // Input row, containing month/year dropdowns if needed and the CVC field. auto input_row = std::make_unique<views::View>(); input_row->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), provider->GetDistanceMetric(DISTANCE_RELATED_CONTROL_HORIZONTAL_SMALL))); // Add the month and year comboboxes if the expiration date is needed. @@ -439,7 +439,7 @@ auto temporary_error = std::make_unique<views::View>(); auto* temporary_error_layout = temporary_error->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), provider->GetDistanceMetric( views::DISTANCE_RELATED_LABEL_HORIZONTAL))); temporary_error_layout->set_cross_axis_alignment(
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.cc index 15e89c4..4f2d7134b 100644 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.cc
@@ -103,7 +103,7 @@ void LocalCardMigrationBubbleViews::AddedToWidget() { auto title_container = std::make_unique<views::View>(); title_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), ChromeLayoutProvider::Get()->GetDistanceMetric( DISTANCE_RELATED_CONTROL_VERTICAL_SMALL))); #if defined(GOOGLE_CHROME_BUILD)
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc index 598f2b1a..9b3c2c2 100644 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc +++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc
@@ -148,7 +148,7 @@ constexpr int kCardListSmallVerticalDistance = 8; auto* card_list_view_layout = card_list_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), should_show_checkbox ? kCardListSmallVerticalDistance : provider->GetDistanceMetric( @@ -182,7 +182,7 @@ provider->GetDistanceMetric(views::DISTANCE_RELATED_LABEL_HORIZONTAL); tip_text_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(container_insets), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(container_insets), container_child_space)); tip_text_container->SetBackground(views::CreateSolidBackground( dialog_view->GetNativeTheme()->SystemDarkModeEnabled() @@ -235,7 +235,7 @@ auto feedback_view = std::make_unique<views::View>(); ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); feedback_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); feedback_view->SetBorder(views::CreateEmptyBorder(kMigrationDialogInsets)); @@ -279,12 +279,12 @@ : controller_(controller) { ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), kMigrationDialogMainContainerChildSpacing)); auto* contents_container = new views::View(); contents_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric( views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); // Don't set bottom since there is a legal message view in the offer dialog. @@ -478,7 +478,7 @@ RemoveAllChildViews(/*delete_children=*/true); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), kMigrationDialogMainContainerChildSpacing)); #if defined(GOOGLE_CHROME_BUILD)
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.cc index 6ede8178..91e052e 100644 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.cc +++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.cc
@@ -98,7 +98,7 @@ ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), kMigrationDialogMainContainerChildSpacing)); #if defined(GOOGLE_CHROME_BUILD) @@ -116,7 +116,7 @@ auto* error_view = new views::View(); auto* horizontal_layout = error_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), provider->GetDistanceMetric( views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); horizontal_layout->set_main_axis_alignment(
diff --git a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc b/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc index 4b7183a..82a4559 100644 --- a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc +++ b/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc
@@ -37,7 +37,7 @@ parent_dialog_(parent_dialog) { ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(DISTANCE_CONTENT_LIST_VERTICAL_MULTI))); AddChildView(GetMigratableCardDescriptionView(migratable_credit_card, @@ -47,7 +47,7 @@ checkbox_uncheck_text_container_ = new views::View(); views::BoxLayout* layout = checkbox_uncheck_text_container_->SetLayoutManager( std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(provider->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL), provider->GetDistanceMetric( @@ -95,7 +95,7 @@ migratable_card_description_view->SetLayoutManager( std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), provider->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_HORIZONTAL))); @@ -143,7 +143,7 @@ std::make_unique<views::View>(); card_network_and_last_four_digits->SetLayoutManager( std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), provider->GetDistanceMetric(DISTANCE_RELATED_LABEL_HORIZONTAL_LIST))); ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
diff --git a/chrome/browser/ui/views/autofill/payments/payments_view_util.cc b/chrome/browser/ui/views/autofill/payments/payments_view_util.cc index 1db9948..640d123 100644 --- a/chrome/browser/ui/views/autofill/payments/payments_view_util.cc +++ b/chrome/browser/ui/views/autofill/payments/payments_view_util.cc
@@ -130,8 +130,8 @@ LegalMessageView::LegalMessageView(const LegalMessageLines& legal_message_lines, views::StyledLabelListener* listener) : legal_message_lines_(legal_message_lines) { - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); for (const LegalMessageLine& line : legal_message_lines) { AddChildView(CreateLegalMessageLineLabel(line, listener).release()); }
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views.cc b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views.cc index 4ea7fd8..ca4362a 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views.cc
@@ -158,7 +158,7 @@ ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); // If applicable, add the upload explanation label. Appears above the card @@ -176,7 +176,7 @@ auto* description_view = new views::View(); views::BoxLayout* box_layout = description_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), provider->GetDistanceMetric( views::DISTANCE_RELATED_BUTTON_HORIZONTAL))); view->AddChildView(description_view); @@ -227,8 +227,8 @@ } void SaveCardBubbleViews::Init() { - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); // For server cards, there is an explanation between the title and the // controls; use views::TEXT. For local cards, since there is no explanation, // use views::CONTROL instead.
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_failure_bubble_views.cc b/chrome/browser/ui/views/autofill/payments/save_card_failure_bubble_views.cc index e187d3d..3ef2a360f 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_failure_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/payments/save_card_failure_bubble_views.cc
@@ -30,7 +30,7 @@ ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); main_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); base::string16 explanation = controller()->GetExplanatoryMessage();
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.cc b/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.cc index 376f7575..7738bc4 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.cc
@@ -196,7 +196,7 @@ // padding. Make a new Harmony DistanceMetric? cardholder_name_label_row->SetLayoutManager( std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), provider->GetDistanceMetric( views::DISTANCE_RELATED_BUTTON_HORIZONTAL))); std::unique_ptr<views::Label> cardholder_name_label = @@ -251,7 +251,7 @@ std::unique_ptr<views::View> cardholder_name_view = std::make_unique<views::View>(); cardholder_name_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); cardholder_name_view->AddChildView(cardholder_name_label_row.release()); cardholder_name_view->AddChildView(cardholder_name_textfield_); @@ -269,7 +269,7 @@ auto expiration_date_view = std::make_unique<views::View>(); ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); expiration_date_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); expiration_date_view->SetID(DialogViewId::EXPIRATION_DATE_VIEW); @@ -304,7 +304,7 @@ auto input_row = std::make_unique<views::View>(); input_row->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), provider->GetDistanceMetric(DISTANCE_RELATED_CONTROL_HORIZONTAL_SMALL))); input_row->AddChildView(month_input_dropdown_); input_row->AddChildView(year_input_dropdown_);
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_sign_in_promo_bubble_views.cc b/chrome/browser/ui/views/autofill/payments/save_card_sign_in_promo_bubble_views.cc index 646580b..55179f0d 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_sign_in_promo_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/payments/save_card_sign_in_promo_bubble_views.cc
@@ -44,7 +44,7 @@ ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); view->SetID(DialogViewId::SIGN_IN_PROMO_VIEW);
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index 4849814..67ca8f9 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -836,8 +836,7 @@ x += managed_bookmarks_pref.width() + bookmark_bar_button_padding; } - if (model_->loaded() && - model_->bookmark_bar_node()->child_count() > 0) { + if (model_->loaded() && !model_->bookmark_bar_node()->children().empty()) { bool last_visible = x < max_x; size_t button_count = bookmark_buttons_.size(); for (size_t i = 0; i <= button_count; ++i) { @@ -1814,7 +1813,7 @@ ->children()[location->index.value()] .get(); location->operation = chrome::GetBookmarkDropOperation( - profile, event, data, parent, parent->child_count()); + profile, event, data, parent, parent->children().size()); if (!location->operation && !data.has_single_url() && data.GetFirstNode(model_, profile->GetPath()) == parent) { // Don't open a menu if the node being dragged is the menu to open.
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc index 5246dc83..9fee624 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc
@@ -348,11 +348,11 @@ controller.reset(new BookmarkContextMenu( nullptr, nullptr, profile_.get(), nullptr, BOOKMARK_LAUNCH_LOCATION_NONE, nodes[0]->parent(), nodes, false)); - int old_count = bb_node->child_count(); + size_t old_count = bb_node->children().size(); controller->ExecuteCommand(IDC_PASTE, 0); ASSERT_TRUE(bb_node->GetChild(1)->is_url()); - ASSERT_EQ(old_count + 1, bb_node->child_count()); + ASSERT_EQ(old_count + 1, bb_node->children().size()); ASSERT_EQ(bb_node->GetChild(0)->url(), bb_node->GetChild(1)->url()); controller.reset(new BookmarkContextMenu( @@ -362,7 +362,7 @@ controller->ExecuteCommand(IDC_CUT, 0); ASSERT_TRUE(bb_node->GetChild(0)->is_url()); ASSERT_TRUE(bb_node->GetChild(1)->is_folder()); - ASSERT_EQ(old_count, bb_node->child_count()); + ASSERT_EQ(old_count, bb_node->children().size()); } // Tests that the "Show managed bookmarks" option in the context menu is only
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc index f2186a8..eddd3d9 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
@@ -491,23 +491,23 @@ std::make_unique<EditorNode>(base::string16(), 0); const BookmarkNode* bb_root_node = bb_model_->root_node(); CreateNodes(bb_root_node, root_node.get()); - DCHECK(root_node->child_count() >= 2 && root_node->child_count() <= 4); + DCHECK_GE(root_node->children().size(), 2u); + DCHECK_LE(root_node->children().size(), 4u); DCHECK_EQ(BookmarkNode::BOOKMARK_BAR, bb_root_node->GetChild(0)->type()); DCHECK_EQ(BookmarkNode::OTHER_NODE, bb_root_node->GetChild(1)->type()); - if (root_node->child_count() >= 3) + if (root_node->children().size() >= 3) DCHECK_EQ(BookmarkNode::MOBILE, bb_root_node->GetChild(2)->type()); return root_node; } void BookmarkEditorView::CreateNodes(const BookmarkNode* bb_node, BookmarkEditorView::EditorNode* b_node) { - for (int i = 0; i < bb_node->child_count(); ++i) { - const BookmarkNode* child_bb_node = bb_node->GetChild(i); + for (const auto& child_bb_node : bb_node->children()) { if (child_bb_node->IsVisible() && child_bb_node->is_folder() && - bb_model_->client()->CanBeEditedByUser(child_bb_node)) { + bb_model_->client()->CanBeEditedByUser(child_bb_node.get())) { EditorNode* new_b_node = b_node->Add(std::make_unique<EditorNode>( child_bb_node->GetTitle(), child_bb_node->id())); - CreateNodes(child_bb_node, new_b_node); + CreateNodes(child_bb_node.get(), new_b_node); } } } @@ -517,8 +517,8 @@ int64_t id) { if (node->value == id) return node; - for (int i = 0; i < node->child_count(); ++i) { - EditorNode* result = FindNodeWithID(node->GetChild(i), id); + for (const auto& child : node->children()) { + EditorNode* result = FindNodeWithID(child.get(), id); if (result) return result; } @@ -581,8 +581,7 @@ const BookmarkNode** parent_bb_node) { if (parent_b_node == b_node) *parent_bb_node = bb_node; - for (int i = 0; i < b_node->child_count(); ++i) { - EditorNode* child_b_node = b_node->GetChild(i); + for (const auto& child_b_node : b_node->children()) { const BookmarkNode* child_bb_node = nullptr; if (child_b_node->value == 0) { // New folder. @@ -592,17 +591,16 @@ } else { // Existing node, reset the title (BookmarkModel ignores changes if the // title is the same). - for (int j = 0; j < bb_node->child_count(); ++j) { - const BookmarkNode* node = bb_node->GetChild(j); - if (node->is_folder() && node->id() == child_b_node->value) { - child_bb_node = node; - break; - } - } - DCHECK(child_bb_node); + const auto i = std::find_if( + bb_node->children().cbegin(), bb_node->children().cend(), + [&child_b_node](const auto& node) { + return node->is_folder() && node->id() == child_b_node->value; + }); + DCHECK(i != bb_node->children().cend()); + child_bb_node = i->get(); bb_model_->SetTitle(child_bb_node, child_b_node->GetTitle()); } - ApplyNameChangesAndCreateNewFolders(child_bb_node, child_b_node, + ApplyNameChangesAndCreateNewFolders(child_bb_node, child_b_node.get(), parent_b_node, parent_bb_node); } } @@ -619,8 +617,8 @@ bookmarks::GetBookmarkNodeByID(bb_model_, editor_node->value)); } - for (int i = 0; i < editor_node->child_count(); ++i) - UpdateExpandedNodes(editor_node->GetChild(i), expanded_nodes); + for (const auto& child : editor_node->children()) + UpdateExpandedNodes(child.get(), expanded_nodes); } ui::SimpleMenuModel* BookmarkEditorView::GetMenuModel() {
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc index 1b44574..234459bc 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc
@@ -158,25 +158,22 @@ BookmarkEditorView::EditorNode* editor_root = editor_tree_model()->GetRoot(); // The root should have two or three children: bookmark bar, other bookmarks // and conditionally mobile bookmarks. - if (model_->mobile_node()->IsVisible()) { - ASSERT_EQ(3, editor_root->child_count()); - } else { - ASSERT_EQ(2, editor_root->child_count()); - } + ASSERT_EQ(model_->mobile_node()->IsVisible() ? 3u : 2u, + editor_root->children().size()); BookmarkEditorView::EditorNode* bb_node = editor_root->GetChild(0); // The root should have 2 nodes: folder F1 and F2. - ASSERT_EQ(2, bb_node->child_count()); + ASSERT_EQ(2u, bb_node->children().size()); ASSERT_EQ(ASCIIToUTF16("F1"), bb_node->GetChild(0)->GetTitle()); ASSERT_EQ(ASCIIToUTF16("F2"), bb_node->GetChild(1)->GetTitle()); // F1 should have one child, F11 - ASSERT_EQ(1, bb_node->GetChild(0)->child_count()); + ASSERT_EQ(1u, bb_node->GetChild(0)->children().size()); ASSERT_EQ(ASCIIToUTF16("F11"), bb_node->GetChild(0)->GetChild(0)->GetTitle()); BookmarkEditorView::EditorNode* other_node = editor_root->GetChild(1); // Other node should have one child (OF1). - ASSERT_EQ(1, other_node->child_count()); + ASSERT_EQ(1u, other_node->children().size()); ASSERT_EQ(ASCIIToUTF16("OF1"), other_node->GetChild(0)->GetTitle()); } @@ -266,7 +263,7 @@ const BookmarkNode* mf2 = bb_node->GetChild(1); // F2 in the model should have two children now: F21 and the node edited. - ASSERT_EQ(2, mf2->child_count()); + ASSERT_EQ(2u, mf2->children().size()); // F21 should be first. ASSERT_EQ(ASCIIToUTF16("F21"), mf2->GetChild(0)->GetTitle()); // Then a. @@ -274,7 +271,7 @@ // F21 should have one child, F211. const BookmarkNode* mf21 = mf2->GetChild(0); - ASSERT_EQ(1, mf21->child_count()); + ASSERT_EQ(1u, mf21->children().size()); ASSERT_EQ(ASCIIToUTF16("F211"), mf21->GetChild(0)->GetTitle()); } @@ -292,7 +289,7 @@ ApplyEdits(editor_tree_model()->GetRoot()->GetChild(0)); - ASSERT_EQ(4, bb_node->child_count()); + ASSERT_EQ(4u, bb_node->children().size()); const BookmarkNode* new_node = bb_node->GetChild(1); @@ -313,7 +310,7 @@ ApplyEdits(NULL); const BookmarkNode* other_node = model_->other_node(); - ASSERT_EQ(2, other_node->child_count()); + ASSERT_EQ(2u, other_node->children().size()); const BookmarkNode* new_node = other_node->GetChild(0); @@ -333,7 +330,7 @@ ApplyEdits(NULL); const BookmarkNode* other_node = model_->other_node(); - ASSERT_EQ(2, other_node->child_count()); + ASSERT_EQ(2u, other_node->children().size()); const BookmarkNode* new_node = other_node->GetChild(0); @@ -360,7 +357,7 @@ ApplyEdits(editor_tree_model()->GetRoot()->GetChild(0)); - ASSERT_EQ(4, kBBNode->child_count()); + ASSERT_EQ(4u, kBBNode->children().size()); const BookmarkNode* kNewNode = kBBNode->GetChild(1); @@ -384,12 +381,12 @@ ApplyEdits(editor_tree_model()->GetRoot()->GetChild(0)); // Make sure the folder was created. - ASSERT_EQ(4, bb_node->child_count()); + ASSERT_EQ(4u, bb_node->children().size()); const BookmarkNode* new_node = bb_node->GetChild(1); EXPECT_EQ(BookmarkNode::FOLDER, new_node->type()); EXPECT_EQ(ASCIIToUTF16("new_F"), new_node->GetTitle()); // The node should have one child. - ASSERT_EQ(1, new_node->child_count()); + ASSERT_EQ(1u, new_node->children().size()); const BookmarkNode* new_child = new_node->GetChild(0); // Make sure the child url/title match. EXPECT_EQ(BookmarkNode::URL, new_child->type()); @@ -413,12 +410,12 @@ ApplyEdits(editor_tree_model()->GetRoot()->GetChild(1)); // Make sure the folder we edited is still there. - ASSERT_EQ(3, model_->other_node()->child_count()); + ASSERT_EQ(3u, model_->other_node()->children().size()); const BookmarkNode* new_node = model_->other_node()->GetChild(2); EXPECT_EQ(BookmarkNode::FOLDER, new_node->type()); EXPECT_EQ(ASCIIToUTF16("new_F"), new_node->GetTitle()); // The node should have one child. - ASSERT_EQ(1, new_node->child_count()); + ASSERT_EQ(1u, new_node->children().size()); const BookmarkNode* new_child = new_node->GetChild(0); // Make sure the child url/title match. EXPECT_EQ(BookmarkNode::URL, new_child->type()); @@ -446,7 +443,7 @@ ApplyEdits(); // Verify the new folder was added and title set appropriately. - ASSERT_EQ(1, parent->child_count()); + ASSERT_EQ(1u, parent->children().size()); const BookmarkNode* new_folder = parent->GetChild(0); ASSERT_TRUE(new_folder->is_folder()); EXPECT_EQ("modified", base::UTF16ToASCII(new_folder->GetTitle()));
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc index 19b4e85..dbba7504 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc
@@ -304,7 +304,7 @@ case views::MenuDelegate::DROP_ON: DCHECK(drop_node->is_folder()); drop_parent = drop_node; - index_to_drop_at = drop_node->child_count(); + index_to_drop_at = drop_node->children().size(); break; case views::MenuDelegate::DROP_BEFORE: @@ -312,7 +312,7 @@ drop_node == model->mobile_node()) { // This can happen with SHOW_PERMANENT_FOLDERS. drop_parent = model->bookmark_bar_node(); - index_to_drop_at = drop_parent->child_count(); + index_to_drop_at = drop_parent->children().size(); } break; @@ -368,7 +368,8 @@ void BookmarkMenuDelegate::WillShowMenu(MenuItemView* menu) { auto iter = menu_id_to_node_map_.find(menu->GetCommand()); - if ((iter != menu_id_to_node_map_.end()) && iter->second->child_count() && + if ((iter != menu_id_to_node_map_.end()) && + !iter->second->children().empty() && menu->GetSubmenu()->GetMenuItems().empty()) BuildMenu(iter->second, 0, menu); } @@ -463,8 +464,8 @@ return false; const bool is_only_child_of_other_folder = - (node->parent() == GetBookmarkModel()->other_node() && - node->parent()->child_count() == 1); + node->parent() == GetBookmarkModel()->other_node() && + node->parent()->children().size() == 1; const bool is_child_of_bookmark_bar = node->parent() == GetBookmarkModel()->bookmark_bar_node(); // The 'other' bookmarks folder hides when it has no more items, so we need
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc index 88f34f36..ecdb1f4 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc
@@ -219,7 +219,7 @@ // Destroy the current delegate so that it doesn't have any references to // deleted nodes. DestroyDelegate(); - while (model_->other_node()->child_count() > 1) + while (model_->other_node()->children().size() > 1) model_->Remove(model_->other_node()->GetChild(1)); NewDelegate();
diff --git a/chrome/browser/ui/views/chrome_cleaner_dialog_win.cc b/chrome/browser/ui/views/chrome_cleaner_dialog_win.cc index 260c867..3b21ed6f 100644 --- a/chrome/browser/ui/views/chrome_cleaner_dialog_win.cc +++ b/chrome/browser/ui/views/chrome_cleaner_dialog_win.cc
@@ -65,7 +65,7 @@ set_margins( layout_provider->GetDialogInsetsForContentType(views::TEXT, views::TEXT)); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), layout_provider->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL))); views::Label* label = new views::Label(
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc index c6e04a2d..fe4a4b29 100644 --- a/chrome/browser/ui/views/collected_cookies_views.cc +++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -215,7 +215,7 @@ DISTANCE_RELATED_CONTROL_VERTICAL_SMALL), dialog_insets.right()); content_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, layout_insets, + views::BoxLayout::Orientation::kHorizontal, layout_insets, ChromeLayoutProvider::Get()->GetDistanceMetric( DISTANCE_RELATED_CONTROL_HORIZONTAL_SMALL))); content_->AddChildView(info_image_);
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc index 69b51ed..706f862 100644 --- a/chrome/browser/ui/views/content_setting_bubble_contents.cc +++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -386,7 +386,7 @@ DCHECK(content_setting_bubble_model_); const ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); std::vector<LayoutRow> rows; @@ -525,7 +525,7 @@ return std::move(extra_views.front()); auto container = std::make_unique<views::View>(); container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), layout->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_HORIZONTAL))); for (auto& extra_view : extra_views) container->AddChildView(std::move(extra_view));
diff --git a/chrome/browser/ui/views/content_setting_domain_list_view.cc b/chrome/browser/ui/views/content_setting_domain_list_view.cc index 074e34ff..b5c0ffb 100644 --- a/chrome/browser/ui/views/content_setting_domain_list_view.cc +++ b/chrome/browser/ui/views/content_setting_domain_list_view.cc
@@ -14,8 +14,8 @@ ContentSettingDomainListView::ContentSettingDomainListView( const base::string16& title, const std::set<std::string>& domains) { - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); auto title_label = std::make_unique<views::Label>(title); title_label->SetMultiLine(true);
diff --git a/chrome/browser/ui/views/crostini/crostini_app_installer_view.cc b/chrome/browser/ui/views/crostini/crostini_app_installer_view.cc index f322acb..ace83c9 100644 --- a/chrome/browser/ui/views/crostini/crostini_app_installer_view.cc +++ b/chrome/browser/ui/views/crostini/crostini_app_installer_view.cc
@@ -43,7 +43,7 @@ : profile_(profile), package_info_(package_info) { views::LayoutProvider* provider = views::LayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, provider->GetInsetsMetric(views::InsetsMetric::INSETS_DIALOG), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); set_margins(provider->GetDialogInsetsForContentType(
diff --git a/chrome/browser/ui/views/crostini/crostini_app_restart_view.cc b/chrome/browser/ui/views/crostini/crostini_app_restart_view.cc index c4a5cc9..5d0d456 100644 --- a/chrome/browser/ui/views/crostini/crostini_app_restart_view.cc +++ b/chrome/browser/ui/views/crostini/crostini_app_restart_view.cc
@@ -70,7 +70,7 @@ : id_(id), display_id_(display_id) { views::LayoutProvider* provider = views::LayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, provider->GetInsetsMetric(views::InsetsMetric::INSETS_DIALOG), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); set_margins(provider->GetDialogInsetsForContentType(
diff --git a/chrome/browser/ui/views/crostini/crostini_app_uninstaller_view.cc b/chrome/browser/ui/views/crostini/crostini_app_uninstaller_view.cc index 2f583ab..88923eb 100644 --- a/chrome/browser/ui/views/crostini/crostini_app_uninstaller_view.cc +++ b/chrome/browser/ui/views/crostini/crostini_app_uninstaller_view.cc
@@ -82,7 +82,7 @@ : profile_(profile), app_id_(app_id), weak_ptr_factory_(this) { views::LayoutProvider* provider = views::LayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, provider->GetInsetsMetric(views::InsetsMetric::INSETS_DIALOG), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); set_margins(provider->GetDialogInsetsForContentType(
diff --git a/chrome/browser/ui/views/crostini/crostini_installer_view.cc b/chrome/browser/ui/views/crostini/crostini_installer_view.cc index 63f57665..3a09a2a 100644 --- a/chrome/browser/ui/views/crostini/crostini_installer_view.cc +++ b/chrome/browser/ui/views/crostini/crostini_installer_view.cc
@@ -509,17 +509,19 @@ views::BoxLayout* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), kDialogSpacingVertical)); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), + kDialogSpacingVertical)); views::View* upper_container_view = new views::View(); upper_container_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, kDialogInsets, kDialogSpacingVertical)); + views::BoxLayout::Orientation::kVertical, kDialogInsets, + kDialogSpacingVertical)); AddChildView(upper_container_view); views::View* lower_container_view = new views::View(); views::BoxLayout* lower_container_layout = lower_container_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, kLowerContainerInsets)); + views::BoxLayout::Orientation::kVertical, kLowerContainerInsets)); AddChildView(lower_container_view); logo_image_ = new views::ImageView(); @@ -549,8 +551,8 @@ // Make a view to keep |message_label_| and |learn_more_link_| together with // less vertical spacing than the other dialog views. views::View* message_view = new views::View(); - message_view->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + message_view->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); message_label_ = new views::Label(message); message_label_->SetMultiLine(true); message_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
diff --git a/chrome/browser/ui/views/crostini/crostini_uninstaller_view.cc b/chrome/browser/ui/views/crostini/crostini_uninstaller_view.cc index d728ada..421ce601 100644 --- a/chrome/browser/ui/views/crostini/crostini_uninstaller_view.cc +++ b/chrome/browser/ui/views/crostini/crostini_uninstaller_view.cc
@@ -123,7 +123,7 @@ : profile_(profile), weak_ptr_factory_(this) { views::LayoutProvider* provider = views::LayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, provider->GetInsetsMetric(views::InsetsMetric::INSETS_DIALOG), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); set_margins(provider->GetDialogInsetsForContentType(
diff --git a/chrome/browser/ui/views/crostini/crostini_upgrade_container_view.cc b/chrome/browser/ui/views/crostini/crostini_upgrade_container_view.cc index 1b376b3..ddba91a 100644 --- a/chrome/browser/ui/views/crostini/crostini_upgrade_container_view.cc +++ b/chrome/browser/ui/views/crostini/crostini_upgrade_container_view.cc
@@ -121,7 +121,7 @@ views::LayoutProvider* provider = views::LayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, provider->GetInsetsMetric(views::InsetsMetric::INSETS_DIALOG), kDialogSpacingVertical)); set_margins(provider->GetDialogInsetsForContentType(
diff --git a/chrome/browser/ui/views/crostini/crostini_upgrade_view.cc b/chrome/browser/ui/views/crostini/crostini_upgrade_view.cc index c1cec7a2..3891572 100644 --- a/chrome/browser/ui/views/crostini/crostini_upgrade_view.cc +++ b/chrome/browser/ui/views/crostini/crostini_upgrade_view.cc
@@ -72,7 +72,7 @@ CrostiniUpgradeView::CrostiniUpgradeView() { views::LayoutProvider* provider = views::LayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, provider->GetInsetsMetric(views::InsetsMetric::INSETS_DIALOG), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); set_margins(provider->GetDialogInsetsForContentType(
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc index 199fe91..6fae6060 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
@@ -65,7 +65,7 @@ const ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, provider->GetDialogInsetsForContentType(views::TEXT, views::CONTROL), provider->GetDistanceMetric(DISTANCE_RELATED_CONTROL_VERTICAL_SMALL)));
diff --git a/chrome/browser/ui/views/device_chooser_content_view.cc b/chrome/browser/ui/views/device_chooser_content_view.cc index f52d6f8..18c25098 100644 --- a/chrome/browser/ui/views/device_chooser_content_view.cc +++ b/chrome/browser/ui/views/device_chooser_content_view.cc
@@ -338,7 +338,7 @@ auto container = std::make_unique<views::View>(); auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_HORIZONTAL)); layout->set_cross_axis_alignment(
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc index 6fb62c55..8d1e559c 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
@@ -59,8 +59,8 @@ RatingsView(double rating, int rating_count) : rating_(rating), rating_count_(rating_count) { SetID(ExtensionInstallDialogView::kRatingsViewId); - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); } ~RatingsView() override {} @@ -127,7 +127,7 @@ explicit PermissionsView(int available_width) : available_width_(available_width) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL))); } @@ -328,7 +328,7 @@ auto webstore_data_container = std::make_unique<views::View>(); webstore_data_container->SetLayoutManager( std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric( DISTANCE_RELATED_CONTROL_VERTICAL_SMALL))); @@ -336,7 +336,7 @@ auto rating_container = std::make_unique<views::View>(); rating_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_LABEL_HORIZONTAL))); auto rating = std::make_unique<RatingsView>(prompt_->average_rating(), prompt_->rating_count()); @@ -474,7 +474,7 @@ extension_info_container->SetBorder(views::CreateEmptyBorder( 0, content_insets.left(), 0, content_insets.right())); extension_info_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); const int content_width = GetPreferredSize().width() - extension_info_container->GetInsets().width(); @@ -573,7 +573,8 @@ const int bottom_padding = ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(0, 0, bottom_padding, 0), + views::BoxLayout::Orientation::kVertical, + gfx::Insets(0, 0, bottom_padding, 0), ChromeLayoutProvider::Get()->GetDistanceMetric( DISTANCE_RELATED_CONTROL_VERTICAL_SMALL)));
diff --git a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc index 4ff75c8..d3d71432 100644 --- a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc +++ b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc
@@ -267,7 +267,7 @@ ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL)); layout->set_minimum_cross_axis_size(kRightColumnWidth); // Indent by the size of the icon.
diff --git a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc index 2fa90b1..63ccb0b 100644 --- a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc
@@ -198,7 +198,7 @@ extension_misc::EXTENSION_ICON_SMALL))) { ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); // Add margins for the icon plus the icon-title padding so that the dialog
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_button.cc b/chrome/browser/ui/views/extensions/extensions_menu_button.cc index 5fe5c1d..554193f 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_button.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_button.cc
@@ -128,8 +128,8 @@ void ExtensionsMenuButton::ConfigureSecondaryView() { views::View* container = secondary_view(); DCHECK(container->children().empty()); - container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); const SkColor icon_color = ui::NativeTheme::GetInstanceForNativeUi()->SystemDarkModeEnabled()
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_view.cc index abee5979..df1b77c 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_view.cc
@@ -55,8 +55,8 @@ EnableUpDownKeyboardAccelerators(); - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); Repopulate(); } @@ -140,8 +140,8 @@ auto extension_buttons = std::make_unique<views::View>(); extension_menu_button_container_for_testing_ = extension_buttons.get(); - extension_buttons->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + extension_buttons->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); auto add_group = [this, &extension_buttons](
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc index 32899b1..05bd430c 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
@@ -133,7 +133,8 @@ provider->GetDistanceMetric(DISTANCE_RELATED_CONTROL_VERTICAL_SMALL); auto scroll_container = std::make_unique<ScrollableView>(); scroll_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), small_vertical_padding)); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), + small_vertical_padding)); scroll_container->SetBorder( views::CreateEmptyBorder(vertical_padding, 0, vertical_padding, 0));
diff --git a/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.cc b/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.cc index 13a0826..187198a 100644 --- a/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.cc +++ b/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.cc
@@ -29,8 +29,8 @@ views::ButtonListener* button_listener, views::ContextMenuController* menu_controller) { DCHECK(button_listener != NULL); - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); const gfx::Insets dialog_insets = provider->GetInsetsMetric(views::INSETS_DIALOG);
diff --git a/chrome/browser/ui/views/extensions/pwa_confirmation_bubble_view.cc b/chrome/browser/ui/views/extensions/pwa_confirmation_bubble_view.cc index a0f86cd..8adefa8 100644 --- a/chrome/browser/ui/views/extensions/pwa_confirmation_bubble_view.cc +++ b/chrome/browser/ui/views/extensions/pwa_confirmation_bubble_view.cc
@@ -104,14 +104,15 @@ int icon_label_spacing = layout_provider->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_HORIZONTAL); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), icon_label_spacing)); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + icon_label_spacing)); AddChildView(CreateIconView(web_app_info_->icons).release()); views::View* labels = new views::View(); AddChildView(labels); - labels->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + labels->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); labels->AddChildView(CreateNameLabel(web_app_info_->title).release()); labels->AddChildView(
diff --git a/chrome/browser/ui/views/feature_promos/feature_promo_bubble_view.cc b/chrome/browser/ui/views/feature_promos/feature_promo_bubble_view.cc index e523867aa..29d340c 100644 --- a/chrome/browser/ui/views/feature_promos/feature_promo_bubble_view.cc +++ b/chrome/browser/ui/views/feature_promos/feature_promo_bubble_view.cc
@@ -87,7 +87,7 @@ ThemeProperties::COLOR_FEATURE_PROMO_BUBBLE_TEXT); auto box_layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, kBubbleContentsInsets, 0); + views::BoxLayout::Orientation::kVertical, kBubbleContentsInsets, 0); box_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); box_layout->set_cross_axis_alignment(
diff --git a/chrome/browser/ui/views/find_bar_view.cc b/chrome/browser/ui/views/find_bar_view.cc index 4d09b88..68df677d 100644 --- a/chrome/browser/ui/views/find_bar_view.cc +++ b/chrome/browser/ui/views/find_bar_view.cc
@@ -240,7 +240,7 @@ find_text_->SetBorder(views::NullBorder()); auto* manager = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(provider->GetInsetsMetric(INSETS_TOAST) - horizontal_margin), 0));
diff --git a/chrome/browser/ui/views/frame/hosted_app_button_container.cc b/chrome/browser/ui/views/frame/hosted_app_button_container.cc index a997957..95e60d3 100644 --- a/chrome/browser/ui/views/frame/hosted_app_button_container.cc +++ b/chrome/browser/ui/views/frame/hosted_app_button_container.cc
@@ -149,7 +149,7 @@ ContentSettingImageView::Delegate* delegate) { views::BoxLayout& layout = *SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_HORIZONTAL))); // Right align to clip the leftmost items first when not enough space. @@ -190,7 +190,7 @@ views::BoxLayout& layout = *SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(0, right_margin.value_or(HorizontalPaddingBetweenItems())), HorizontalPaddingBetweenItems()));
diff --git a/chrome/browser/ui/views/hover_button.h b/chrome/browser/ui/views/hover_button.h index 820bf2a..a30368a79 100644 --- a/chrome/browser/ui/views/hover_button.h +++ b/chrome/browser/ui/views/hover_button.h
@@ -28,8 +28,6 @@ class View; } // namespace views -class PageInfoBubbleViewBrowserTest; - // A button taking the full width of its parent that shows a background color // when hovered over. class HoverButton : public views::MenuButton, public views::MenuButtonListener { @@ -122,7 +120,6 @@ SetStatusLabel); FRIEND_TEST_ALL_PREFIXES(ExtensionsMenuButtonTest, UpdatesToDisplayCorrectActionTitle); - friend class PageInfoBubbleViewBrowserTest; views::StyledLabel* title_ = nullptr; views::Label* subtitle_ = nullptr;
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view.cc b/chrome/browser/ui/views/intent_picker_bubble_view.cc index 285c06b..e026f499 100644 --- a/chrome/browser/ui/views/intent_picker_bubble_view.cc +++ b/chrome/browser/ui/views/intent_picker_bubble_view.cc
@@ -331,8 +331,8 @@ // Creates a view to hold the views for each app. auto scrollable_view = std::make_unique<views::View>(); - scrollable_view->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + scrollable_view->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); size_t i = 0; size_t to_erase = app_info_.size();
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc index 85c0cf0d..5641d29 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -382,7 +382,7 @@ const int spacing = provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_HORIZONTAL); auto box_layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, provider->GetInsetsMetric(INSETS_TOAST) - margins(), spacing); box_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter);
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_no_sinks_view.cc b/chrome/browser/ui/views/media_router/cast_dialog_no_sinks_view.cc index 7be6ab9..523abc1a 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_no_sinks_view.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_no_sinks_view.cc
@@ -37,8 +37,8 @@ CastDialogNoSinksView::CastDialogNoSinksView(Profile* profile) : profile_(profile), weak_factory_(this) { - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); looking_for_sinks_view_ = CreateLookingForSinksView(); AddChildView(looking_for_sinks_view_);
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view.cc b/chrome/browser/ui/views/media_router/cast_dialog_view.cc index 0aceea0e..371ee91 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_view.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_view.cc
@@ -351,8 +351,8 @@ void CastDialogView::PopulateScrollView(const std::vector<UIMediaSink>& sinks) { sink_buttons_.clear(); auto sink_list_view = std::make_unique<views::View>(); - sink_list_view->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + sink_list_view->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); for (size_t i = 0; i < sinks.size(); i++) { const UIMediaSink& sink = sinks.at(i); CastDialogSinkButton* sink_button =
diff --git a/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc b/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc index 5f153ef..2254df7 100644 --- a/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc +++ b/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc
@@ -127,8 +127,8 @@ dialog_title_( l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_REMOTING_DIALOG_TITLE)) { DCHECK(pref_service_); - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); // Depress the Cast toolbar icon. action_controller_->OnDialogShown(); }
diff --git a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc index 2a617c6..78b2286 100644 --- a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc +++ b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
@@ -163,8 +163,8 @@ location_bar_view_ = new LocationBarView(nullptr, profile, &command_updater_, this, true); - auto box_owner = - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + auto box_owner = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); box_owner->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch); auto* box = SetLayoutManager(std::move(box_owner));
diff --git a/chrome/browser/ui/views/omnibox/remove_suggestion_bubble.cc b/chrome/browser/ui/views/omnibox/remove_suggestion_bubble.cc index 6cfcb5f..452b8b4 100644 --- a/chrome/browser/ui/views/omnibox/remove_suggestion_bubble.cc +++ b/chrome/browser/ui/views/omnibox/remove_suggestion_bubble.cc
@@ -34,8 +34,8 @@ DCHECK(template_url_service); DCHECK(match_.SupportsDeletion()); - auto* layout_manager = SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + auto* layout_manager = SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); layout_manager->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart); // TODO(tommycli): Replace this with the real spacing from UX.
diff --git a/chrome/browser/ui/views/page_action/omnibox_page_action_icon_container_view.cc b/chrome/browser/ui/views/page_action/omnibox_page_action_icon_container_view.cc index cf458b30..97bd5ab1 100644 --- a/chrome/browser/ui/views/page_action/omnibox_page_action_icon_container_view.cc +++ b/chrome/browser/ui/views/page_action/omnibox_page_action_icon_container_view.cc
@@ -27,7 +27,7 @@ views::BoxLayout& layout = *SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), params.between_icon_spacing)); // Right align to clip the leftmost items first when not enough space. layout.set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kEnd);
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc index fc55d5a..2955f62 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc
@@ -258,7 +258,8 @@ layout->StartRow(views::GridLayout::kFixedSize, label_column_status); auto ev_certificate_label_container = std::make_unique<views::View>(); ev_certificate_label_container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); ev_certificate_label_container_ = layout->AddView(std::move(ev_certificate_label_container), 1.0, 1.0, views::GridLayout::FILL, views::GridLayout::LEADING); @@ -266,7 +267,8 @@ layout->StartRow(views::GridLayout::kFixedSize, label_column_status); auto reset_decisions_label_container = std::make_unique<views::View>(); reset_decisions_label_container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); reset_decisions_label_container_ = layout->AddView(std::move(reset_decisions_label_container), 1.0, 1.0, views::GridLayout::FILL, views::GridLayout::LEADING); @@ -390,8 +392,8 @@ (change_password_button->CalculatePreferredSize().width() + whitelist_password_reuse_button->CalculatePreferredSize().width()); auto layout = std::make_unique<views::BoxLayout>( - can_fit_in_one_line ? views::BoxLayout::kHorizontal - : views::BoxLayout::kVertical, + can_fit_in_one_line ? views::BoxLayout::Orientation::kHorizontal + : views::BoxLayout::Orientation::kVertical, gfx::Insets(), kSpacingBetweenButtons); // Make buttons left-aligned. For RTL languages, buttons will automatically // become right-aligned. @@ -892,7 +894,8 @@ return; auto* layout = page_feature_info_view_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch); @@ -1004,8 +1007,9 @@ std::unique_ptr<views::View> PageInfoBubbleView::CreateSiteSettingsView() { auto site_settings_view = std::make_unique<views::View>(); - auto* box_layout = site_settings_view->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + auto* box_layout = + site_settings_view->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); box_layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch);
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.h b/chrome/browser/ui/views/page_info/page_info_bubble_view.h index 1606724..d1f8f8a 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view.h +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.h
@@ -15,7 +15,6 @@ #include "chrome/browser/ui/page_info/page_info_dialog.h" #include "chrome/browser/ui/page_info/page_info_ui.h" #include "chrome/browser/ui/views/bubble_anchor_util_views.h" -#include "chrome/browser/ui/views/hover_button.h" #include "chrome/browser/ui/views/page_info/chosen_object_view_observer.h" #include "chrome/browser/ui/views/page_info/page_info_bubble_view_base.h" #include "chrome/browser/ui/views/page_info/permission_selector_row.h" @@ -25,12 +24,12 @@ #include "ui/views/controls/button/button.h" #include "ui/views/controls/link_listener.h" #include "ui/views/controls/separator.h" -#include "ui/views/controls/styled_label.h" #include "ui/views/controls/styled_label_listener.h" #include "ui/views/widget/widget.h" class BubbleHeaderView; class GURL; +class HoverButton; class Profile; namespace content {
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc index 278f9ac65..d49f50c3 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
@@ -50,8 +50,6 @@ namespace { -constexpr char kExpiredCertificateFile[] = "expired_cert.pem"; - class ClickEvent : public ui::Event { public: ClickEvent() : ui::Event(ui::ET_UNKNOWN, base::TimeTicks(), 0) {} @@ -142,7 +140,6 @@ constexpr char kUnwantedSoftware[] = "UnwantedSoftware"; constexpr char kSignInPasswordReuse[] = "SignInPasswordReuse"; constexpr char kEnterprisePasswordReuse[] = "EnterprisePasswordReuse"; - constexpr char kMalwareAndBadCert[] = "MalwareAndBadCert"; constexpr char kMixedContentForm[] = "MixedContentForm"; constexpr char kMixedContent[] = "MixedContent"; constexpr char kAllowAllPermissions[] = "AllowAllPermissions"; @@ -160,7 +157,7 @@ GURL url = http_url; if (name == kSecure || name == kEvSecure || name == kMixedContentForm || name == kMixedContent || name == kAllowAllPermissions || - name == kBlockAllPermissions || name == kMalwareAndBadCert) { + name == kBlockAllPermissions) { url = https_url; } if (name == kInternal) { @@ -206,24 +203,19 @@ expected_identifiers_.push_back( PageInfoBubbleView::VIEW_ID_PAGE_INFO_LABEL_EV_CERTIFICATE_DETAILS); } else if (name == kMalware) { - identity.safe_browsing_status = PageInfo::SAFE_BROWSING_STATUS_MALWARE; + identity.identity_status = PageInfo::SITE_IDENTITY_STATUS_MALWARE; } else if (name == kDeceptive) { - identity.safe_browsing_status = - PageInfo::SAFE_BROWSING_STATUS_SOCIAL_ENGINEERING; + identity.identity_status = + PageInfo::SITE_IDENTITY_STATUS_SOCIAL_ENGINEERING; } else if (name == kUnwantedSoftware) { - identity.safe_browsing_status = - PageInfo::SAFE_BROWSING_STATUS_UNWANTED_SOFTWARE; + identity.identity_status = + PageInfo::SITE_IDENTITY_STATUS_UNWANTED_SOFTWARE; } else if (name == kSignInPasswordReuse) { - identity.safe_browsing_status = - PageInfo::SAFE_BROWSING_STATUS_SIGN_IN_PASSWORD_REUSE; + identity.identity_status = + PageInfo::SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE; } else if (name == kEnterprisePasswordReuse) { - identity.safe_browsing_status = - PageInfo::SAFE_BROWSING_STATUS_ENTERPRISE_PASSWORD_REUSE; - } else if (name == kMalwareAndBadCert) { - identity.identity_status = PageInfo::SITE_IDENTITY_STATUS_ERROR; - identity.certificate = net::ImportCertFromFile( - net::GetTestCertsDirectory(), kExpiredCertificateFile); - identity.safe_browsing_status = PageInfo::SAFE_BROWSING_STATUS_MALWARE; + identity.identity_status = + PageInfo::SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE; } else if (name == kMixedContentForm) { identity.identity_status = PageInfo::SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT; @@ -348,15 +340,6 @@ ->SetIdentityInfo(identity_info); } - base::string16 GetCertificateButtonTitle() const { - // Only PageInfoBubbleViewBrowserTest can access certificate_button_ in - // PageInfoBubbleView, or title() in HoverButton. - PageInfoBubbleView* page_info_bubble_view = - static_cast<PageInfoBubbleView*>( - PageInfoBubbleView::GetPageInfoBubble()); - return page_info_bubble_view->certificate_button_->title()->text(); - } - private: std::vector<PageInfoBubbleView::PageInfoBubbleViewID> expected_identifiers_; @@ -638,13 +621,6 @@ ShowAndVerifyUi(); } -// Shows the Page Info bubble for a site flagged for malware that also has a bad -// certificate. -IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, - InvokeUi_MalwareAndBadCert) { - ShowAndVerifyUi(); -} - // Shows the Page Info bubble for an admin-provided cert when the page is // secure, but has a form that submits to an insecure url. IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, @@ -738,41 +714,6 @@ l10n_util::GetStringUTF16(IDS_PAGE_INFO_MIXED_CONTENT_SUMMARY)); } -// Ensure a page can both have an invalid certificate *and* be blocked by Safe -// Browsing. Regression test for bug 869925. -IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, BlockedAndInvalidCert) { - net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); - https_server.AddDefaultHandlers( - base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); - ASSERT_TRUE(https_server.Start()); - - ui_test_utils::NavigateToURL(browser(), https_server.GetURL("/simple.html")); - - // Setup the bogus identity with an expired cert and SB flagging. - PageInfoUI::IdentityInfo identity; - identity.identity_status = PageInfo::SITE_IDENTITY_STATUS_ERROR; - identity.certificate = net::ImportCertFromFile(net::GetTestCertsDirectory(), - kExpiredCertificateFile); - identity.safe_browsing_status = PageInfo::SAFE_BROWSING_STATUS_MALWARE; - OpenPageInfoBubble(browser()); - - SetPageInfoBubbleIdentityInfo(identity); - - views::BubbleDialogDelegateView* page_info = - PageInfoBubbleView::GetPageInfoBubble(); - - // Verify bubble complains of malware... - EXPECT_EQ(page_info->GetWindowTitle(), - l10n_util::GetStringUTF16(IDS_PAGE_INFO_MALWARE_SUMMARY)); - - // ...and has a "Certificate (Invalid)" button. - const base::string16 invalid_parens = l10n_util::GetStringUTF16( - IDS_PAGE_INFO_CERTIFICATE_INVALID_PARENTHESIZED); - EXPECT_EQ(GetCertificateButtonTitle(), - l10n_util::GetStringFUTF16(IDS_PAGE_INFO_CERTIFICATE_BUTTON_TEXT, - invalid_parens)); -} - namespace { // Tracks focus of an arbitrary UI element.
diff --git a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc index 765ce5d..c6c885c 100644 --- a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc +++ b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc
@@ -45,8 +45,8 @@ views::ButtonListener* button_listener, network::mojom::URLLoaderFactory* loader_factory) { auto list_view = std::make_unique<views::View>(); - list_view->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + list_view->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); int item_height = 0; for (const auto& form : forms) { std::pair<base::string16, base::string16> titles =
diff --git a/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc b/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc index d0bd4a3..0c5d4878 100644 --- a/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc +++ b/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc
@@ -158,7 +158,7 @@ // Add 1px distance between views for the separator. views::BoxLayout* box_layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), 1)); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), 1)); box_layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch);
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc index 4ba49d0b..0c54535 100644 --- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc
@@ -192,7 +192,7 @@ // the first input field. constexpr int kRowBottomPadding = 6; auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(kRowBottomPadding, kPaymentRequestRowHorizontalInsets), kRowVerticalSpacing); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); @@ -209,7 +209,8 @@ constexpr int kPaddingBetweenCardIcons = 8; std::unique_ptr<views::View> icons_row = std::make_unique<views::View>(); icons_row->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), kPaddingBetweenCardIcons)); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + kPaddingBetweenCardIcons)); std::string selected_network = credit_card_to_edit_ ? autofill::data_util::GetPaymentRequestData( @@ -246,7 +247,7 @@ if (IsEditingServerCard()) { std::unique_ptr<views::View> data_source = std::make_unique<views::View>(); data_source->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), kPaddingBetweenCardIcons)); // "From Google Payments".
diff --git a/chrome/browser/ui/views/payments/editor_view_controller.cc b/chrome/browser/ui/views/payments/editor_view_controller.cc index 6789c03..b2aa7ee 100644 --- a/chrome/browser/ui/views/payments/editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/editor_view_controller.cc
@@ -49,8 +49,8 @@ autofill::ServerFieldType type) { std::unique_ptr<views::View> view = std::make_unique<views::View>(); - std::unique_ptr<views::BoxLayout> layout = - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + std::unique_ptr<views::BoxLayout> layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch); @@ -143,7 +143,8 @@ } void EditorViewController::FillContentView(views::View* content_view) { - auto layout = std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + auto layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch);
diff --git a/chrome/browser/ui/views/payments/error_message_view_controller.cc b/chrome/browser/ui/views/payments/error_message_view_controller.cc index ada3e2ea..fe15abd 100644 --- a/chrome/browser/ui/views/payments/error_message_view_controller.cc +++ b/chrome/browser/ui/views/payments/error_message_view_controller.cc
@@ -49,7 +49,7 @@ void ErrorMessageViewController::FillContentView(views::View* content_view) { auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(0, kPaymentRequestRowHorizontalInsets), 0); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); layout->set_cross_axis_alignment(
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller.cc b/chrome/browser/ui/views/payments/order_summary_view_controller.cc index 644edb5..b2caeeaf 100644 --- a/chrome/browser/ui/views/payments/order_summary_view_controller.cc +++ b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
@@ -160,7 +160,8 @@ } void OrderSummaryViewController::FillContentView(views::View* content_view) { - auto layout = std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + auto layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch);
diff --git a/chrome/browser/ui/views/payments/payment_method_view_controller.cc b/chrome/browser/ui/views/payments/payment_method_view_controller.cc index 9b4029e..3f96bd02 100644 --- a/chrome/browser/ui/views/payments/payment_method_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_method_view_controller.cc
@@ -115,7 +115,7 @@ card_info_container->set_can_process_events_within_subtree(false); auto box_layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(kPaymentRequestRowVerticalInsets, 0)); box_layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart); @@ -209,7 +209,8 @@ } void PaymentMethodViewController::FillContentView(views::View* content_view) { - auto layout = std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + auto layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch);
diff --git a/chrome/browser/ui/views/payments/payment_request_item_list.cc b/chrome/browser/ui/views/payments/payment_request_item_list.cc index a3a5fcc..1e326a1 100644 --- a/chrome/browser/ui/views/payments/payment_request_item_list.cc +++ b/chrome/browser/ui/views/payments/payment_request_item_list.cc
@@ -206,7 +206,7 @@ std::unique_ptr<views::View> content_view = std::make_unique<views::View>(); content_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(kPaymentRequestRowVerticalInsets, 0), 0)); for (auto& item : items_)
diff --git a/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc b/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc index 11614cbb..59969ec 100644 --- a/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc +++ b/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc
@@ -451,9 +451,9 @@ std::make_unique<views::View>(); trailing_buttons_container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal, - gfx::Insets(), - kPaymentRequestButtonSpacing)); + std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + kPaymentRequestButtonSpacing)); #if defined(OS_MACOSX) AddSecondaryButton(trailing_buttons_container.get());
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc index 5edfc7c6..b8a9393 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.cc +++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -69,7 +69,7 @@ DCHECK(accessible_content); std::unique_ptr<views::View> container = std::make_unique<views::View>(); std::unique_ptr<views::BoxLayout> layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), 0); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), 0); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart); container->SetLayoutManager(std::move(layout)); @@ -273,7 +273,7 @@ std::unique_ptr<views::View> content_view = std::make_unique<views::View>(); auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), 0); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), 0); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart); @@ -388,8 +388,8 @@ DCHECK(accessible_content); std::unique_ptr<views::View> container = std::make_unique<views::View>(); - auto layout = std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical, - gfx::Insets(), 0); + auto layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical, gfx::Insets(), 0); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart); container->SetLayoutManager(std::move(layout)); @@ -428,7 +428,7 @@ // 8 pixels between the warning icon view (if present) and the text. constexpr int kRowHorizontalSpacing = 8; auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(0, kPaymentRequestRowHorizontalInsets), kRowHorizontalSpacing); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart);
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc index ea905e9..f4d6407 100644 --- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -936,7 +936,7 @@ std::unique_ptr<views::View> PaymentSheetViewController::CreateDataSourceRow() { std::unique_ptr<views::View> content_view = std::make_unique<views::View>(); auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(0, kPaymentRequestRowHorizontalInsets)); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); layout->set_cross_axis_alignment(
diff --git a/chrome/browser/ui/views/payments/profile_list_view_controller.cc b/chrome/browser/ui/views/payments/profile_list_view_controller.cc index 9549239..3b59702d 100644 --- a/chrome/browser/ui/views/payments/profile_list_view_controller.cc +++ b/chrome/browser/ui/views/payments/profile_list_view_controller.cc
@@ -359,7 +359,8 @@ } void ProfileListViewController::FillContentView(views::View* content_view) { - auto layout = std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical); + auto layout = std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical); layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch);
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc index 489db17..011f46c2 100644 --- a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc +++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
@@ -124,7 +124,7 @@ ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); for (size_t index = 0; index < requests.size(); index++) { @@ -132,7 +132,7 @@ int indent = provider->GetDistanceMetric(DISTANCE_SUBSECTION_HORIZONTAL_INDENT); label_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(0, indent), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(0, indent), provider->GetDistanceMetric(views::DISTANCE_RELATED_LABEL_HORIZONTAL))); views::ImageView* icon = new views::ImageView(); const gfx::VectorIcon& vector_id = requests[index]->GetIconId();
diff --git a/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.cc b/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.cc index 9193743a..793d4f2 100644 --- a/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.cc +++ b/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.cc
@@ -92,17 +92,17 @@ views::BoxLayout* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, kDialogInsets)); + views::BoxLayout::Orientation::kVertical, kDialogInsets)); views::View* upper_container_view = new views::View(); upper_container_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets())); + views::BoxLayout::Orientation::kVertical, gfx::Insets())); AddChildView(upper_container_view); views::View* lower_container_view = new views::View(); views::BoxLayout* lower_container_layout = lower_container_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, kLowerContainerInsets)); + views::BoxLayout::Orientation::kVertical, kLowerContainerInsets)); AddChildView(lower_container_view); views::ImageView* logo_image = new views::ImageView(); @@ -124,7 +124,7 @@ views::BoxLayout* message_container_layout = message_container_view->SetLayoutManager( std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(kMessageHeight - kMessageFontSize, 0, 0, 0))); upper_container_view->AddChildView(message_container_view);
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc index c69cb2c..4d9dc614 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -276,7 +276,8 @@ // Add margins. std::unique_ptr<views::View> margined_view = std::make_unique<views::View>(); margined_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(0, kMenuEdgeMargin))); + views::BoxLayout::Orientation::kVertical, + gfx::Insets(0, kMenuEdgeMargin))); margined_view->AddChildView(std::move(button)); AddMenuItemInternal(std::move(margined_view), MenuItems::kStyledButton); @@ -297,7 +298,7 @@ // Add margins. std::unique_ptr<views::View> margined_view = std::make_unique<views::View>(); margined_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(GetMarginSize(kSmall), kMenuEdgeMargin))); margined_view->AddChildView(std::move(button)); @@ -318,7 +319,8 @@ // Add margins. std::unique_ptr<views::View> margined_view = std::make_unique<views::View>(); margined_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(0, kMenuEdgeMargin))); + views::BoxLayout::Orientation::kVertical, + gfx::Insets(0, kMenuEdgeMargin))); margined_view->AddChildView(std::move(label)); AddMenuItemInternal(std::move(margined_view), MenuItems::kLabel); @@ -329,7 +331,8 @@ // Add margins. std::unique_ptr<views::View> margined_view = std::make_unique<views::View>(); margined_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(0, kMenuEdgeMargin))); + views::BoxLayout::Orientation::kVertical, + gfx::Insets(0, kMenuEdgeMargin))); margined_view->AddChildView(std::move(view)); AddMenuItemInternal(std::move(margined_view), MenuItems::kGeneral); } @@ -340,7 +343,7 @@ // Create a view to keep menu contents. auto contents_view = std::make_unique<views::View>(); contents_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets())); + views::BoxLayout::Orientation::kVertical, gfx::Insets())); for (MenuItems& group : menu_item_groups_) { if (group.items.empty()) { @@ -378,7 +381,7 @@ } sub_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets(GetMarginSize(top_margin), 0, GetMarginSize(bottom_margin), 0), GetMarginSize(child_spacing)));
diff --git a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc index d5d5569..0d4e2304 100644 --- a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc +++ b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
@@ -139,7 +139,8 @@ set_owned_by_client(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), kHorizontalMargin)); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + kHorizontalMargin)); auto gripper = std::make_unique<views::ImageView>(); gripper->SetImage(ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
diff --git a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc index d0fd7a9..f9bb3ca 100644 --- a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc +++ b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc
@@ -133,8 +133,8 @@ const std::map<std::string, TargetDeviceInfo> devices) { device_buttons_.clear(); auto device_list_view = std::make_unique<views::View>(); - device_list_view->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + device_list_view->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); int tag = 0; for (const auto& device : devices) { auto device_button = std::make_unique<SendTabToSelfBubbleDeviceButton>(
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc index 54429a7..472b7561 100644 --- a/chrome/browser/ui/views/session_crashed_bubble_view.cc +++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -210,7 +210,7 @@ void SessionCrashedBubbleView::Init() { ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); // Description text label.
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector.cc b/chrome/browser/ui/views/ssl_client_certificate_selector.cc index 8c0fbfb..7f7ae00 100644 --- a/chrome/browser/ui/views/ssl_client_certificate_selector.cc +++ b/chrome/browser/ui/views/ssl_client_certificate_selector.cc
@@ -88,7 +88,8 @@ auth_observer_impl_( std::make_unique<SSLClientAuthObserverImpl>(web_contents, cert_request_info, - std::move(delegate))) { + std::move(delegate))), + weak_factory_(this) { chrome::RecordDialogCreation( chrome::DialogIdentifier::SSL_CLIENT_CERTIFICATE_SELECTOR); } @@ -133,9 +134,21 @@ std::move(identity)); } +void SSLClientCertificateSelector::OnCancel() { + // Close the dialog if it is not currently being displayed + if (!GetWidget()->IsVisible()) + CloseDialog(); +} + +base::OnceClosure SSLClientCertificateSelector::GetCancellationCallback() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + return base::BindOnce(&SSLClientCertificateSelector::OnCancel, + weak_factory_.GetWeakPtr()); +} + namespace chrome { -void ShowSSLClientCertificateSelector( +base::OnceClosure ShowSSLClientCertificateSelector( content::WebContents* contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs, @@ -147,13 +160,14 @@ // TODO(davidben): Move this hook to the WebContentsDelegate and only try to // show a dialog in Browser's implementation. https://crbug.com/456255 if (!SSLClientCertificateSelector::CanShow(contents)) - return; + return base::OnceClosure(); SSLClientCertificateSelector* selector = new SSLClientCertificateSelector( contents, cert_request_info, std::move(client_certs), std::move(delegate)); selector->Init(); selector->Show(); + return selector->GetCancellationCallback(); } } // namespace chrome
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector.h b/chrome/browser/ui/views/ssl_client_certificate_selector.h index e1c3c46..0dc5191 100644 --- a/chrome/browser/ui/views/ssl_client_certificate_selector.h +++ b/chrome/browser/ui/views/ssl_client_certificate_selector.h
@@ -23,6 +23,9 @@ class SSLClientCertificateSelector : public chrome::CertificateSelector { public: + // Writes a callback to the output parameter |cancellation_callback|. The + // callback expects to be invoked on the UI thread and will invoke this + // instance's OnCancel. SSLClientCertificateSelector( content::WebContents* web_contents, const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info, @@ -38,11 +41,19 @@ void AcceptCertificate( std::unique_ptr<net::ClientCertIdentity> identity) override; + void OnCancel(); + + // Returns a UI-thread callback that will cancel this CertificateSelector. The + // callback may be null. The callback is not required to be called. + base::OnceClosure GetCancellationCallback(); + private: class SSLClientAuthObserverImpl; std::unique_ptr<SSLClientAuthObserverImpl> auth_observer_impl_; + base::WeakPtrFactory<SSLClientCertificateSelector> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(SSLClientCertificateSelector); };
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector_mac.mm b/chrome/browser/ui/views/ssl_client_certificate_selector_mac.mm index 88179a7a..81080ad 100644 --- a/chrome/browser/ui/views/ssl_client_certificate_selector_mac.mm +++ b/chrome/browser/ui/views/ssl_client_certificate_selector_mac.mm
@@ -16,6 +16,7 @@ #include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_nsobject.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ssl/ssl_client_auth_observer.h" @@ -330,7 +331,8 @@ : certificate_selector_([[SSLClientCertificateSelectorMac alloc] initWithBrowserContext:contents->GetBrowserContext() certRequestInfo:cert_request_info - delegate:std::move(delegate)]) { + delegate:std::move(delegate)]), + weak_factory_(this) { views::Widget* overlay_window = constrained_window::ShowWebModalDialogWithOverlayViews(this, contents); [certificate_selector_ setOverlayWindow:overlay_window]; @@ -362,9 +364,20 @@ [caller release]; } + base::OnceClosure GetCancellationCallback() { + return base::BindOnce(&SSLClientCertificateSelectorDelegate::CloseSelector, + weak_factory_.GetWeakPtr()); + } + private: + void CloseSelector() { + [certificate_selector_ closeSelectorSheetWithCode:NSModalResponseStop]; + } + base::scoped_nsobject<SSLClientCertificateSelectorMac> certificate_selector_; + base::WeakPtrFactory<SSLClientCertificateSelectorDelegate> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(SSLClientCertificateSelectorDelegate); }; @@ -372,7 +385,7 @@ namespace chrome { -void ShowSSLClientCertificateSelector( +base::OnceClosure ShowSSLClientCertificateSelector( content::WebContents* contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs, @@ -384,11 +397,13 @@ // TODO(davidben): Move this hook to the WebContentsDelegate and only try to // show a dialog in Browser's implementation. https://crbug.com/456255 if (!CertificateSelector::CanShow(contents)) - return; + return base::OnceClosure(); - new SSLClientCertificateSelectorDelegate(contents, cert_request_info, - std::move(client_certs), - std::move(delegate)); + auto* selector_delegate = new SSLClientCertificateSelectorDelegate( + contents, cert_request_info, std::move(client_certs), + std::move(delegate)); + + return selector_delegate->GetCancellationCallback(); } OkAndCancelableForTesting* ShowSSLClientCertificateSelectorMacForTesting(
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector_mac_browsertest.mm b/chrome/browser/ui/views/ssl_client_certificate_selector_mac_browsertest.mm index 2f50ceda..8dc4ea5 100644 --- a/chrome/browser/ui/views/ssl_client_certificate_selector_mac_browsertest.mm +++ b/chrome/browser/ui/views/ssl_client_certificate_selector_mac_browsertest.mm
@@ -139,10 +139,11 @@ EXPECT_FALSE(web_contents_modal_dialog_manager->IsDialogActive()); TestClientCertificateDelegateResults results; - chrome::ShowSSLClientCertificateSelector( - web_contents, auth_requestor_->cert_request_info_.get(), - GetTestCertificateList(), - std::make_unique<TestClientCertificateDelegate>(&results)); + base::OnceClosure cancellation_callback = + chrome::ShowSSLClientCertificateSelector( + web_contents, auth_requestor_->cert_request_info_.get(), + GetTestCertificateList(), + std::make_unique<TestClientCertificateDelegate>(&results)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(web_contents_modal_dialog_manager->IsDialogActive()); @@ -159,6 +160,40 @@ EXPECT_FALSE(results.continue_with_certificate_called); } +IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMacTest, + CancellationCallback) { + base::HistogramTester histograms; + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + WebContentsModalDialogManager* web_contents_modal_dialog_manager = + WebContentsModalDialogManager::FromWebContents(web_contents); + EXPECT_FALSE(web_contents_modal_dialog_manager->IsDialogActive()); + + TestClientCertificateDelegateResults results; + base::OnceClosure cancellation_callback = + chrome::ShowSSLClientCertificateSelector( + web_contents, auth_requestor_->cert_request_info_.get(), + GetTestCertificateList(), + std::make_unique<TestClientCertificateDelegate>(&results)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(web_contents_modal_dialog_manager->IsDialogActive()); + + std::move(cancellation_callback).Run(); + + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(web_contents_modal_dialog_manager->IsDialogActive()); + + // The user did not close the tab, so there should be zero samples reported + // for ClientCertSelectionResult::kUserCloseTab. + + // The TestClientCertificateDelegate will not be freed (yet) because no + // SSLClientAuthObserver methods have been invoked. The SSLClientAuthObserver + // owns the ClientCertificateDelegate in a unique_ptr, so it will be freed the + // SSLClientAuthObserver is destroyed. + EXPECT_FALSE(results.destroyed); + EXPECT_FALSE(results.continue_with_certificate_called); +} + IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorMacTest, Cancel) { base::HistogramTester histograms; content::WebContents* web_contents = @@ -243,10 +278,11 @@ NSUInteger num_child_windows = [[window childWindows] count]; TestClientCertificateDelegateResults results; - chrome::ShowSSLClientCertificateSelector( - web_contents, auth_requestor_->cert_request_info_.get(), - GetTestCertificateList(), - std::make_unique<TestClientCertificateDelegate>(&results)); + base::OnceClosure cancellation_callback = + chrome::ShowSSLClientCertificateSelector( + web_contents, auth_requestor_->cert_request_info_.get(), + GetTestCertificateList(), + std::make_unique<TestClientCertificateDelegate>(&results)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(web_contents_modal_dialog_manager->IsDialogActive());
diff --git a/chrome/browser/ui/views/subtle_notification_view.cc b/chrome/browser/ui/views/subtle_notification_view.cc index 2c47995..15b769c0 100644 --- a/chrome/browser/ui/views/subtle_notification_view.cc +++ b/chrome/browser/ui/views/subtle_notification_view.cc
@@ -75,7 +75,8 @@ const base::string16& text) { // The |between_child_spacing| is the horizontal margin of the key name. SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), kKeyNameMarginHorizPx)); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), + kKeyNameMarginHorizPx)); SetText(text); } @@ -124,7 +125,8 @@ views::View* key = new views::View; auto key_name_layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(0, kKeyNamePaddingPx), 0); + views::BoxLayout::Orientation::kHorizontal, + gfx::Insets(0, kKeyNamePaddingPx), 0); key_name_layout->set_minimum_cross_axis_size( label->GetPreferredSize().height() + kKeyNamePaddingPx * 2); key->SetLayoutManager(std::move(key_name_layout)); @@ -150,7 +152,7 @@ AddChildView(instruction_view_); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(outer_padding_vert, outer_padding_horiz), kMiddlePaddingPx)); }
diff --git a/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.cc b/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.cc index c35a259..85e22c8 100644 --- a/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.cc +++ b/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.cc
@@ -37,7 +37,7 @@ const int title_resource_id = accounts_promo_message_resource_id; std::unique_ptr<views::BoxLayout> layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), ChromeLayoutProvider::Get() ->GetDialogInsetsForContentType(views::TEXT, views::TEXT) .bottom());
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index 8d8a019d7..df6035c 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -233,10 +233,10 @@ else base::RecordAction(UserMetricsAction("CloseTab_RecordingIndicator")); - const CloseTabSource source = - (event.type() == ui::ET_MOUSE_RELEASED && - !(event.flags() & ui::EF_FROM_TOUCH)) ? CLOSE_TAB_FROM_MOUSE - : CLOSE_TAB_FROM_TOUCH; + const CloseTabSource source = (event.type() == ui::ET_MOUSE_RELEASED && + !(event.flags() & ui::EF_FROM_TOUCH)) + ? CLOSE_TAB_FROM_MOUSE + : CLOSE_TAB_FROM_TOUCH; DCHECK_EQ(close_button_, sender); controller_->CloseTab(this, source); if (event.type() == ui::ET_GESTURE_TAP) @@ -524,9 +524,28 @@ void Tab::OnMouseMoved(const ui::MouseEvent& event) { tab_style_->SetHoverLocation(event.location()); controller_->OnMouseEventInTab(this, event); +#if defined(OS_LINUX) + MaybeUpdateHoverStatus(event); +#endif } void Tab::OnMouseEntered(const ui::MouseEvent& event) { + MaybeUpdateHoverStatus(event); +} + +void Tab::MaybeUpdateHoverStatus(const ui::MouseEvent& event) { +#if defined(OS_LINUX) + // Move the hit test area for hovering up so that it is not overlapped by tab + // hover cards when they are shown. Also see the adjustment made in + // abHoverCardBubbleView::TabHoverCardBubbleView(); the two adjustments should + // add to a net six pixels. + // TODO(crbug/978134): Once Linux/CrOS widget transparency is solved, remove + // this case. + constexpr int kHoverCardOverlap = 4; + if (event.location().y() >= height() - kHoverCardOverlap) + return; +#endif + mouse_hovered_ = true; tab_style_->ShowHover(TabStyle::ShowHoverStyle::kSubtle); UpdateForegroundColors();
diff --git a/chrome/browser/ui/views/tabs/tab.h b/chrome/browser/ui/views/tabs/tab.h index 6c28cd1a..b1155bc 100644 --- a/chrome/browser/ui/views/tabs/tab.h +++ b/chrome/browser/ui/views/tabs/tab.h
@@ -35,7 +35,7 @@ namespace gfx { class Animation; class LinearAnimation; -} +} // namespace gfx namespace views { class Label; } @@ -219,6 +219,10 @@ // and alert icon. void UpdateForegroundColors(); + // Considers switching to hovered mode or [re-]showing the hover card based on + // the mouse moving over the tab. + void MaybeUpdateHoverStatus(const ui::MouseEvent& event); + // The controller, never nullptr. TabController* const controller_;
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc index 6e5de1dd..a9e6d3f5 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -280,7 +280,13 @@ set_margins(gfx::Insets()); // Inset the tab hover cards anchor rect to bring the card closer to the tab. +#if defined(OS_LINUX) + // TODO(crbug/978134): Once Linux/CrOS widget transparency is solved, remove + // this case. + constexpr gfx::Insets kTabHoverCardAnchorInsets(0, 0); +#else constexpr gfx::Insets kTabHoverCardAnchorInsets(2, 0); +#endif set_anchor_view_insets(kTabHoverCardAnchorInsets); // Set so that when hovering over a tab in a inactive window that window will
diff --git a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc index 741dc25..99c15d26 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc
@@ -92,7 +92,7 @@ if (icon && extra_view) { std::unique_ptr<views::View> parent = std::make_unique<views::View>(); parent->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL))); parent->AddChildView(std::move(icon)); @@ -144,7 +144,7 @@ ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); int width = provider->GetDistanceMetric(
diff --git a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc index a4cca054..d477e18 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc
@@ -40,26 +40,29 @@ bool highlighted) { // TODO(crbug.com/932818): Pass observed button type to container. highlighted_view_ = highlighted ? observed_button : nullptr; - UpdateHighlight(highlighted); + UpdateHighlight(); } void ToolbarIconContainerView::OnStateChanged( views::Button* observed_button, views::Button::ButtonState old_state) { - if (highlighted_view_) - return; - - UpdateHighlight( - observed_button->state() == views::Button::ButtonState::STATE_PRESSED || - observed_button->state() == views::Button::ButtonState::STATE_HOVERED); + UpdateHighlight(); } void ToolbarIconContainerView::OnViewFocused(views::View* observed_view) { - UpdateHighlight(true); + UpdateHighlight(); } void ToolbarIconContainerView::OnViewBlurred(views::View* observed_view) { - UpdateHighlight(false); + UpdateHighlight(); +} + +void ToolbarIconContainerView::OnMouseEntered(const ui::MouseEvent& event) { + UpdateHighlight(); +} + +void ToolbarIconContainerView::OnMouseExited(const ui::MouseEvent& event) { + UpdateHighlight(); } void ToolbarIconContainerView::ChildPreferredSizeChanged(views::View* child) { @@ -77,10 +80,38 @@ return gfx::Insets(); } -void ToolbarIconContainerView::UpdateHighlight(bool highlighted) { +void ToolbarIconContainerView::UpdateHighlight() { if (!uses_highlight_) return; + bool highlighted = false; + + // If this container is mouse hovered and the main view is not mouse hovered + // the container should be highlighted. + if (!main_view_ || !main_view_->IsMouseHovered()) + highlighted = IsMouseHovered(); + + // The container should also be highlighted if a dialog is anchored to. + if (highlighted_view_) + highlighted = true; + + // The container should also highlight if any of the child buttons are + // either pressed or hovered. + for (views::View* child : children()) { + // The main view should not be considered for focus / button state. + if (child == main_view_) + continue; + if (child->HasFocus()) + highlighted = true; + views::Button* button = views::Button::AsButton(child); + if (!button) + continue; + if (button->state() == views::Button::ButtonState::STATE_PRESSED || + button->state() == views::Button::ButtonState::STATE_HOVERED) { + highlighted = true; + } + } + SetBorder(highlighted ? views::CreateRoundedRectBorder( 1,
diff --git a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h index 5895333..8a09423 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h
@@ -40,11 +40,13 @@ friend class ToolbarPageActionIconContainerViewBrowserTest; // views::View: + void OnMouseEntered(const ui::MouseEvent& event) override; + void OnMouseExited(const ui::MouseEvent& event) override; void ChildPreferredSizeChanged(views::View* child) override; void ChildVisibilityChanged(views::View* child) override; gfx::Insets GetInsets() const override; - void UpdateHighlight(bool highlighted); + void UpdateHighlight(); // The main view is nominally always present and is last child in the view // hierarchy.
diff --git a/chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view_browsertest.cc b/chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view_browsertest.cc index 94c2b17..6cf75d4 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view_browsertest.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view_browsertest.cc
@@ -6,6 +6,7 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/views/autofill/payments/save_card_icon_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_page_action_icon_container_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" @@ -50,17 +51,17 @@ InProcessBrowserTest::SetUp(); } - void TestUsesHighlight(ToolbarPageActionIconContainerView* view, + void TestUsesHighlight(ToolbarPageActionIconContainerView* container, bool expect_highlight) { - DCHECK(view); - EXPECT_EQ(view->uses_highlight(), expect_highlight); - EXPECT_EQ(view->border(), nullptr); + DCHECK(container); + EXPECT_EQ(container->uses_highlight(), expect_highlight); + EXPECT_EQ(container->border(), nullptr); - view->UpdateHighlight(true); - EXPECT_EQ(view->border() != nullptr, expect_highlight); + container->save_card_icon_view()->SetHighlighted(true); + EXPECT_EQ(container->border() != nullptr, expect_highlight); - view->UpdateHighlight(false); - EXPECT_EQ(view->border(), nullptr); + container->save_card_icon_view()->SetHighlighted(false); + EXPECT_EQ(container->border(), nullptr); } private:
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc index ef5d787..2df3f76c 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view.cc +++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -216,8 +216,8 @@ } void TranslateBubbleView::Init() { - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); should_always_translate_ = model_->ShouldAlwaysTranslate(); // Create different view based on user selection in
diff --git a/chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.cc b/chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.cc index ded5e56..c031f51de 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.cc
@@ -54,7 +54,8 @@ // is designed to fill the dialog's top half without any border/margins, and // the |lower_half| will already contain the standard dialog borders. SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kVertical, gfx::Insets(), 0 /* between_child_spacing */)); + BoxLayout::Orientation::kVertical, gfx::Insets(), + 0 /* between_child_spacing */)); std::unique_ptr<views::View> upper_half = CreateIllustrationWithOverlays(); std::unique_ptr<views::View> lower_half = CreateContentsBelowIllustration(); @@ -139,7 +140,7 @@ auto contents = std::make_unique<views::View>(); BoxLayout* contents_layout = contents->SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kVertical, gfx::Insets(), + BoxLayout::Orientation::kVertical, gfx::Insets(), views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); @@ -149,7 +150,7 @@ auto label_container = std::make_unique<views::View>(); label_container->SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kVertical, gfx::Insets(), + BoxLayout::Orientation::kVertical, gfx::Insets(), views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL)));
diff --git a/chrome/browser/ui/views/webauthn/ble_device_selection_sheet_view.cc b/chrome/browser/ui/views/webauthn/ble_device_selection_sheet_view.cc index 34d6152..52d0678 100644 --- a/chrome/browser/ui/views/webauthn/ble_device_selection_sheet_view.cc +++ b/chrome/browser/ui/views/webauthn/ble_device_selection_sheet_view.cc
@@ -26,7 +26,7 @@ BleDeviceSelectionSheetView::BuildStepSpecificContent() { auto device_selection_view = std::make_unique<views::View>(); device_selection_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL))); auto device_list_view =
diff --git a/chrome/browser/ui/views/webauthn/ble_pin_entry_view.cc b/chrome/browser/ui/views/webauthn/ble_pin_entry_view.cc index c1a147b..94debb7a 100644 --- a/chrome/browser/ui/views/webauthn/ble_pin_entry_view.cc +++ b/chrome/browser/ui/views/webauthn/ble_pin_entry_view.cc
@@ -29,7 +29,7 @@ BlePinEntryView::BlePinEntryView(Delegate* delegate) : delegate_(delegate) { auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_CONTROL_VERTICAL_TEXT_PADDING)); layout->set_cross_axis_alignment(
diff --git a/chrome/browser/ui/views/webauthn/hover_list_view.cc b/chrome/browser/ui/views/webauthn/hover_list_view.cc index 3bc805be..a086395 100644 --- a/chrome/browser/ui/views/webauthn/hover_list_view.cc +++ b/chrome/browser/ui/views/webauthn/hover_list_view.cc
@@ -166,7 +166,7 @@ auto item_container = std::make_unique<views::View>(); item_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), + views::BoxLayout::Orientation::kVertical, gfx::Insets(), 0 /* betweeen_child_spacing */)); item_container_ = item_container.get();
diff --git a/chrome/browser/ui/webui/bookmarks/bookmarks_browsertest.cc b/chrome/browser/ui/webui/bookmarks/bookmarks_browsertest.cc index 9c03d9fa3..483ef599 100644 --- a/chrome/browser/ui/webui/bookmarks/bookmarks_browsertest.cc +++ b/chrome/browser/ui/webui/bookmarks/bookmarks_browsertest.cc
@@ -65,7 +65,7 @@ node->Set("children", std::make_unique<base::ListValue>()); list.Append(std::move(node)); profile->GetPrefs()->Set(bookmarks::prefs::kManagedBookmarks, list); - ASSERT_EQ(2, managed->managed_node()->child_count()); + ASSERT_EQ(2u, managed->managed_node()->children().size()); } void BookmarksBrowserTest::SetupExtensionAPIEditDisabledTest() {
diff --git a/chrome/browser/ui/webui/cookies_tree_model_util.cc b/chrome/browser/ui/webui/cookies_tree_model_util.cc index 9c94abc4..1e98254 100644 --- a/chrome/browser/ui/webui/cookies_tree_model_util.cc +++ b/chrome/browser/ui/webui/cookies_tree_model_util.cc
@@ -305,15 +305,15 @@ for (const auto& child : parent->children()) { std::string cookie_id_path = id_path + "," + GetTreeNodeId(child.get()) + ","; - for (int k = 0; k < child->child_count(); ++k) { - const CookieTreeNode* details = child->GetChild(k); + for (const auto& details : child->children()) { std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue); if (GetCookieTreeNodeDictionary(*details, include_quota_nodes, dict.get())) { // TODO(dschuyler): This ID path is an artifact from using tree nodes to // hold the cookies. Can this be changed to a dictionary with a key // lookup (and remove use of id_map_)? - dict->SetString("idPath", cookie_id_path + GetTreeNodeId(details)); + dict->SetString("idPath", + cookie_id_path + GetTreeNodeId(details.get())); list->Append(std::move(dict)); } } @@ -361,14 +361,10 @@ const CookieTreeNode* CookiesTreeModelUtil::GetTreeNodeFromTitle( const CookieTreeNode* root, const base::string16& title) { - // TODO(dschuyler): This method reduces an old O(n^2) lookup with an O(n) - // lookup for O(1) space, but it could be further improved to O(1) lookup if - // desired (by trading O(n) space for the time improvement). - int site_count = root->child_count(); - for (int i = 0; i < site_count; ++i) { - const CookieTreeNode* child = root->GetChild(i); - if (title == child->GetTitle()) - return child; - } - return nullptr; + // TODO(dschuyler): This is an O(n) lookup for O(1) space, but it could be + // improved to O(1) lookup if desired (by using O(n) space). + const auto i = std::find_if( + root->children().cbegin(), root->children().cend(), + [&title](const auto& child) { return title == child->GetTitle(); }); + return (i == root->children().cend()) ? nullptr : i->get(); }
diff --git a/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc b/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc index 0e1ed21..1d4468e 100644 --- a/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc +++ b/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
@@ -340,9 +340,8 @@ AllowJavascript(); CookieTreeNode* parent = cookies_tree_model_->GetRoot(); - while (parent->child_count()) { + while (!parent->children().empty()) cookies_tree_model_->DeleteCookieNode(parent->GetChild(0)); - } } void CookiesViewHandler::HandleRemoveItem(const base::ListValue* args) { @@ -353,26 +352,24 @@ AllowJavascript(); CookieTreeNode* parent = cookies_tree_model_->GetRoot(); - int parent_child_count = parent->child_count(); - for (int i = 0; i < parent_child_count; ++i) { - CookieTreeNode* node = parent->GetChild(i); - if (node->GetTitle() == site) { - cookies_tree_model_->DeleteCookieNode(node); - sorted_sites_.clear(); - return; - } + const auto i = std::find_if( + parent->children().cbegin(), parent->children().cend(), + [&site](const auto& node) { return node->GetTitle() == site; }); + if (i != parent->children().cend()) { + cookies_tree_model_->DeleteCookieNode(i->get()); + sorted_sites_.clear(); } } void CookiesViewHandler::SendLocalDataList(const CookieTreeNode* parent) { CHECK(cookies_tree_model_.get()); CHECK(request_.should_send_list); - const int parent_child_count = parent->child_count(); + const size_t parent_child_count = parent->children().size(); if (sorted_sites_.empty()) { // Sort the list by site. sorted_sites_.reserve(parent_child_count); // Optimization, hint size. - for (int i = 0; i < parent_child_count; ++i) { - const base::string16& title = parent->GetChild(i)->GetTitle(); + for (size_t i = 0; i < parent_child_count; ++i) { + const base::string16& title = parent->children()[i]->GetTitle(); sorted_sites_.push_back(LabelAndIndex(title, i)); } std::sort(sorted_sites_.begin(), sorted_sites_.end()); @@ -389,24 +386,22 @@ for (int i = 0; i < list_item_count; ++i) { const CookieTreeNode* site = parent->GetChild(sorted_sites_[i].second); base::string16 description; - for (int k = 0; k < site->child_count(); ++k) { - if (!description.empty()) { + for (const auto& category : site->children()) { + if (!description.empty()) description += base::ASCIIToUTF16(", "); - } - const CookieTreeNode* category = site->GetChild(k); const auto node_type = category->GetDetailedInfo().node_type; - int item_count = category->child_count(); + size_t item_count = category->children().size(); switch (node_type) { case CookieTreeNode::DetailedInfo::TYPE_QUOTA: // TODO(crbug.com/642955): Omit quota values until bug is addressed. continue; case CookieTreeNode::DetailedInfo::TYPE_COOKIE: - DCHECK_EQ(0, item_count); + DCHECK_EQ(0u, item_count); item_count = 1; FALLTHROUGH; case CookieTreeNode::DetailedInfo::TYPE_COOKIES: description += l10n_util::GetPluralStringFUTF16( - IDS_SETTINGS_SITE_SETTINGS_NUM_COOKIES, item_count); + IDS_SETTINGS_SITE_SETTINGS_NUM_COOKIES, int{item_count}); break; default: int ids_value = GetCategoryLabelID(node_type);
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc index 36cbda3d..6318434 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -474,8 +474,7 @@ const CookieTreeNode* root = cookies_tree_model_->GetRoot(); std::string usage_string = ""; std::string cookie_string = ""; - for (int i = 0; i < root->child_count(); ++i) { - const CookieTreeNode* site = root->GetChild(i); + for (const auto& site : root->children()) { std::string title = base::UTF16ToUTF8(site->GetTitle()); if (title != usage_host_) continue; @@ -602,11 +601,9 @@ if (!url.is_valid()) return; AllowJavascript(); - CookieTreeNode* parent = cookies_tree_model_->GetRoot(); - for (int i = 0; i < parent->child_count(); ++i) { - CookieTreeNode* node = parent->GetChild(i); + for (const auto& node : cookies_tree_model_->GetRoot()->children()) { if (origin == node->GetDetailedInfo().origin.GetURL().spec()) { - cookies_tree_model_->DeleteCookieNode(node); + cookies_tree_model_->DeleteCookieNode(node.get()); return; } } @@ -1413,9 +1410,7 @@ std::map<std::string, int64_t>* origin_size_map) { CHECK(cookies_tree_model_.get()); - const CookieTreeNode* root = cookies_tree_model_->GetRoot(); - for (int i = 0; i < root->child_count(); ++i) { - const CookieTreeNode* site = root->GetChild(i); + for (const auto& site : cookies_tree_model_->GetRoot()->children()) { int64_t size = site->InclusiveSize(); if (size == 0) continue; @@ -1429,9 +1424,7 @@ std::map<std::string, int>* origin_cookie_map) { CHECK(cookies_tree_model_.get()); // Get sites that don't have data but have cookies. - const CookieTreeNode* root = cookies_tree_model_->GetRoot(); - for (int i = 0; i < root->child_count(); ++i) { - const CookieTreeNode* site = root->GetChild(i); + for (const auto& site : cookies_tree_model_->GetRoot()->children()) { GURL url = site->GetDetailedInfo().origin.GetURL(); (*origin_cookie_map)[url.host()] = site->NumberOfCookies(); CreateOrAppendSiteGroupEntry(all_sites_map, url, @@ -1450,18 +1443,16 @@ // Find all the nodes that contain the given etld+1. std::vector<CookieTreeNode*> nodes_to_delete; - for (int i = 0; i < parent->child_count(); ++i) { - CookieTreeNode* node = parent->GetChild(i); + for (const auto& node : parent->children()) { std::string cookie_node_etld_plus1 = net::registry_controlled_domains::GetDomainAndRegistry( base::UTF16ToUTF8(node->GetTitle()), net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); if (etld_plus1_string == cookie_node_etld_plus1) - nodes_to_delete.push_back(node); + nodes_to_delete.push_back(node.get()); } - for (auto* node : nodes_to_delete) { + for (auto* node : nodes_to_delete) cookies_tree_model_->DeleteCookieNode(node); - } LogAllSitesAction(AllSitesAction::kClearData); }
diff --git a/chrome/browser/web_applications/test/test_data_retriever.cc b/chrome/browser/web_applications/test/test_data_retriever.cc index b2b088d..c5d893c 100644 --- a/chrome/browser/web_applications/test/test_data_retriever.cc +++ b/chrome/browser/web_applications/test/test_data_retriever.cc
@@ -81,4 +81,17 @@ destruction_callback_ = std::move(callback); } +void TestDataRetriever::BuildDefaultDataToRetrieve(const GURL& url, + const GURL& scope) { + SetRendererWebApplicationInfo(std::make_unique<WebApplicationInfo>()); + + auto manifest = std::make_unique<blink::Manifest>(); + manifest->start_url = url; + manifest->scope = scope; + + SetManifest(std::move(manifest), /*is_installable=*/true); + + SetIcons(IconsMap{}); +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/test/test_data_retriever.h b/chrome/browser/web_applications/test/test_data_retriever.h index db5b67d..149cce1 100644 --- a/chrome/browser/web_applications/test/test_data_retriever.h +++ b/chrome/browser/web_applications/test/test_data_retriever.h
@@ -12,6 +12,7 @@ #include "chrome/browser/web_applications/components/web_app_data_retriever.h" #include "chrome/browser/web_applications/components/web_app_install_utils.h" +class GURL; struct WebApplicationInfo; namespace web_app { @@ -54,6 +55,11 @@ WebApplicationInfo& web_app_info() { return *web_app_info_; } + // Builds minimal data for install to succeed. Data includes: empty renderer + // info, manifest with |url| and |scope|, installability checked as |true|, + // empty icons. + void BuildDefaultDataToRetrieve(const GURL& url, const GURL& scope); + private: std::unique_ptr<WebApplicationInfo> web_app_info_;
diff --git a/chrome/browser/web_applications/web_app_install_manager.cc b/chrome/browser/web_applications/web_app_install_manager.cc index 4cbb74c8..e4be72f 100644 --- a/chrome/browser/web_applications/web_app_install_manager.cc +++ b/chrome/browser/web_applications/web_app_install_manager.cc
@@ -61,8 +61,6 @@ WebappInstallSource install_source, WebAppInstallDialogCallback dialog_callback, OnceInstallCallback callback) { - DCHECK(AreWebAppsUserInstallable(profile())); - auto task = std::make_unique<WebAppInstallTask>( profile(), install_finalizer_, data_retriever_factory_.Run()); task->InstallWebAppFromManifest( @@ -79,8 +77,6 @@ WebappInstallSource install_source, WebAppInstallDialogCallback dialog_callback, OnceInstallCallback callback) { - DCHECK(AreWebAppsUserInstallable(profile())); - auto task = std::make_unique<WebAppInstallTask>( profile(), install_finalizer_, data_retriever_factory_.Run()); task->InstallWebAppFromManifestWithFallback( @@ -96,8 +92,6 @@ bool no_network_install, WebappInstallSource install_source, OnceInstallCallback callback) { - DCHECK(AreWebAppsUserInstallable(profile())); - auto task = std::make_unique<WebAppInstallTask>( profile(), install_finalizer_, data_retriever_factory_.Run()); task->InstallWebAppFromInfo(
diff --git a/chrome/browser/web_applications/web_app_install_task.cc b/chrome/browser/web_applications/web_app_install_task.cc index 82517cb..219baae 100644 --- a/chrome/browser/web_applications/web_app_install_task.cc +++ b/chrome/browser/web_applications/web_app_install_task.cc
@@ -71,6 +71,7 @@ WebappInstallSource install_source, InstallManager::WebAppInstallDialogCallback dialog_callback, InstallManager::OnceInstallCallback install_callback) { + DCHECK(AreWebAppsUserInstallable(profile_)); CheckInstallPreconditions(); Observe(contents); @@ -93,6 +94,7 @@ WebappInstallSource install_source, InstallManager::WebAppInstallDialogCallback dialog_callback, InstallManager::OnceInstallCallback install_callback) { + DCHECK(AreWebAppsUserInstallable(profile_)); CheckInstallPreconditions(); Observe(contents); @@ -111,6 +113,7 @@ bool no_network_install, WebappInstallSource install_source, InstallManager::OnceInstallCallback callback) { + DCHECK(AreWebAppsUserInstallable(profile_)); CheckInstallPreconditions(); std::vector<BitmapAndSource> square_icons; @@ -191,7 +194,6 @@ void WebAppInstallTask::CheckInstallPreconditions() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(AreWebAppsUserInstallable(profile_)); // Concurrent calls are not allowed. DCHECK(!web_contents());
diff --git a/chrome/browser/web_applications/web_app_install_task_unittest.cc b/chrome/browser/web_applications/web_app_install_task_unittest.cc index f157be5..1fa2273 100644 --- a/chrome/browser/web_applications/web_app_install_task_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_task_unittest.cc
@@ -31,7 +31,9 @@ #include "chrome/browser/web_applications/web_app_icon_manager.h" #include "chrome/browser/web_applications/web_app_install_finalizer.h" #include "chrome/browser/web_applications/web_app_registrar.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 "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/manifest/manifest.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -192,21 +194,8 @@ } void CreateDefaultDataToRetrieve(const GURL& url, const GURL& scope) { - data_retriever_->SetRendererWebApplicationInfo( - std::make_unique<WebApplicationInfo>()); - - auto manifest = std::make_unique<blink::Manifest>(); - manifest->start_url = url; - manifest->scope = scope; - blink::Manifest::RelatedApplication related_app; - related_app.platform = - base::NullableString16(base::ASCIIToUTF16("chromeos_play")); - related_app.id = base::NullableString16(base::ASCIIToUTF16("com.app.id")); - manifest->related_applications.push_back(std::move(related_app)); - - data_retriever_->SetManifest(std::move(manifest), /*is_installable=*/true); - - data_retriever_->SetIcons(IconsMap{}); + DCHECK(data_retriever_); + data_retriever_->BuildDefaultDataToRetrieve(url, scope); } void CreateDefaultDataToRetrieve(const GURL& url) { @@ -219,7 +208,7 @@ } void SetIconsMapToRetrieve(IconsMap icons_map) { - CHECK(data_retriever_); + DCHECK(data_retriever_); data_retriever_->SetIcons(std::move(icons_map)); } @@ -995,8 +984,21 @@ const GURL scope("https://example.com/scope"); const base::Optional<SkColor> theme_color = 0xAABBCCDD; - CreateDefaultDataToRetrieve(url, scope); CreateRendererAppInfo(url, name, description, /*scope*/ GURL{}, theme_color); + { + auto manifest = std::make_unique<blink::Manifest>(); + manifest->start_url = url; + manifest->scope = scope; + blink::Manifest::RelatedApplication related_app; + related_app.platform = + base::NullableString16(base::ASCIIToUTF16("chromeos_play")); + related_app.id = base::NullableString16(base::ASCIIToUTF16("com.app.id")); + manifest->related_applications.push_back(std::move(related_app)); + + data_retriever_->SetManifest(std::move(manifest), /*is_installable=*/true); + + data_retriever_->SetIcons(IconsMap{}); + } base::RunLoop run_loop; install_task_->InstallWebAppFromManifestWithFallback( @@ -1013,4 +1015,33 @@ } #endif +// Default apps should be installable for guest profiles. +TEST_F(WebAppInstallTaskTest, InstallWebAppWithOptions_GuestProfile) { + SetInstallFinalizerForTesting(); + + TestingProfileManager profile_manager(TestingBrowserProcess::GetGlobal()); + ASSERT_TRUE(profile_manager.SetUp()); + Profile* guest_profile = profile_manager.CreateGuestProfile(); + + auto data_retriever = std::make_unique<TestDataRetriever>(); + data_retriever->BuildDefaultDataToRetrieve(GURL("https://example.com/path"), + /*scope=*/GURL{}); + + auto install_task = std::make_unique<WebAppInstallTask>( + guest_profile, install_finalizer_.get(), std::move(data_retriever)); + + InstallOptions install_options; + install_options.install_source = InstallSource::kExternalDefault; + + base::RunLoop run_loop; + install_task->InstallWebAppWithOptions( + web_contents(), install_options, + base::BindLambdaForTesting( + [&](const AppId& app_id, InstallResultCode code) { + EXPECT_EQ(InstallResultCode::kSuccess, code); + run_loop.Quit(); + })); + run_loop.Run(); +} + } // namespace web_app
diff --git a/chrome/child/BUILD.gn b/chrome/child/BUILD.gn index a6f9c65..f00de1b 100644 --- a/chrome/child/BUILD.gn +++ b/chrome/child/BUILD.gn
@@ -14,7 +14,6 @@ if (is_win) { sources += [ - "delay_load_failure_hook.cc", "v8_crashpad_support_win.cc", "v8_crashpad_support_win.h", ]
diff --git a/chrome/child/delay_load_failure_hook.cc b/chrome/child/delay_load_failure_hook.cc deleted file mode 100644 index 319ed8d..0000000 --- a/chrome/child/delay_load_failure_hook.cc +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// windows.h needs to be included before delayimp.h. -#include <windows.h> - -#include <delayimp.h> - -#include "base/debug/alias.h" -#include "base/logging.h" -#include "base/stl_util.h" -#include "base/strings/string_util.h" - -namespace { - -// Delay load failure hook that generates a crash report. By default a failure -// to delay load will trigger an exception handled by the delay load runtime and -// this won't generate a crash report. -extern "C" FARPROC WINAPI DelayLoadFailureHook(unsigned reason, - DelayLoadInfo* dll_info) { - char dll_name[256]; - base::strlcpy(dll_name, dll_info->szDll, base::size(dll_name)); - base::debug::Alias(&dll_name); - - CHECK(false); - return 0; -} - -} // namespace - -// Set the delay load failure hook to the function above. -// -// The |__pfnDliFailureHook2| failure notification hook gets called -// automatically by the delay load runtime in case of failure, see -// https://docs.microsoft.com/en-us/cpp/build/reference/failure-hooks?view=vs-2019 -// for more information about this. -extern "C" const PfnDliHook __pfnDliFailureHook2 = DelayLoadFailureHook;
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index b5088fc0..8745357e 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json
@@ -158,7 +158,7 @@ }, "browserAction": { "dependencies": ["manifest:browser_action"], - "contexts": ["blessed_extension"] + "contexts": ["blessed_extension", "extension_service_worker"] }, // This API is whitelisted on stable and should not be enabled for a wider // audience without resolving security issues raised in API proposal and
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 6eca1ed..a1b18f4 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -125,8 +125,8 @@ const char kChromeUIResetPasswordURL[] = "chrome://reset-password/"; const char kChromeUIRestartHost[] = "restart"; const char kChromeUIRestartURL[] = "chrome://restart/"; -const char kChromeUISafetyPixelbookURL[] = "https://g.co/Pixelbook/safety"; -const char kChromeUISafetyPixelSlateURL[] = "https://g.co/PixelSlate/safety"; +const char kChromeUISafetyPixelbookURL[] = "https://g.co/Pixelbook/legal"; +const char kChromeUISafetyPixelSlateURL[] = "https://g.co/PixelSlate/legal"; const char kChromeUISettingsHost[] = "settings"; const char kChromeUISettingsURL[] = "chrome://settings/"; const char kChromeUISignInInternalsHost[] = "signin-internals";
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 1f1871d..36742f7 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1517,7 +1517,8 @@ void ChromeContentRendererClient:: DidInitializeServiceWorkerContextOnWorkerThread( - v8::Local<v8::Context> context, + blink::WebServiceWorkerContextProxy* context_proxy, + v8::Local<v8::Context> v8_context, int64_t service_worker_version_id, const GURL& service_worker_scope, const GURL& script_url) { @@ -1525,7 +1526,8 @@ ChromeExtensionsRendererClient::GetInstance() ->extension_dispatcher() ->DidInitializeServiceWorkerContextOnWorkerThread( - context, service_worker_version_id, service_worker_scope, script_url); + context_proxy, v8_context, service_worker_version_id, + service_worker_scope, script_url); #endif }
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h index 33245a0..c926cd33 100644 --- a/chrome/renderer/chrome_content_renderer_client.h +++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -50,6 +50,10 @@ #endif class ThreadProfiler; +namespace blink { +class WebServiceWorkerContextProxy; +} + namespace content { class BrowserPluginDelegate; struct WebPluginInfo; @@ -180,7 +184,8 @@ void SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() override; void WillInitializeServiceWorkerContextOnWorkerThread() override; void DidInitializeServiceWorkerContextOnWorkerThread( - v8::Local<v8::Context> context, + blink::WebServiceWorkerContextProxy* context_proxy, + v8::Local<v8::Context> v8_context, int64_t service_worker_version_id, const GURL& service_worker_scope, const GURL& script_url) override;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index c5e1059..c85b3c2 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2257,6 +2257,7 @@ } if (safe_browsing_mode == 1) { sources += [ + "../browser/safe_browsing/ad_redirect_trigger_browsertest.cc", "../browser/safe_browsing/certificate_reporting_service_browsertest.cc", "../browser/safe_browsing/chrome_password_protection_service_browsertest.cc", "../browser/safe_browsing/client_side_detection_host_browsertest.cc", @@ -3225,6 +3226,7 @@ data_deps = [ "//chrome/test/data/media/engagement/preload:generate_preload_list", "//chrome/test/data/media/engagement/preload:test_data", + "//testing/buildbot/filters:unit_tests_filters", ] data = [ @@ -4484,6 +4486,7 @@ "//components/safe_browsing/browser:unittests", "//components/safe_browsing/db:v4_test_util", "//components/safe_browsing/renderer:websocket_sb_handshake_throttle_unittest", + "//components/safe_browsing/triggers:ad_redirect_trigger", ] } else if (safe_browsing_mode == 2) { sources += [ "../browser/safe_browsing/telemetry/android/android_telemetry_service_unittest.cc" ]
diff --git a/chrome/test/data/banners/image-512px-corp.png b/chrome/test/data/banners/image-512px-corp.png new file mode 100644 index 0000000..b36355f55 --- /dev/null +++ b/chrome/test/data/banners/image-512px-corp.png Binary files differ
diff --git a/chrome/test/data/banners/image-512px-corp.png.mock-http-headers b/chrome/test/data/banners/image-512px-corp.png.mock-http-headers new file mode 100644 index 0000000..a433744 --- /dev/null +++ b/chrome/test/data/banners/image-512px-corp.png.mock-http-headers
@@ -0,0 +1,3 @@ +HTTP/1.1 200 OK +Content-Type: image/png +Cross-Origin-Resource-Policy: same-origin
diff --git a/chrome/test/data/extensions/api_test/service_worker/worker_based_background/browser_action/background.js b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/browser_action/background.js new file mode 100644 index 0000000..432914f --- /dev/null +++ b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/browser_action/background.js
@@ -0,0 +1,22 @@ +// 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. + +var initialUserGesture = chrome.test.isProcessingUserGesture(); + +chrome.browserAction.onClicked.addListener(() => { + chrome.test.assertFalse(initialUserGesture); + + // We should be running with a user gesture. + // TODO(lazyboy): isProcessingUserGesture() only performs renderer level + // checks, also call an actual API that requires gesture. + chrome.test.assertTrue(chrome.test.isProcessingUserGesture()); + // Call an API so we can check gesture state in the callback. + chrome.tabs.create({url: chrome.runtime.getURL('page.html')}, () => { + chrome.test.assertNoLastError(); + chrome.test.assertFalse(chrome.test.isProcessingUserGesture()); + chrome.test.notifyPass(); + }); +}); + +chrome.test.sendMessage('ready');
diff --git a/chrome/test/data/extensions/api_test/service_worker/worker_based_background/browser_action/manifest.json b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/browser_action/manifest.json new file mode 100644 index 0000000..b8e191a --- /dev/null +++ b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/browser_action/manifest.json
@@ -0,0 +1,8 @@ +{ + "name": "browserAction + user gesture", + "description": "Demonstrates usage and features of user gesture", + "version": "1.0", + "manifest_version": 2, + "background": {"service_worker": "background.js"}, + "browser_action": {} +}
diff --git a/chrome/test/data/extensions/api_test/service_worker/worker_based_background/browser_action/page.html b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/browser_action/page.html new file mode 100644 index 0000000..c50eddd4 --- /dev/null +++ b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/browser_action/page.html
@@ -0,0 +1 @@ +<!doctype html>
diff --git a/chrome/test/data/extensions/api_test/service_worker/worker_based_background/notification_click/background.js b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/notification_click/background.js new file mode 100644 index 0000000..f51d836 --- /dev/null +++ b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/notification_click/background.js
@@ -0,0 +1,24 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// By default there should not be any user gesture present. +chrome.test.assertFalse(chrome.test.isProcessingUserGesture()); + +// Note: showNotification() requires SW to be activated first. +self.onactivate = function(e) { + self.registration.showNotification('Hello world', + {body: 'Body here'}) + .then((e) => { + chrome.test.notifyPass(); + }).catch((e) => { + chrome.test.notifyFailure('showNotification failed'); + }); +}; + +self.onnotificationclick = function(e) { + chrome.test.log('onnotificationclick'); + // We should be running with a user gesture w.r.t. extension APIs. + chrome.test.assertTrue(chrome.test.isProcessingUserGesture()); + chrome.test.notifyPass(); +};
diff --git a/chrome/test/data/extensions/api_test/service_worker/worker_based_background/notification_click/manifest.json b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/notification_click/manifest.json new file mode 100644 index 0000000..3abdcf0 --- /dev/null +++ b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/notification_click/manifest.json
@@ -0,0 +1,8 @@ +{ + "name": "Extension API in Service Worker notificationclick", + "description": "Demonstrates usage and features of user gesture", + "version": "1.0", + "manifest_version": 2, + "permissions": ["notifications"], + "background": {"service_worker": "background.js"} +}
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index 6f6b701..b246697 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -317,8 +317,6 @@ "extensions/api/tts/tts_extension_api.h", "extensions/api/tts/tts_extension_api_constants.cc", "extensions/api/tts/tts_extension_api_constants.h", - "extensions/cast_display_info_provider.cc", - "extensions/cast_display_info_provider.h", "extensions/cast_extension_host_delegate.cc", "extensions/cast_extension_host_delegate.h", "extensions/cast_extension_system.cc",
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index 8f4efd7d..5e43b70 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -693,7 +693,7 @@ return; } -void CastContentBrowserClient::SelectClientCertificate( +base::OnceClosure CastContentBrowserClient::SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs, @@ -704,7 +704,7 @@ LOG(ERROR) << "Invalid URL string: " << requesting_url.possibly_invalid_spec(); delegate->ContinueWithCertificate(nullptr, nullptr); - return; + return base::OnceClosure(); } // In our case there are no relevant certs in |client_certs|. The cert @@ -730,6 +730,7 @@ base::Bind( &content::ClientCertificateDelegate::ContinueWithCertificate, base::Owned(delegate.release())))); + return base::OnceClosure(); } void CastContentBrowserClient::SelectClientCertificateOnIOThread(
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index f3a6f49..81132ce 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h
@@ -166,7 +166,7 @@ bool expired_previous_decision, const base::Callback<void(content::CertificateRequestResultType)>& callback) override; - void SelectClientCertificate( + base::OnceClosure SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs,
diff --git a/chromecast/browser/extensions/cast_display_info_provider.cc b/chromecast/browser/extensions/cast_display_info_provider.cc deleted file mode 100644 index 45cb624..0000000 --- a/chromecast/browser/extensions/cast_display_info_provider.cc +++ /dev/null
@@ -1,24 +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 "chromecast/browser/extensions/cast_display_info_provider.h" - -#include "base/logging.h" - -namespace extensions { - -CastDisplayInfoProvider::CastDisplayInfoProvider() = default; - -void CastDisplayInfoProvider::UpdateDisplayUnitInfoForPlatform( - const display::Display& display, - extensions::api::system_display::DisplayUnitInfo* unit) { - NOTIMPLEMENTED_LOG_ONCE(); -} - -// static -DisplayInfoProvider* DisplayInfoProvider::Create() { - return new CastDisplayInfoProvider(); -} - -} // namespace extensions
diff --git a/chromecast/browser/extensions/cast_display_info_provider.h b/chromecast/browser/extensions/cast_display_info_provider.h deleted file mode 100644 index f75df40e0..0000000 --- a/chromecast/browser/extensions/cast_display_info_provider.h +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROMECAST_BROWSER_EXTENSIONS_CAST_DISPLAY_INFO_PROVIDER_H_ -#define CHROMECAST_BROWSER_EXTENSIONS_CAST_DISPLAY_INFO_PROVIDER_H_ - -#include "base/macros.h" -#include "extensions/browser/api/system_display/display_info_provider.h" - -namespace extensions { - -class CastDisplayInfoProvider : public DisplayInfoProvider { - public: - CastDisplayInfoProvider(); - - // DisplayInfoProvider implementation. - void UpdateDisplayUnitInfoForPlatform( - const display::Display& display, - extensions::api::system_display::DisplayUnitInfo* unit) override; - - private: - DISALLOW_COPY_AND_ASSIGN(CastDisplayInfoProvider); -}; - -} // namespace extensions - -#endif // CHROMECAST_BROWSER_EXTENSIONS_CAST_DISPLAY_INFO_PROVIDER_H_
diff --git a/chromeos/dbus/debug_daemon_client.cc b/chromeos/dbus/debug_daemon_client.cc index f23457c8..a3c8cc4 100644 --- a/chromeos/dbus/debug_daemon_client.cc +++ b/chromeos/dbus/debug_daemon_client.cc
@@ -219,6 +219,18 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } + void StopPerf(uint64_t session_id, VoidDBusMethodCallback callback) override { + DCHECK(session_id); + dbus::MethodCall method_call(debugd::kDebugdInterface, debugd::kStopPerf); + dbus::MessageWriter writer(&method_call); + writer.AppendUint64(session_id); + + debugdaemon_proxy_->CallMethod( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::BindOnce(&DebugDaemonClientImpl::OnVoidMethod, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + } + void GetScrubbedBigLogs(GetLogsCallback callback) override { // The PipeReaderWrapper is a self-deleting object; we don't have to worry // about ownership or lifetime. We need to create a new one for each Big
diff --git a/chromeos/dbus/debug_daemon_client.h b/chromeos/dbus/debug_daemon_client.h index 2732c35..cae11477 100644 --- a/chromeos/dbus/debug_daemon_client.h +++ b/chromeos/dbus/debug_daemon_client.h
@@ -82,6 +82,13 @@ int file_descriptor, DBusMethodCallback<uint64_t> callback) = 0; + // Stops the perf session identified with |session_id| that was started by a + // prior call to GetPerfOutput(), and let the caller of GetPerfOutput() gather + // profiling data right away. If the profiler session as identified by + // |session_id| has ended, this method will silently succeed. + virtual void StopPerf(uint64_t session_id, + VoidDBusMethodCallback callback) = 0; + // Callback type for GetAllLogs() using GetLogsCallback = base::OnceCallback<void(bool succeeded,
diff --git a/chromeos/dbus/fake_debug_daemon_client.cc b/chromeos/dbus/fake_debug_daemon_client.cc index 8bdd65d..f144e53 100644 --- a/chromeos/dbus/fake_debug_daemon_client.cc +++ b/chromeos/dbus/fake_debug_daemon_client.cc
@@ -102,6 +102,9 @@ int file_descriptor, DBusMethodCallback<uint64_t> error_callback) {} +void FakeDebugDaemonClient::StopPerf(uint64_t session_id, + VoidDBusMethodCallback callback) {} + void FakeDebugDaemonClient::GetScrubbedBigLogs(GetLogsCallback callback) { std::map<std::string, std::string> sample; sample["Sample Scrubbed Big Log"] = "Your email address is xxxxxxxx";
diff --git a/chromeos/dbus/fake_debug_daemon_client.h b/chromeos/dbus/fake_debug_daemon_client.h index c6a5e5e..a920f8a 100644 --- a/chromeos/dbus/fake_debug_daemon_client.h +++ b/chromeos/dbus/fake_debug_daemon_client.h
@@ -51,6 +51,7 @@ const std::vector<std::string>& perf_args, int file_descriptor, DBusMethodCallback<uint64_t> callback) override; + void StopPerf(uint64_t session_id, VoidDBusMethodCallback callback) override; void GetScrubbedBigLogs(GetLogsCallback callback) override; void GetAllLogs(GetLogsCallback callback) override; void GetLog(const std::string& log_name,
diff --git a/components/autofill/core/browser/autofill_field.cc b/components/autofill/core/browser/autofill_field.cc index e60544c..7068d12 100644 --- a/components/autofill/core/browser/autofill_field.cc +++ b/components/autofill/core/browser/autofill_field.cc
@@ -113,6 +113,19 @@ return AutofillType(server_type_); } + // If the explicit type is cc-exp and either the server or heuristics agree on + // a 2 vs 4 digit specialization of cc-exp, use that specialization. + if (html_type_ == HTML_TYPE_CREDIT_CARD_EXP) { + if (server_type_ == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR || + server_type_ == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR) { + return AutofillType(server_type_); + } + if (heuristic_type_ == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR || + heuristic_type_ == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR) { + return AutofillType(heuristic_type_); + } + } + // Use the html type specified by the website unless it is unrecognized and // autofill predicts a credit card type. if (html_type_ != HTML_TYPE_UNSPECIFIED &&
diff --git a/components/bookmarks/browser/bookmark_codec.cc b/components/bookmarks/browser/bookmark_codec.cc index f3accc9..b3357e4 100644 --- a/components/bookmarks/browser/bookmark_codec.cc +++ b/components/bookmarks/browser/bookmark_codec.cc
@@ -150,8 +150,8 @@ UpdateChecksumWithFolderNode(id, title); auto child_values = std::make_unique<base::ListValue>(); - for (int i = 0; i < node->child_count(); ++i) - child_values->Append(EncodeNode(node->GetChild(i))); + for (const auto& child : node->children()) + child_values->Append(EncodeNode(child.get())); value->Set(kChildrenKey, std::move(child_values)); } const BookmarkNode::MetaInfoMap* meta_info_map = node->GetMetaInfoMap(); @@ -478,8 +478,8 @@ void BookmarkCodec::ReassignIDsHelper(BookmarkNode* node) { DCHECK(node); node->set_id(++maximum_id_); - for (int i = 0; i < node->child_count(); ++i) - ReassignIDsHelper(node->GetChild(i)); + for (const auto& child : node->children()) + ReassignIDsHelper(child.get()); } void BookmarkCodec::UpdateChecksum(const std::string& str) {
diff --git a/components/bookmarks/browser/bookmark_codec_unittest.cc b/components/bookmarks/browser/bookmark_codec_unittest.cc index 6ca33211..829af07a97 100644 --- a/components/bookmarks/browser/bookmark_codec_unittest.cc +++ b/components/bookmarks/browser/bookmark_codec_unittest.cc
@@ -68,9 +68,11 @@ } else { EXPECT_TRUE(expected->date_folder_modified() == actual->date_folder_modified()); - ASSERT_EQ(expected->child_count(), actual->child_count()); - for (int i = 0; i < expected->child_count(); ++i) - AssertNodesEqual(expected->GetChild(i), actual->GetChild(i)); + ASSERT_EQ(expected->children().size(), actual->children().size()); + for (size_t i = 0; i < expected->children().size(); ++i) { + AssertNodesEqual(expected->children()[i].get(), + actual->children()[i].get()); + } } } @@ -226,8 +228,8 @@ int64_t node_id = node->id(); EXPECT_TRUE(assigned_ids->find(node_id) == assigned_ids->end()); assigned_ids->insert(node_id); - for (int i = 0; i < node->child_count(); ++i) - CheckIDs(node->GetChild(i), assigned_ids); + for (const auto& child : node->children()) + CheckIDs(child.get(), assigned_ids); } void ExpectIDsUnique(BookmarkModel* model) { @@ -304,8 +306,9 @@ // The test depends on existence of multiple children under bookmark bar, so // make sure that's the case. - int bb_child_count = model_to_encode->bookmark_bar_node()->child_count(); - ASSERT_GT(bb_child_count, 1); + size_t bb_child_count = + model_to_encode->bookmark_bar_node()->children().size(); + ASSERT_GT(bb_child_count, 1u); std::string enc_checksum; std::unique_ptr<base::Value> value = @@ -316,7 +319,7 @@ // Change IDs for all children of bookmark bar to be 1. base::DictionaryValue* child_value; - for (int i = 0; i < bb_child_count; ++i) { + for (size_t i = 0; i < bb_child_count; ++i) { GetBookmarksBarChildValue(value.get(), i, &child_value); std::string id; ASSERT_TRUE(child_value->GetString(BookmarkCodec::kIdKey, &id)); @@ -395,24 +398,24 @@ ExpectIDsUnique(decoded_model.get()); const BookmarkNode* bbn = decoded_model->bookmark_bar_node(); - ASSERT_EQ(1, bbn->child_count()); + ASSERT_EQ(1u, bbn->children().size()); const BookmarkNode* child = bbn->GetChild(0); EXPECT_EQ(BookmarkNode::FOLDER, child->type()); EXPECT_EQ(ASCIIToUTF16("Folder A"), child->GetTitle()); - ASSERT_EQ(1, child->child_count()); + ASSERT_EQ(1u, child->children().size()); child = child->GetChild(0); EXPECT_EQ(BookmarkNode::URL, child->type()); EXPECT_EQ(ASCIIToUTF16("Bookmark Manager"), child->GetTitle()); const BookmarkNode* other = decoded_model->other_node(); - ASSERT_EQ(1, other->child_count()); + ASSERT_EQ(1u, other->children().size()); child = other->GetChild(0); EXPECT_EQ(BookmarkNode::FOLDER, child->type()); EXPECT_EQ(ASCIIToUTF16("Folder B"), child->GetTitle()); - ASSERT_EQ(1, child->child_count()); + ASSERT_EQ(1u, child->children().size()); child = child->GetChild(0); EXPECT_EQ(BookmarkNode::URL, child->type()); @@ -440,7 +443,7 @@ EXPECT_EQ("value1", meta_value); EXPECT_FALSE(model->root_node()->GetMetaInfo("other_key", &meta_value)); const BookmarkNode* bbn = model->bookmark_bar_node(); - ASSERT_EQ(1, bbn->child_count()); + ASSERT_EQ(1u, bbn->children().size()); const BookmarkNode* child = bbn->GetChild(0); EXPECT_TRUE(child->GetMetaInfo("node_info", &meta_value)); EXPECT_EQ("value2", meta_value);
diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmarks/browser/bookmark_model.cc index c6cbe917..f292162 100644 --- a/components/bookmarks/browser/bookmark_model.cc +++ b/components/bookmarks/browser/bookmark_model.cc
@@ -238,17 +238,16 @@ // its immediate children. For removing all non permanent nodes just remove // all children of non-root permanent nodes. { - for (int i = 0; i < root_->child_count(); ++i) { - const BookmarkNode* permanent_node = root_->GetChild(i); - - if (!client_->CanBeEditedByUser(permanent_node)) + for (const auto& permanent_node : root_->children()) { + if (!client_->CanBeEditedByUser(permanent_node.get())) continue; - for (int j = permanent_node->child_count() - 1; j >= 0; --j) { + for (size_t j = permanent_node->children().size(); j > 0; --j) { std::unique_ptr<BookmarkNode> node = url_index_->Remove( - AsMutable(permanent_node->GetChild(j)), &removed_urls); + permanent_node->children()[j - 1].get(), &removed_urls); RemoveNode(node.get()); - removed_node_data_list.push_back({permanent_node, j, std::move(node)}); + removed_node_data_list.push_back( + {permanent_node.get(), j - 1, std::move(node)}); } } } @@ -618,7 +617,7 @@ DCHECK(client_->CanBeEditedByUser(parent)); if (!parent || !parent->is_folder() || is_root_node(parent) || - parent->child_count() <= 1) { + parent->children().size() <= 1) { return; } @@ -646,7 +645,7 @@ DCHECK(client_->CanBeEditedByUser(parent)); // Ensure that all children in |parent| are in |ordered_nodes|. - DCHECK_EQ(static_cast<size_t>(parent->child_count()), ordered_nodes.size()); + DCHECK_EQ(parent->children().size(), ordered_nodes.size()); for (const BookmarkNode* node : ordered_nodes) DCHECK_EQ(parent, node->parent()); @@ -761,8 +760,8 @@ CancelPendingFaviconLoadRequests(node); // Recurse through children. - for (int i = node->child_count() - 1; i >= 0; --i) - RemoveNode(node->GetChild(i)); + for (size_t i = node->children().size(); i > 0; --i) + RemoveNode(node->children()[i - 1].get()); } void BookmarkModel::DoneLoading(std::unique_ptr<BookmarkLoadDetails> details) { @@ -831,8 +830,8 @@ void BookmarkModel::AddNodeToIndexRecursive(BookmarkNode* node) { if (node->is_url()) index_->Add(node); - for (int i = 0; i < node->child_count(); ++i) - AddNodeToIndexRecursive(node->GetChild(i)); + for (const auto& child : node->children()) + AddNodeToIndexRecursive(child.get()); } bool BookmarkModel::IsValidIndex(const BookmarkNode* parent,
diff --git a/components/bookmarks/browser/bookmark_model_unittest.cc b/components/bookmarks/browser/bookmark_model_unittest.cc index 005c2b9..a3e9028 100644 --- a/components/bookmarks/browser/bookmark_model_unittest.cc +++ b/components/bookmarks/browser/bookmark_model_unittest.cc
@@ -202,10 +202,10 @@ // Verifies the contents of the bookmark bar node match the contents of the // TestNode. void VerifyModelMatchesNode(TestNode* expected, const BookmarkNode* actual) { - ASSERT_EQ(expected->child_count(), actual->child_count()); - for (int i = 0; i < expected->child_count(); ++i) { - TestNode* expected_child = expected->GetChild(i); - const BookmarkNode* actual_child = actual->GetChild(i); + ASSERT_EQ(expected->children().size(), actual->children().size()); + for (size_t i = 0; i < expected->children().size(); ++i) { + TestNode* expected_child = expected->children()[i].get(); + const BookmarkNode* actual_child = actual->children()[i].get(); ASSERT_EQ(expected_child->GetTitle(), actual_child->GetTitle()); if (expected_child->value == BookmarkNode::FOLDER) { ASSERT_TRUE(actual_child->type() == BookmarkNode::FOLDER); @@ -475,17 +475,17 @@ TEST_F(BookmarkModelTest, InitialState) { const BookmarkNode* bb_node = model_->bookmark_bar_node(); ASSERT_TRUE(bb_node != nullptr); - EXPECT_EQ(0, bb_node->child_count()); + EXPECT_EQ(0u, bb_node->children().size()); EXPECT_EQ(BookmarkNode::BOOKMARK_BAR, bb_node->type()); const BookmarkNode* other_node = model_->other_node(); ASSERT_TRUE(other_node != nullptr); - EXPECT_EQ(0, other_node->child_count()); + EXPECT_EQ(0u, other_node->children().size()); EXPECT_EQ(BookmarkNode::OTHER_NODE, other_node->type()); const BookmarkNode* mobile_node = model_->mobile_node(); ASSERT_TRUE(mobile_node != nullptr); - EXPECT_EQ(0, mobile_node->child_count()); + EXPECT_EQ(0u, mobile_node->children().size()); EXPECT_EQ(BookmarkNode::MOBILE, mobile_node->type()); EXPECT_TRUE(bb_node->id() != other_node->id()); @@ -502,7 +502,7 @@ AssertObserverCount(1, 0, 0, 0, 0, 0, 0, 0, 0); observer_details_.ExpectEquals(root, nullptr, 0, size_t{-1}); - ASSERT_EQ(1, root->child_count()); + ASSERT_EQ(1u, root->children().size()); ASSERT_EQ(title, new_node->GetTitle()); ASSERT_TRUE(url == new_node->url()); ASSERT_EQ(BookmarkNode::URL, new_node->type()); @@ -523,7 +523,7 @@ AssertObserverCount(1, 0, 0, 0, 0, 0, 0, 0, 0); observer_details_.ExpectEquals(root, nullptr, 0, size_t{-1}); - ASSERT_EQ(1, root->child_count()); + ASSERT_EQ(1u, root->children().size()); ASSERT_EQ(title, new_node->GetTitle()); ASSERT_TRUE(url == new_node->url()); ASSERT_EQ(BookmarkNode::URL, new_node->type()); @@ -543,8 +543,7 @@ const BookmarkNode* new_node = model_->AddURL(root, i, title, url); - int size = i + 1; - EXPECT_EQ(size, root->child_count()); + EXPECT_EQ(i + 1, root->children().size()); EXPECT_EQ(ASCIIToUTF16(url_whitespace_test_cases[i].expected_title), new_node->GetTitle()); EXPECT_EQ(BookmarkNode::URL, new_node->type()); @@ -564,7 +563,7 @@ AssertObserverCount(1, 0, 0, 0, 0, 0, 0, 0, 0); observer_details_.ExpectEquals(root, nullptr, 0, size_t{-1}); - ASSERT_EQ(1, root->child_count()); + ASSERT_EQ(1u, root->children().size()); ASSERT_EQ(title, new_node->GetTitle()); ASSERT_TRUE(url == new_node->url()); ASSERT_EQ(BookmarkNode::URL, new_node->type()); @@ -587,7 +586,7 @@ AssertObserverCount(1, 0, 0, 0, 0, 0, 0, 0, 0); observer_details_.ExpectEquals(root, nullptr, 0, size_t{-1}); - ASSERT_EQ(1, root->child_count()); + ASSERT_EQ(1u, root->children().size()); ASSERT_EQ(title, new_node->GetTitle()); ASSERT_TRUE(url == new_node->url()); ASSERT_EQ(BookmarkNode::URL, new_node->type()); @@ -606,7 +605,7 @@ AssertObserverCount(1, 0, 0, 0, 0, 0, 0, 0, 0); observer_details_.ExpectEquals(root, nullptr, 0, size_t{-1}); - ASSERT_EQ(1, root->child_count()); + ASSERT_EQ(1u, root->children().size()); ASSERT_EQ(title, new_node->GetTitle()); ASSERT_EQ(BookmarkNode::FOLDER, new_node->type()); @@ -629,8 +628,7 @@ const BookmarkNode* new_node = model_->AddFolder(root, i, title); - int size = i + 1; - EXPECT_EQ(size, root->child_count()); + EXPECT_EQ(i + 1, root->children().size()); EXPECT_EQ(ASCIIToUTF16(title_whitespace_test_cases[i].expected_title), new_node->GetTitle()); EXPECT_EQ(BookmarkNode::FOLDER, new_node->type()); @@ -645,7 +643,7 @@ ClearCounts(); model_->Remove(root->GetChild(0)); - ASSERT_EQ(0, root->child_count()); + ASSERT_EQ(0u, root->children().size()); AssertObserverCount(0, 0, 1, 0, 0, 1, 0, 0, 0); observer_details_.ExpectEquals(root, nullptr, 0, size_t{-1}); @@ -668,7 +666,7 @@ // Now remove the folder. model_->Remove(root->GetChild(0)); - ASSERT_EQ(0, root->child_count()); + ASSERT_EQ(0u, root->children().size()); AssertObserverCount(0, 0, 1, 0, 0, 1, 0, 0, 0); observer_details_.ExpectEquals(root, nullptr, 0, size_t{-1}); @@ -694,7 +692,7 @@ AssertObserverCount(3, 0, 0, 0, 0, 0, 0, 0, 0); ClearCounts(); - int permanent_node_count = model_->root_node()->child_count(); + size_t permanent_node_count = model_->root_node()->children().size(); NodeRemovalDetail expected_node_removal_details[] = { NodeRemovalDetail(bookmark_bar_node, 1, url_node), @@ -704,9 +702,9 @@ model_->SetUndoDelegate(this); model_->RemoveAllUserBookmarks(); - EXPECT_EQ(0, bookmark_bar_node->child_count()); + EXPECT_EQ(0u, bookmark_bar_node->children().size()); // No permanent node should be removed. - EXPECT_EQ(permanent_node_count, model_->root_node()->child_count()); + EXPECT_EQ(permanent_node_count, model_->root_node()->children().size()); // No individual BookmarkNodeRemoved events are fired, so removed count // should be 0. AssertObserverCount(0, 0, 0, 0, 0, 0, 0, 0, 1); @@ -791,9 +789,9 @@ AssertObserverCount(0, 1, 0, 0, 0, 0, 0, 0, 0); observer_details_.ExpectEquals(root, folder1, 1, 0); EXPECT_TRUE(folder1 == node->parent()); - EXPECT_EQ(1, root->child_count()); + EXPECT_EQ(1u, root->children().size()); EXPECT_EQ(folder1, root->GetChild(0)); - EXPECT_EQ(1, folder1->child_count()); + EXPECT_EQ(1u, folder1->children().size()); EXPECT_EQ(node, folder1->GetChild(0)); // And remove the folder. @@ -802,7 +800,7 @@ AssertObserverCount(0, 0, 1, 0, 0, 1, 0, 0, 0); observer_details_.ExpectEquals(root, nullptr, 0, size_t{-1}); EXPECT_TRUE(model_->GetMostRecentlyAddedUserNodeForURL(url) == nullptr); - EXPECT_EQ(0, root->child_count()); + EXPECT_EQ(0u, root->children().size()); } TEST_F(BookmarkModelTest, NonMovingMoveCall) { @@ -1082,7 +1080,7 @@ AssertObserverCount(0, 0, 0, 0, 1, 0, 0, 1, 0); // Make sure the order matches is correct (it should be reversed). - ASSERT_EQ(4, parent->child_count()); + ASSERT_EQ(4u, parent->children().size()); EXPECT_EQ("D", base::UTF16ToASCII(parent->GetChild(0)->GetTitle())); EXPECT_EQ("C", base::UTF16ToASCII(parent->GetChild(1)->GetTitle())); EXPECT_EQ("B", base::UTF16ToASCII(parent->GetChild(2)->GetTitle()));
diff --git a/components/bookmarks/browser/bookmark_node_data.cc b/components/bookmarks/browser/bookmark_node_data.cc index f0539f91..159e786 100644 --- a/components/bookmarks/browser/bookmark_node_data.cc +++ b/components/bookmarks/browser/bookmark_node_data.cc
@@ -36,8 +36,8 @@ id_(node->id()) { if (node->GetMetaInfoMap()) meta_info_map = *node->GetMetaInfoMap(); - for (int i = 0; i < node->child_count(); ++i) - children.push_back(Element(node->GetChild(i))); + for (const auto& child : node->children()) + children.push_back(Element(child.get())); } BookmarkNodeData::Element::Element(const Element& other) = default;
diff --git a/components/bookmarks/browser/bookmark_storage.cc b/components/bookmarks/browser/bookmark_storage.cc index d2c08de..4d946ac 100644 --- a/components/bookmarks/browser/bookmark_storage.cc +++ b/components/bookmarks/browser/bookmark_storage.cc
@@ -53,8 +53,8 @@ if (node->url().is_valid()) details->index()->Add(node); } else { - for (int i = 0; i < node->child_count(); ++i) - AddBookmarksToIndex(details, node->GetChild(i)); + for (const auto& child : node->children()) + AddBookmarksToIndex(details, child.get()); } } @@ -70,8 +70,8 @@ if (!node->is_folder()) (*num_nodes_per_url_hash)[std::hash<std::string>()(node->url().spec())]++; - for (int i = 0; i < node->child_count(); ++i) - PopulateNumNodesPerUrlHash(node->GetChild(i), num_nodes_per_url_hash); + for (const auto& child : node->children()) + PopulateNumNodesPerUrlHash(child.get(), num_nodes_per_url_hash); } // Computes the number of bookmarks (excluding folders) with a URL that is used @@ -102,8 +102,8 @@ if (!node->is_root() && node->GetTitle().empty()) ++num_nodes_with_empty_title; - for (int i = 0; i < node->child_count(); ++i) - num_nodes_with_empty_title += GetNumNodesWithEmptyTitle(node->GetChild(i)); + for (const auto& child : node->children()) + num_nodes_with_empty_title += GetNumNodesWithEmptyTitle(child.get()); return num_nodes_with_empty_title; } @@ -227,8 +227,7 @@ std::move(load_extra_callback_).Run(&max_id_); bool has_non_empty_node = false; for (auto& node : extra_nodes) { - if (node->child_count() != 0) - has_non_empty_node = true; + has_non_empty_node |= !node->children().empty(); root_node_->Add(std::move(node)); } return has_non_empty_node;
diff --git a/components/bookmarks/browser/bookmark_utils.cc b/components/bookmarks/browser/bookmark_utils.cc index 69e2d90..0acb356 100644 --- a/components/bookmarks/browser/bookmark_utils.cc +++ b/components/bookmarks/browser/bookmark_utils.cc
@@ -131,8 +131,8 @@ if (node->id() == id) return node; - for (int i = 0, child_count = node->child_count(); i < child_count; ++i) { - const BookmarkNode* result = GetNodeByID(node->GetChild(i), id); + for (const auto& child : node->children()) { + const BookmarkNode* result = GetNodeByID(child.get(), id); if (result) return result; } @@ -214,12 +214,9 @@ bool HasUserCreatedBookmarks(BookmarkModel* model) { const BookmarkNode* root_node = model->root_node(); - for (int i = 0; i < root_node->child_count(); ++i) { - const BookmarkNode* node = root_node->GetChild(i); - if (node->child_count() > 0) - return true; - } - return false; + return std::any_of( + root_node->children().cbegin(), root_node->children().cend(), + [](const auto& node) { return !node->children().empty(); }); } #endif @@ -275,8 +272,7 @@ base::string16* title) { std::unordered_set<base::string16> titles; base::string16 original_title_lower = base::i18n::ToLower(*title); - for (int i = 0; i < parent->child_count(); i++) { - const BookmarkNode* node = parent->GetChild(i); + for (const auto& node : parent->children()) { if (node->is_url() && (url == node->url()) && base::StartsWith(base::i18n::ToLower(node->GetTitle()), original_title_lower, @@ -368,11 +364,10 @@ // only children of the root_node. const BookmarkNode* root_node = model->root_node(); - for (int i = 0; i < root_node->child_count(); ++i) { - const BookmarkNode* node = root_node->GetChild(i); - if (node->IsVisible() && model->client()->CanBeEditedByUser(node) && - !base::Contains(nodes, node)) { - nodes.push_back(node); + for (const auto& node : root_node->children()) { + if (node->IsVisible() && model->client()->CanBeEditedByUser(node.get()) && + !base::Contains(nodes, node.get())) { + nodes.push_back(node.get()); if (nodes.size() == max_count) break;
diff --git a/components/bookmarks/browser/bookmark_utils_unittest.cc b/components/bookmarks/browser/bookmark_utils_unittest.cc index cac122e..eb79df6a 100644 --- a/components/bookmarks/browser/bookmark_utils_unittest.cc +++ b/components/bookmarks/browser/bookmark_utils_unittest.cc
@@ -285,7 +285,7 @@ EXPECT_TRUE(CanPasteFromClipboard(model.get(), new_folder)); PasteFromClipboard(model.get(), new_folder, 0); - ASSERT_EQ(1, new_folder->child_count()); + ASSERT_EQ(1u, new_folder->children().size()); // Url for added node should be same as url_text. EXPECT_EQ(url_text, ASCIIToUTF16(new_folder->GetChild(0)->url().spec())); @@ -340,7 +340,7 @@ EXPECT_TRUE(CanPasteFromClipboard(model.get(), bookmark_bar_node)); PasteFromClipboard(model.get(), bookmark_bar_node, 1); - ASSERT_EQ(2, bookmark_bar_node->child_count()); + ASSERT_EQ(2u, bookmark_bar_node->children().size()); // Url for added node should be same as url_text. EXPECT_EQ(url_text, @@ -368,13 +368,13 @@ // Paste node to a different folder. const BookmarkNode* folder = model->AddFolder(model->bookmark_bar_node(), 0, ASCIIToUTF16("Folder")); - EXPECT_EQ(0, folder->child_count()); + EXPECT_EQ(0u, folder->children().size()); // And make sure we can paste a bookmark from the clipboard. EXPECT_TRUE(CanPasteFromClipboard(model.get(), folder)); PasteFromClipboard(model.get(), folder, 0); - ASSERT_EQ(1, folder->child_count()); + ASSERT_EQ(1u, folder->children().size()); // Verify that the pasted node contains the same meta info. const BookmarkNode* pasted = folder->GetChild(0); @@ -409,7 +409,7 @@ CopyToClipboard(model.get(), nodes, true); // Make sure the nodes were removed. - EXPECT_EQ(0, model->other_node()->child_count()); + EXPECT_EQ(0u, model->other_node()->children().size()); // Make sure observers were notified the set of changes should be grouped. ExpectGroupedChangeCount(1, 1); @@ -505,9 +505,9 @@ std::vector<BookmarkNodeData::Element> elements; BookmarkNodeData::Element node_data(node); elements.push_back(node_data); - EXPECT_EQ(0, folder->child_count()); + EXPECT_EQ(0u, folder->children().size()); CloneBookmarkNode(model.get(), elements, folder, 0, false); - ASSERT_EQ(1, folder->child_count()); + ASSERT_EQ(1u, folder->children().size()); // Verify that the cloned node contains the same meta info. const BookmarkNode* clone = folder->GetChild(0); @@ -536,7 +536,7 @@ // Cloning a bookmark should clear the non cloned key. CloneBookmarkNode(model.get(), elements, parent, 0, true); - ASSERT_EQ(2, parent->child_count()); + ASSERT_EQ(2u, parent->children().size()); std::string value; EXPECT_FALSE(parent->GetChild(0)->GetMetaInfo("foo", &value)); @@ -560,7 +560,7 @@ // Cloning a folder should clear the non cloned key. CloneBookmarkNode(model.get(), elements, parent, 0, true); - ASSERT_EQ(2, parent->child_count()); + ASSERT_EQ(2u, parent->children().size()); std::string value; EXPECT_FALSE(parent->GetChild(0)->GetMetaInfo("foo", &value)); @@ -603,7 +603,7 @@ EXPECT_TRUE(model->bookmark_bar_node()->children().empty()); EXPECT_TRUE(model->other_node()->children().empty()); EXPECT_TRUE(model->mobile_node()->children().empty()); - EXPECT_EQ(1, extra_node->child_count()); + EXPECT_EQ(1u, extra_node->children().size()); } } // namespace
diff --git a/components/bookmarks/browser/url_index.cc b/components/bookmarks/browser/url_index.cc index 1af9762..7a69378 100644 --- a/components/bookmarks/browser/url_index.cc +++ b/components/bookmarks/browser/url_index.cc
@@ -4,6 +4,7 @@ #include "components/bookmarks/browser/url_index.h" +#include "base/containers/adapters.h" #include "components/bookmarks/browser/url_and_title.h" namespace bookmarks { @@ -117,8 +118,8 @@ url_lock_.AssertAcquired(); if (node->is_url()) nodes_ordered_by_url_set_.insert(node); - for (int i = 0; i < node->child_count(); ++i) - AddImpl(node->GetChild(i)); + for (const auto& child : node->children()) + AddImpl(child.get()); } void UrlIndex::RemoveImpl(BookmarkNode* node, std::set<GURL>* removed_urls) { @@ -134,8 +135,8 @@ if (removed_urls) removed_urls->insert(node->url()); } - for (int i = node->child_count() - 1; i >= 0; --i) - RemoveImpl(node->GetChild(i), removed_urls); + for (const auto& child : base::Reversed(node->children())) + RemoveImpl(child.get(), removed_urls); } } // namespace bookmarks
diff --git a/components/bookmarks/managed/managed_bookmarks_tracker_unittest.cc b/components/bookmarks/managed/managed_bookmarks_tracker_unittest.cc index 0b807e3..e03b910b 100644 --- a/components/bookmarks/managed/managed_bookmarks_tracker_unittest.cc +++ b/components/bookmarks/managed/managed_bookmarks_tracker_unittest.cc
@@ -150,24 +150,21 @@ if (node->is_folder()) { const base::ListValue* children = nullptr; if (!dict->GetList("children", &children) || - node->child_count() != static_cast<int>(children->GetSize())) { + node->children().size() != children->GetSize()) { return false; } - for (int i = 0; i < node->child_count(); ++i) { - const base::DictionaryValue* child = nullptr; - if (!children->GetDictionary(i, &child) || - !NodeMatchesValue(node->GetChild(i), child)) { - return false; - } - } - } else if (node->is_url()) { - std::string url; - if (!dict->GetString("url", &url) || node->url() != url) - return false; - } else { - return false; + size_t i = 0; + return std::all_of(node->children().cbegin(), node->children().cend(), + [children, &i](const auto& child_node) { + const base::DictionaryValue* child = nullptr; + return children->GetDictionary(i++, &child) && + NodeMatchesValue(child_node.get(), child); + }); } - return true; + if (!node->is_url()) + return false; + std::string url; + return dict->GetString("url", &url) && node->url() == url; } base::ScopedTempDir scoped_temp_dir_; @@ -308,12 +305,12 @@ EXPECT_TRUE(IsManaged(managed_node())); const BookmarkNode* parent = managed_node(); - ASSERT_EQ(2, parent->child_count()); + ASSERT_EQ(2u, parent->children().size()); EXPECT_TRUE(IsManaged(parent->GetChild(0))); EXPECT_TRUE(IsManaged(parent->GetChild(1))); parent = parent->GetChild(1); - ASSERT_EQ(2, parent->child_count()); + ASSERT_EQ(2u, parent->children().size()); EXPECT_TRUE(IsManaged(parent->GetChild(0))); EXPECT_TRUE(IsManaged(parent->GetChild(1))); } @@ -321,7 +318,7 @@ TEST_F(ManagedBookmarksTrackerTest, RemoveAllUserBookmarksDoesntRemoveManaged) { prefs_.SetManagedPref(prefs::kManagedBookmarks, CreateTestTree()); CreateModel(); - EXPECT_EQ(2, managed_node()->child_count()); + EXPECT_EQ(2u, managed_node()->children().size()); EXPECT_CALL(observer_, BookmarkNodeAdded(model_.get(), model_->bookmark_bar_node(), 0)); @@ -333,13 +330,13 @@ GURL("http://google.com/")); model_->AddFolder( model_->bookmark_bar_node(), 1, base::ASCIIToUTF16("Test Folder")); - EXPECT_EQ(2, model_->bookmark_bar_node()->child_count()); + EXPECT_EQ(2u, model_->bookmark_bar_node()->children().size()); Mock::VerifyAndClearExpectations(&observer_); EXPECT_CALL(observer_, BookmarkAllUserNodesRemoved(model_.get(), _)); model_->RemoveAllUserBookmarks(); - EXPECT_EQ(2, managed_node()->child_count()); - EXPECT_EQ(0, model_->bookmark_bar_node()->child_count()); + EXPECT_EQ(2u, managed_node()->children().size()); + EXPECT_EQ(0u, model_->bookmark_bar_node()->children().size()); Mock::VerifyAndClearExpectations(&observer_); }
diff --git a/components/bookmarks/test/bookmark_test_helpers.cc b/components/bookmarks/test/bookmark_test_helpers.cc index 98a2283..ec506f5 100644 --- a/components/bookmarks/test/bookmark_test_helpers.cc +++ b/components/bookmarks/test/bookmark_test_helpers.cc
@@ -109,18 +109,12 @@ } std::string ModelStringFromNode(const BookmarkNode* node) { - // Since the children of the node are not available as a vector, - // we'll just have to do it the hard way. - int child_count = node->child_count(); std::string child_string; - for (int i = 0; i < child_count; ++i) { - const BookmarkNode* child = node->GetChild(i); - if (child->is_folder()) { - child_string += base::UTF16ToUTF8(child->GetTitle()) + ":[ " + - ModelStringFromNode(child) + "] "; - } else { - child_string += base::UTF16ToUTF8(child->GetTitle()) + " "; - } + for (const auto& child : node->children()) { + child_string += base::UTF16ToUTF8(child->GetTitle()); + if (child->is_folder()) + child_string += ":[ " + ModelStringFromNode(child.get()) + "]"; + child_string += ' '; } return child_string; }
diff --git a/components/browser_sync/profile_sync_service_bookmark_unittest.cc b/components/browser_sync/profile_sync_service_bookmark_unittest.cc index d490c656a..01425839 100644 --- a/components/browser_sync/profile_sync_service_bookmark_unittest.cc +++ b/components/browser_sync/profile_sync_service_bookmark_unittest.cc
@@ -645,11 +645,12 @@ } // Check for position matches. - int browser_index = bnode->parent()->GetIndexOf(bnode); + size_t browser_index = size_t{bnode->parent()->GetIndexOf(bnode)}; if (browser_index == 0) { EXPECT_EQ(gnode.GetPredecessorId(), 0); } else { - const BookmarkNode* bprev = bnode->parent()->GetChild(browser_index - 1); + const BookmarkNode* bprev = + bnode->parent()->children()[browser_index - 1].get(); syncer::ReadNode gprev(trans); ASSERT_TRUE(InitSyncNodeFromChromeNode(bprev, &gprev)); EXPECT_EQ(gnode.GetPredecessorId(), gprev.GetId()); @@ -658,8 +659,8 @@ // Note: the managed node is the last child of the root_node but isn't // synced; if CanSyncNode() is false then there is no next node to sync. const BookmarkNode* bnext = nullptr; - if (browser_index + 1 < bnode->parent()->child_count()) - bnext = bnode->parent()->GetChild(browser_index + 1); + if (browser_index + 1 < bnode->parent()->children().size()) + bnext = bnode->parent()->children()[browser_index + 1].get(); if (!bnext || !CanSyncNode(bnext)) { EXPECT_EQ(gnode.GetSuccessorId(), 0); } else { @@ -925,7 +926,7 @@ ExpectModelMatch(); // The bookmark node should be deleted. - EXPECT_EQ(0, folder->child_count()); + EXPECT_TRUE(folder->children().empty()); } // Tests that the external ID is used to match the right folder amoung @@ -1082,10 +1083,9 @@ // Concatenate resulting titles of native nodes. std::string native_titles; - for (int i = 0; i < folder->child_count(); i++) { + for (const auto& child : folder->children()) { if (!native_titles.empty()) native_titles += ","; - const BookmarkNode* child = folder->GetChild(i); native_titles += base::UTF16ToUTF8(child->GetTitle()); } @@ -1312,7 +1312,7 @@ adds.ApplyPendingChanges(change_processor()); - EXPECT_EQ(1, model()->other_node()->child_count()); + EXPECT_EQ(1u, model()->other_node()->children().size()); ExpectModelMatch(&trans); } @@ -1322,7 +1322,7 @@ StartSync(); // There should still be just the one bookmark. - EXPECT_EQ(1, model()->other_node()->child_count()); + EXPECT_EQ(1u, model()->other_node()->children().size()); ExpectModelMatch(); } @@ -1332,7 +1332,7 @@ LoadBookmarkModel(DELETE_EXISTING_STORAGE, SAVE_TO_STORAGE); StartSync(); - int child_count = 0; + size_t child_count = 0; { syncer::WriteTransaction trans(FROM_HERE, test_user_share()->user_share()); @@ -1346,7 +1346,7 @@ // We're lenient about what should happen -- the model could wind up with // the node or without it; but things should be consistent, and we // shouldn't crash. - child_count = model()->other_node()->child_count(); + child_count = model()->other_node()->children().size(); EXPECT_TRUE(child_count == 0 || child_count == 1); ExpectModelMatch(&trans); } @@ -1357,7 +1357,7 @@ StartSync(); // Things ought not to have changed. - EXPECT_EQ(model()->other_node()->child_count(), child_count); + EXPECT_EQ(model()->other_node()->children().size(), child_count); ExpectModelMatch(); } @@ -1398,16 +1398,14 @@ } // Verify that the browser model matches the sync model. - EXPECT_EQ(static_cast<size_t>(model()->other_node()->child_count()), - 2 * base::size(names)); + EXPECT_EQ(model()->other_node()->children().size(), 2 * base::size(names)); ExpectModelMatch(); // Restart and re-associate. Verify things still match. StopSync(); LoadBookmarkModel(LOAD_FROM_STORAGE, SAVE_TO_STORAGE); StartSync(); - EXPECT_EQ(static_cast<size_t>(model()->other_node()->child_count()), - 2 * base::size(names)); + EXPECT_EQ(model()->other_node()->children().size(), 2 * base::size(names)); ExpectModelMatch(); } @@ -1492,13 +1490,13 @@ model()->AddURL(model()->other_node(), 0, base::ASCIIToUTF16("Dup"), GURL("http://dup.com/")); - EXPECT_EQ(2, model()->other_node()->child_count()); + EXPECT_EQ(2u, model()->other_node()->children().size()); // Restart the sync service to trigger model association. StopSync(); StartSync(); - EXPECT_EQ(2, model()->other_node()->child_count()); + EXPECT_EQ(2u, model()->other_node()->children().size()); ExpectModelMatch(); } @@ -1615,7 +1613,7 @@ int* running_count); void CompareWithTestData(const BookmarkNode* node, const TestData* data, - int size, + size_t size, int* running_count); void ExpectBookmarkModelMatchesTestData(); @@ -1772,14 +1770,14 @@ void ProfileSyncServiceBookmarkTestWithData::CompareWithTestData( const BookmarkNode* node, const TestData* data, - int size, + size_t size, int* running_count) { ASSERT_TRUE(node); ASSERT_TRUE(data); ASSERT_TRUE(node->is_folder()); - ASSERT_EQ(size, node->child_count()); - for (int i = 0; i < size; ++i) { - const BookmarkNode* child_node = node->GetChild(i); + ASSERT_EQ(size, node->children().size()); + for (size_t i = 0; i < size; ++i) { + const BookmarkNode* child_node = node->children()[i].get(); const TestData& item = data[i]; GURL url = GURL(item.url == nullptr ? "" : item.url); BookmarkNode test_node(url); @@ -1809,7 +1807,7 @@ PopulateFromTestData(bookmarks_bar_node, kBookmarkBarChildren, base::size(kBookmarkBarChildren), &count); - ASSERT_GE(bookmarks_bar_node->child_count(), 4); + ASSERT_GE(bookmarks_bar_node->children().size(), 4u); const BookmarkNode* f1_node = bookmarks_bar_node->GetChild(1); PopulateFromTestData(f1_node, kF1Children, base::size(kF1Children), &count); const BookmarkNode* f2_node = bookmarks_bar_node->GetChild(3); @@ -1819,7 +1817,7 @@ PopulateFromTestData(other_bookmarks_node, kOtherBookmarkChildren, base::size(kOtherBookmarkChildren), &count); - ASSERT_GE(other_bookmarks_node->child_count(), 6); + ASSERT_GE(other_bookmarks_node->children().size(), 6u); const BookmarkNode* f3_node = other_bookmarks_node->GetChild(0); PopulateFromTestData(f3_node, kF3Children, base::size(kF3Children), &count); const BookmarkNode* f4_node = other_bookmarks_node->GetChild(3); @@ -1835,7 +1833,7 @@ PopulateFromTestData(mobile_bookmarks_node, kMobileBookmarkChildren, base::size(kMobileBookmarkChildren), &count); - ASSERT_GE(mobile_bookmarks_node->child_count(), 3); + ASSERT_GE(mobile_bookmarks_node->children().size(), 3u); const BookmarkNode* f5_node = mobile_bookmarks_node->GetChild(0); PopulateFromTestData(f5_node, kF5Children, base::size(kF5Children), &count); const BookmarkNode* f6_node = mobile_bookmarks_node->GetChild(1); @@ -1851,7 +1849,7 @@ CompareWithTestData(bookmark_bar_node, kBookmarkBarChildren, base::size(kBookmarkBarChildren), &count); - ASSERT_GE(bookmark_bar_node->child_count(), 4); + ASSERT_GE(bookmark_bar_node->children().size(), 4u); const BookmarkNode* f1_node = bookmark_bar_node->GetChild(1); CompareWithTestData(f1_node, kF1Children, base::size(kF1Children), &count); const BookmarkNode* f2_node = bookmark_bar_node->GetChild(3); @@ -1861,7 +1859,7 @@ CompareWithTestData(other_bookmarks_node, kOtherBookmarkChildren, base::size(kOtherBookmarkChildren), &count); - ASSERT_GE(other_bookmarks_node->child_count(), 6); + ASSERT_GE(other_bookmarks_node->children().size(), 6u); const BookmarkNode* f3_node = other_bookmarks_node->GetChild(0); CompareWithTestData(f3_node, kF3Children, base::size(kF3Children), &count); const BookmarkNode* f4_node = other_bookmarks_node->GetChild(3); @@ -1877,7 +1875,7 @@ CompareWithTestData(mobile_bookmarks_node, kMobileBookmarkChildren, base::size(kMobileBookmarkChildren), &count); - ASSERT_GE(mobile_bookmarks_node->child_count(), 3); + ASSERT_GE(mobile_bookmarks_node->children().size(), 3u); const BookmarkNode* f5_node = mobile_bookmarks_node->GetChild(0); CompareWithTestData(f5_node, kF5Children, base::size(kF5Children), &count); const BookmarkNode* f6_node = mobile_bookmarks_node->GetChild(1); @@ -1944,9 +1942,9 @@ // Blow away the bookmark model -- it should be empty afterwards. LoadBookmarkModel(DELETE_EXISTING_STORAGE, DONT_SAVE_TO_STORAGE); - EXPECT_EQ(model()->bookmark_bar_node()->child_count(), 0); - EXPECT_EQ(model()->other_node()->child_count(), 0); - EXPECT_EQ(model()->mobile_node()->child_count(), 0); + EXPECT_TRUE(model()->bookmark_bar_node()->children().empty()); + EXPECT_TRUE(model()->other_node()->children().empty()); + EXPECT_TRUE(model()->mobile_node()->children().empty()); // Now restart the sync service. Starting it should populate the bookmark // model -- test for consistency. @@ -1978,7 +1976,7 @@ ExpectBookmarkModelMatchesTestData(); const BookmarkNode* bookmark_bar = model()->bookmark_bar_node(); ASSERT_TRUE(bookmark_bar); - ASSERT_GT(bookmark_bar->child_count(), 1); + ASSERT_GT(bookmark_bar->children().size(), 1u); model()->Move(bookmark_bar->GetChild(0), bookmark_bar, 1); StartSync(); ExpectModelMatch(); @@ -1994,28 +1992,29 @@ // Remove some nodes and reorder some nodes. const BookmarkNode* bookmark_bar_node = model()->bookmark_bar_node(); - int remove_index = 2; - ASSERT_GT(bookmark_bar_node->child_count(), remove_index); - const BookmarkNode* child_node = bookmark_bar_node->GetChild(remove_index); + size_t remove_index = 2; + ASSERT_GT(bookmark_bar_node->children().size(), remove_index); + const BookmarkNode* child_node = + bookmark_bar_node->children()[remove_index].get(); ASSERT_TRUE(child_node); ASSERT_TRUE(child_node->is_url()); - model()->Remove(bookmark_bar_node->GetChild(remove_index)); - ASSERT_GT(bookmark_bar_node->child_count(), remove_index); - child_node = bookmark_bar_node->GetChild(remove_index); + model()->Remove(bookmark_bar_node->children()[remove_index].get()); + ASSERT_GT(bookmark_bar_node->children().size(), remove_index); + child_node = bookmark_bar_node->children()[remove_index].get(); ASSERT_TRUE(child_node); ASSERT_TRUE(child_node->is_folder()); - model()->Remove(bookmark_bar_node->GetChild(remove_index)); + model()->Remove(bookmark_bar_node->children()[remove_index].get()); const BookmarkNode* other_node = model()->other_node(); - ASSERT_GE(other_node->child_count(), 1); + ASSERT_GE(other_node->children().size(), 1u); const BookmarkNode* f3_node = other_node->GetChild(0); ASSERT_TRUE(f3_node); ASSERT_TRUE(f3_node->is_folder()); remove_index = 2; - ASSERT_GT(f3_node->child_count(), remove_index); - model()->Remove(f3_node->GetChild(remove_index)); - ASSERT_GT(f3_node->child_count(), remove_index); - model()->Remove(f3_node->GetChild(remove_index)); + ASSERT_GT(f3_node->children().size(), remove_index); + model()->Remove(f3_node->children()[remove_index].get()); + ASSERT_GT(f3_node->children().size(), remove_index); + model()->Remove(f3_node->children()[remove_index].get()); StartSync(); ExpectModelMatch(); @@ -2028,32 +2027,32 @@ // Remove some nodes and reorder some nodes. bookmark_bar_node = model()->bookmark_bar_node(); remove_index = 0; - ASSERT_GT(bookmark_bar_node->child_count(), remove_index); - child_node = bookmark_bar_node->GetChild(remove_index); + ASSERT_GT(bookmark_bar_node->children().size(), remove_index); + child_node = bookmark_bar_node->children()[remove_index].get(); ASSERT_TRUE(child_node); ASSERT_TRUE(child_node->is_url()); - model()->Remove(bookmark_bar_node->GetChild(remove_index)); - ASSERT_GT(bookmark_bar_node->child_count(), remove_index); - child_node = bookmark_bar_node->GetChild(remove_index); + model()->Remove(bookmark_bar_node->children()[remove_index].get()); + ASSERT_GT(bookmark_bar_node->children().size(), remove_index); + child_node = bookmark_bar_node->children()[remove_index].get(); ASSERT_TRUE(child_node); ASSERT_TRUE(child_node->is_folder()); - model()->Remove(bookmark_bar_node->GetChild(remove_index)); + model()->Remove(bookmark_bar_node->children()[remove_index].get()); - ASSERT_GE(bookmark_bar_node->child_count(), 2); + ASSERT_GE(bookmark_bar_node->children().size(), 2u); model()->Move(bookmark_bar_node->GetChild(0), bookmark_bar_node, 1); other_node = model()->other_node(); - ASSERT_GE(other_node->child_count(), 1); + ASSERT_GE(other_node->children().size(), 1u); f3_node = other_node->GetChild(0); ASSERT_TRUE(f3_node); ASSERT_TRUE(f3_node->is_folder()); remove_index = 0; - ASSERT_GT(f3_node->child_count(), remove_index); - model()->Remove(f3_node->GetChild(remove_index)); - ASSERT_GT(f3_node->child_count(), remove_index); - model()->Remove(f3_node->GetChild(remove_index)); + ASSERT_GT(f3_node->children().size(), remove_index); + model()->Remove(f3_node->children()[remove_index].get()); + ASSERT_GT(f3_node->children().size(), remove_index); + model()->Remove(f3_node->children()[remove_index].get()); - ASSERT_GE(other_node->child_count(), 4); + ASSERT_GE(other_node->children().size(), 4u); model()->Move(other_node->GetChild(0), other_node, 1); model()->Move(other_node->GetChild(2), other_node, 3); @@ -2179,9 +2178,10 @@ // Modify the date_added field of a bookmark so it doesn't match with // the sync data. const BookmarkNode* bookmark_bar_node = model()->bookmark_bar_node(); - int modified_index = 2; - ASSERT_GT(bookmark_bar_node->child_count(), modified_index); - const BookmarkNode* child_node = bookmark_bar_node->GetChild(modified_index); + size_t modified_index = 2; + ASSERT_GT(bookmark_bar_node->children().size(), modified_index); + const BookmarkNode* child_node = + bookmark_bar_node->children()[modified_index].get(); ASSERT_TRUE(child_node); EXPECT_TRUE(child_node->is_url()); model()->SetDateAdded(child_node, base::Time::FromInternalValue(10)); @@ -2289,11 +2289,11 @@ adds.ApplyPendingChanges(change_processor()); // Verify that the nodes are created with the correct meta info. - ASSERT_LT(0, model()->bookmark_bar_node()->child_count()); + ASSERT_GT(model()->bookmark_bar_node()->children().size(), 0u); const BookmarkNode* folder_node = model()->bookmark_bar_node()->GetChild(0); ASSERT_TRUE(folder_node->GetMetaInfoMap()); EXPECT_EQ(folder_meta_info, *folder_node->GetMetaInfoMap()); - ASSERT_LT(0, folder_node->child_count()); + ASSERT_GT(folder_node->children().size(), 0u); const BookmarkNode* node = folder_node->GetChild(0); ASSERT_TRUE(node->GetMetaInfoMap()); EXPECT_EQ(node_meta_info, *node->GetMetaInfoMap()); @@ -2409,10 +2409,9 @@ EXPECT_NE(BookmarkNode::kInvalidSyncTransactionVersion, version); (*node_versions)[n->id()] = version; - for (int i = 0; i < n->child_count(); ++i) { - if (!CanSyncNode(n->GetChild(i))) - continue; - nodes.push(n->GetChild(i)); + for (const auto& child : n->children()) { + if (CanSyncNode(child.get())) + nodes.push(child.get()); } } }
diff --git a/components/browsing_data/core/counters/bookmark_counter.cc b/components/browsing_data/core/counters/bookmark_counter.cc index ab1da23e..21d8672 100644 --- a/components/browsing_data/core/counters/bookmark_counter.cc +++ b/components/browsing_data/core/counters/bookmark_counter.cc
@@ -18,8 +18,8 @@ if (node->date_added() >= period_start) ++count; } else { - for (int i = 0; i < node->child_count(); ++i) - count += CountBookmarksFromNode(node->GetChild(i), period_start); + for (const auto& child : node->children()) + count += CountBookmarksFromNode(child.get(), period_start); } return count; }
diff --git a/components/embedder_support/android/delegate/DEPS b/components/embedder_support/android/delegate/DEPS index 2d68883..9115f9d 100644 --- a/components/embedder_support/android/delegate/DEPS +++ b/components/embedder_support/android/delegate/DEPS
@@ -2,6 +2,8 @@ "+components/embedder_support/android/web_contents_delegate_jni_headers", "+content/public/browser", "+content/public/common", + "+jni", + "+third_party/blink/public/common", "+third_party/blink/public/mojom", "+ui/android", "+ui/base",
diff --git a/components/embedder_support/android/delegate/web_contents_delegate_android.cc b/components/embedder_support/android/delegate/web_contents_delegate_android.cc index 3d791ce..3ba63a18 100644 --- a/components/embedder_support/android/delegate/web_contents_delegate_android.cc +++ b/components/embedder_support/android/delegate/web_contents_delegate_android.cc
@@ -21,6 +21,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/referrer.h" #include "content/public/common/resource_request_body_android.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" #include "ui/base/window_open_disposition.h" #include "ui/gfx/geometry/rect.h" #include "url/gurl.h" @@ -375,9 +376,11 @@ return Java_WebContentsDelegateAndroid_isFullscreenForTabOrPending(env, obj); } -void WebContentsDelegateAndroid::OnDidBlockFramebust( +void WebContentsDelegateAndroid::OnDidBlockNavigation( content::WebContents* web_contents, - const GURL& url) {} + const GURL& initiator_url, + const GURL& blocked_url, + blink::NavigationBlockedReason reason) {} int WebContentsDelegateAndroid::GetTopControlsHeight() { JNIEnv* env = AttachCurrentThread();
diff --git a/components/embedder_support/android/delegate/web_contents_delegate_android.h b/components/embedder_support/android/delegate/web_contents_delegate_android.h index e535b00bd..62ccbc2 100644 --- a/components/embedder_support/android/delegate/web_contents_delegate_android.h +++ b/components/embedder_support/android/delegate/web_contents_delegate_android.h
@@ -13,6 +13,7 @@ #include "base/android/scoped_java_ref.h" #include "base/compiler_specific.h" #include "content/public/browser/web_contents_delegate.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" class GURL; @@ -110,8 +111,10 @@ void ExitFullscreenModeForTab(content::WebContents* web_contents) override; bool IsFullscreenForTabOrPending( const content::WebContents* web_contents) override; - void OnDidBlockFramebust(content::WebContents* web_contents, - const GURL& url) override; + void OnDidBlockNavigation(content::WebContents* web_contents, + const GURL& blocked_url, + const GURL& initiator_url, + blink::NavigationBlockedReason reason) override; int GetTopControlsHeight() override; int GetBottomControlsHeight() override; bool DoBrowserControlsShrinkRendererSize(
diff --git a/components/exo/wayland/fuzzer/harness.cc.tmpl b/components/exo/wayland/fuzzer/harness.cc.tmpl index 2e2857a..0fc670d 100644 --- a/components/exo/wayland/fuzzer/harness.cc.tmpl +++ b/components/exo/wayland/fuzzer/harness.cc.tmpl
@@ -76,10 +76,10 @@ {{arg.cpp_type}} {{arg.name}} = harness->get_{{arg.interface}}(action.{{arg.name}}()); {% if not arg.nullable %} if (!{{arg.name}}) - return; + return; {% endif %} - {% elif arg.type == 'fd' %} - int {{arg.name}} = harness->GetFileDescriptor(action.{{arg.name}}()); + {% elif arg.type == 'fd' %} + int {{arg.name}} = harness->GetFileDescriptor(action.{{arg.name}}()); {% endif %} {% endfor %} {% if request.is_constructor %} @@ -160,7 +160,16 @@ } Harness::~Harness() { - wl_display_disconnect(wl_display_list_.front()); + {% for interface in interfaces %} + for (auto ifc : {{interface.name}}_list_) { + if (ifc) + {% if interface.name == "wl_display" %} + wl_display_disconnect(ifc); + {% else %} + free(ifc); + {% endif %} + } + {% endfor %} } void Harness::Run(const actions::actions& all_steps) {
diff --git a/components/gwp_asan/client/sampling_malloc_shims_unittest.cc b/components/gwp_asan/client/sampling_malloc_shims_unittest.cc index 915ecf0..a42f7a4 100644 --- a/components/gwp_asan/client/sampling_malloc_shims_unittest.cc +++ b/components/gwp_asan/client/sampling_malloc_shims_unittest.cc
@@ -76,8 +76,8 @@ void runTest(const char* name) { base::Process process = SpawnChild(name); int exit_code = -1; - ASSERT_TRUE(process.WaitForExitWithTimeout( - TestTimeouts::action_max_timeout(), &exit_code)); + ASSERT_TRUE(WaitForMultiprocessTestChildExit( + process, TestTimeouts::action_max_timeout(), &exit_code)); EXPECT_EQ(exit_code, kSuccess); } };
diff --git a/components/gwp_asan/client/sampling_partitionalloc_shims_unittest.cc b/components/gwp_asan/client/sampling_partitionalloc_shims_unittest.cc index 91b842e..54a6752 100644 --- a/components/gwp_asan/client/sampling_partitionalloc_shims_unittest.cc +++ b/components/gwp_asan/client/sampling_partitionalloc_shims_unittest.cc
@@ -63,8 +63,8 @@ void runTest(const char* name) { base::Process process = SpawnChild(name); int exit_code = -1; - ASSERT_TRUE(process.WaitForExitWithTimeout( - TestTimeouts::action_max_timeout(), &exit_code)); + ASSERT_TRUE(WaitForMultiprocessTestChildExit( + process, TestTimeouts::action_max_timeout(), &exit_code)); EXPECT_EQ(exit_code, kSuccess); } };
diff --git a/components/gwp_asan/crash_handler/crash_handler_unittest.cc b/components/gwp_asan/crash_handler/crash_handler_unittest.cc index cd08c1f8..f658bc5 100644 --- a/components/gwp_asan/crash_handler/crash_handler_unittest.cc +++ b/components/gwp_asan/crash_handler/crash_handler_unittest.cc
@@ -224,8 +224,8 @@ base::SpawnMultiProcessTestChild("CrashingProcess", cmd_line, options); int exit_code = -1; - EXPECT_TRUE(process.WaitForExitWithTimeout( - TestTimeouts::action_max_timeout(), &exit_code)); + EXPECT_TRUE(WaitForMultiprocessTestChildExit( + process, TestTimeouts::action_max_timeout(), &exit_code)); EXPECT_NE(exit_code, kSuccess); return (exit_code != kSuccess);
diff --git a/components/media_message_center/media_notification_view.cc b/components/media_message_center/media_notification_view.cc index acc84ee..b0330a3 100644 --- a/components/media_message_center/media_notification_view.cc +++ b/components/media_message_center/media_notification_view.cc
@@ -116,7 +116,7 @@ DCHECK(container_); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), 0)); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), 0)); auto header_row = std::make_unique<message_center::NotificationHeaderView>(this); @@ -141,7 +141,8 @@ auto title_artist_row = std::make_unique<views::View>(); title_artist_row_layout_ = title_artist_row->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, kMediaTitleArtistInsets, 0)); + views::BoxLayout::Orientation::kVertical, kMediaTitleArtistInsets, + 0)); title_artist_row_layout_->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kCenter); title_artist_row_layout_->set_cross_axis_alignment( @@ -167,7 +168,7 @@ auto button_row = std::make_unique<views::View>(); auto* button_row_layout = button_row->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), kMediaButtonRowSeparator)); button_row_layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter); @@ -382,7 +383,7 @@ main_row_ ->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, + views::BoxLayout::Orientation::kVertical, gfx::Insets( kDefaultMarginSize, kDefaultMarginSize, kDefaultMarginSize, has_artwork_ ? kRightMarginExpandedSize : kDefaultMarginSize), @@ -394,7 +395,7 @@ main_row_ ->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(0, kDefaultMarginSize, 14, has_artwork_ ? kRightMarginSize : kDefaultMarginSize), kDefaultMarginSize, true))
diff --git a/components/previews/core/previews_experiments.h b/components/previews/core/previews_experiments.h index 2fd9ea4..bc0fa0b 100644 --- a/components/previews/core/previews_experiments.h +++ b/components/previews/core/previews_experiments.h
@@ -15,6 +15,8 @@ namespace previews { +// Types of previews. This enum must remain synchronized with the enum +// |PreviewsType| in tools/metrics/histograms/enums.xml. enum class PreviewsType { // Used to indicate that there is no preview type. NONE = 0,
diff --git a/components/safe_browsing/browser/threat_details.cc b/components/safe_browsing/browser/threat_details.cc index dc40a03..408fd72 100644 --- a/components/safe_browsing/browser/threat_details.cc +++ b/components/safe_browsing/browser/threat_details.cc
@@ -97,6 +97,8 @@ return ClientSafeBrowsingReportRequest::BLOCKED_AD_POPUP; case SB_THREAT_TYPE_AD_SAMPLE: return ClientSafeBrowsingReportRequest::AD_SAMPLE; + case SB_THREAT_TYPE_BLOCKED_AD_REDIRECT: + return ClientSafeBrowsingReportRequest::BLOCKED_AD_REDIRECT; case SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE: case SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE: return ClientSafeBrowsingReportRequest::URL_PASSWORD_PROTECTION_PHISHING; @@ -805,7 +807,6 @@ return; } } - // Add all the urls in our |resources_| maps to the |report_| protocol buffer. for (auto& resource_pair : resources_) { ClientSafeBrowsingReportRequest::Resource* pb_resource =
diff --git a/components/safe_browsing/db/v4_protocol_manager_util.h b/components/safe_browsing/db/v4_protocol_manager_util.h index dd21935..e5b34ad 100644 --- a/components/safe_browsing/db/v4_protocol_manager_util.h +++ b/components/safe_browsing/db/v4_protocol_manager_util.h
@@ -146,6 +146,9 @@ // Chrome sign in password reuse detected on low reputation page, SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE, + // A Google ad that caused a blocked autoredirect was collected + SB_THREAT_TYPE_BLOCKED_AD_REDIRECT, + // A sample of an ad was collected SB_THREAT_TYPE_AD_SAMPLE,
diff --git a/components/safe_browsing/features.cc b/components/safe_browsing/features.cc index 444fb4f..eb9ebc9 100644 --- a/components/safe_browsing/features.cc +++ b/components/safe_browsing/features.cc
@@ -20,6 +20,9 @@ const base::Feature kAdPopupTriggerFeature{"SafeBrowsingAdPopupTrigger", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kAdRedirectTriggerFeature{ + "SafeBrowsingAdRedirectTrigger", base::FEATURE_DISABLED_BY_DEFAULT}; + // Controls various parameters related to occasionally collecting ad samples, // for example to control how often collection should occur. const base::Feature kAdSamplerTriggerFeature{"SafeBrowsingAdSamplerTrigger", @@ -87,6 +90,7 @@ bool show_state; } kExperimentalFeatures[]{ {&kAdPopupTriggerFeature, true}, + {&kAdRedirectTriggerFeature, true}, {&kAdSamplerTriggerFeature, false}, {&kCaptureInlineJavascriptForGoogleAds, true}, {&kCaptureSafetyNetId, true},
diff --git a/components/safe_browsing/features.h b/components/safe_browsing/features.h index 2d7549d9..fd73826 100644 --- a/components/safe_browsing/features.h +++ b/components/safe_browsing/features.h
@@ -20,9 +20,13 @@ namespace safe_browsing { // Features list // Controls whether we send RIND reports when a popup originating from a Google -// ad is blocked. +// Ad is blocked. extern const base::Feature kAdPopupTriggerFeature; +// Controls whether we send RIND reports when a redirect caused by a Google Ad +// is blocked. +extern const base::Feature kAdRedirectTriggerFeature; + extern const base::Feature kAdSamplerTriggerFeature; // Controls whether we sample inline JavaScript for ads in RIND
diff --git a/components/safe_browsing/proto/csd.proto b/components/safe_browsing/proto/csd.proto index 9e164c3..0b23e70 100644 --- a/components/safe_browsing/proto/csd.proto +++ b/components/safe_browsing/proto/csd.proto
@@ -1155,6 +1155,7 @@ URL_SUSPICIOUS = 15; BILLING = 16; APK_DOWNLOAD = 17; + BLOCKED_AD_REDIRECT = 19; BLOCKED_AD_POPUP = 20; }
diff --git a/components/safe_browsing/triggers/BUILD.gn b/components/safe_browsing/triggers/BUILD.gn index ea0d45ecb..1ee288e6 100644 --- a/components/safe_browsing/triggers/BUILD.gn +++ b/components/safe_browsing/triggers/BUILD.gn
@@ -50,10 +50,10 @@ ] } -source_set("ad_sampler_trigger") { +source_set("ad_popup_trigger") { sources = [ - "ad_sampler_trigger.cc", - "ad_sampler_trigger.h", + "ad_popup_trigger.cc", + "ad_popup_trigger.h", ] deps = [ ":trigger_throttler", @@ -65,10 +65,26 @@ ] } -source_set("ad_popup_trigger") { +source_set("ad_redirect_trigger") { sources = [ - "ad_popup_trigger.cc", - "ad_popup_trigger.h", + "ad_redirect_trigger.cc", + "ad_redirect_trigger.h", + ] + deps = [ + ":trigger_throttler", + ":trigger_util", + ":triggers", + "//base:base", + "//components/safe_browsing:features", + "//content/public/browser", + "//content/public/common", + ] +} + +source_set("ad_sampler_trigger") { + sources = [ + "ad_sampler_trigger.cc", + "ad_sampler_trigger.h", ] deps = [ ":trigger_throttler", @@ -120,6 +136,7 @@ "//components/safe_browsing:features", "//components/safe_browsing/browser:browser", "//components/subresource_filter/content/browser:test_support", + "//content/public/browser:browser", "//content/test:test_support", "//testing/gmock", "//testing/gtest",
diff --git a/components/safe_browsing/triggers/ad_redirect_trigger.cc b/components/safe_browsing/triggers/ad_redirect_trigger.cc new file mode 100644 index 0000000..180d208b --- /dev/null +++ b/components/safe_browsing/triggers/ad_redirect_trigger.cc
@@ -0,0 +1,150 @@ +// 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 "components/safe_browsing/triggers/ad_redirect_trigger.h" + +#include <string> + +#include "base/bind.h" +#include "base/feature_list.h" +#include "base/metrics/field_trial_params.h" +#include "base/metrics/histogram_macros.h" +#include "base/rand_util.h" +#include "base/single_thread_task_runner.h" +#include "base/strings/string_number_conversions.h" +#include "base/task/post_task.h" +#include "components/safe_browsing/features.h" +#include "components/safe_browsing/triggers/trigger_manager.h" +#include "components/safe_browsing/triggers/trigger_throttler.h" +#include "components/safe_browsing/triggers/trigger_util.h" +#include "components/security_interstitials/content/unsafe_resource.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_contents.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/simple_url_loader.h" + +namespace safe_browsing { + +// Number of milliseconds to allow data collection to run before sending a +// report (since this trigger runs in the background). +const int64_t kAdRedirectCollectionPeriodMilliseconds = 5000; + +// Range of number of milliseconds to wait after a page finished loading before +// starting a report. Allows ads which load in the background to finish loading. +const int64_t kMaxAdRedirectCollectionStartDelayMilliseconds = 5000; +const int64_t kMinAdRedirectCollectionStartDelayMilliseconds = 500; + +// Metric for tracking what the Ad Redirect trigger does on each navigation. +const char kAdRedirectTriggerActionMetricName[] = + "SafeBrowsing.Triggers.AdRedirect.Action"; + +AdRedirectTrigger::AdRedirectTrigger( + content::WebContents* web_contents, + TriggerManager* trigger_manager, + PrefService* prefs, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + history::HistoryService* history_service) + : web_contents_(web_contents), + start_report_delay_ms_( + base::RandInt(kMinAdRedirectCollectionStartDelayMilliseconds, + kMaxAdRedirectCollectionStartDelayMilliseconds)), + finish_report_delay_ms_(kAdRedirectCollectionPeriodMilliseconds), + trigger_manager_(trigger_manager), + prefs_(prefs), + url_loader_factory_(url_loader_factory), + history_service_(history_service), + task_runner_(base::CreateSingleThreadTaskRunnerWithTraits( + {content::BrowserThread::UI})), + weak_ptr_factory_(this) {} + +AdRedirectTrigger::~AdRedirectTrigger() {} + +// static +void AdRedirectTrigger::CreateForWebContents( + content::WebContents* web_contents, + TriggerManager* trigger_manager, + PrefService* prefs, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + history::HistoryService* history_service) { + DCHECK(web_contents); + if (!FromWebContents(web_contents)) { + web_contents->SetUserData(UserDataKey(), + base::WrapUnique(new AdRedirectTrigger( + web_contents, trigger_manager, prefs, + url_loader_factory, history_service))); + } +} + +void AdRedirectTrigger::CreateAdRedirectReport() { + SBErrorOptions error_options = + TriggerManager::GetSBErrorDisplayOptions(*prefs_, web_contents_); + security_interstitials::UnsafeResource resource; + resource.threat_type = SB_THREAT_TYPE_BLOCKED_AD_REDIRECT; + resource.url = web_contents_->GetURL(); + resource.web_contents_getter = resource.GetWebContentsGetter( + web_contents_->GetMainFrame()->GetProcess()->GetID(), + web_contents_->GetMainFrame()->GetRoutingID()); + TriggerManagerReason reason; + if (!trigger_manager_->StartCollectingThreatDetailsWithReason( + TriggerType::AD_REDIRECT, web_contents_, resource, + url_loader_factory_, history_service_, error_options, &reason)) { + if (reason == TriggerManagerReason::DAILY_QUOTA_EXCEEDED) { + UMA_HISTOGRAM_ENUMERATION( + kAdRedirectTriggerActionMetricName, + AdRedirectTriggerAction::REDIRECT_DAILY_QUOTA_EXCEEDED); + } else { + UMA_HISTOGRAM_ENUMERATION( + kAdRedirectTriggerActionMetricName, + AdRedirectTriggerAction::REDIRECT_COULD_NOT_START_REPORT); + } + return; + } + // Call into TriggerManager to finish the reports after a short delay. Any + // ads that are detected during this delay will be rejected by TriggerManager + // because a report is already being collected, so we won't send multiple + // reports for the same page. + task_runner_->PostDelayedTask( + FROM_HERE, + base::BindOnce( + IgnoreResult(&TriggerManager::FinishCollectingThreatDetails), + base::Unretained(trigger_manager_), TriggerType::AD_REDIRECT, + base::Unretained(web_contents_), base::TimeDelta(), + /*did_proceed=*/false, /*num_visits=*/0, error_options), + base::TimeDelta::FromMilliseconds(finish_report_delay_ms_)); + UMA_HISTOGRAM_ENUMERATION(kAdRedirectTriggerActionMetricName, + AdRedirectTriggerAction::AD_REDIRECT); +} + +void AdRedirectTrigger::OnDidBlockNavigation(const GURL& initiator_url) { + UMA_HISTOGRAM_ENUMERATION(kAdRedirectTriggerActionMetricName, + AdRedirectTriggerAction::REDIRECT_CHECK); + content::RenderFrameHost* initiator_frame = + web_contents_->GetOriginalOpener(); + // Use focused frame as proxy if there is no opener. + if (!initiator_frame) + initiator_frame = web_contents_->GetFocusedFrame(); + if (!DetectGoogleAd(initiator_frame, initiator_url)) { + UMA_HISTOGRAM_ENUMERATION(kAdRedirectTriggerActionMetricName, + AdRedirectTriggerAction::REDIRECT_NO_GOOGLE_AD); + return; + } + // Create a report after a short delay. + task_runner_->PostDelayedTask( + FROM_HERE, + base::BindOnce(&AdRedirectTrigger::CreateAdRedirectReport, + weak_ptr_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(start_report_delay_ms_)); +} + +void AdRedirectTrigger::SetDelayForTest(int start_report_delay, + int finish_report_delay) { + start_report_delay_ms_ = start_report_delay; + finish_report_delay_ms_ = finish_report_delay; +} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(AdRedirectTrigger) +} // namespace safe_browsing
diff --git a/components/safe_browsing/triggers/ad_redirect_trigger.h b/components/safe_browsing/triggers/ad_redirect_trigger.h new file mode 100644 index 0000000..f29c395 --- /dev/null +++ b/components/safe_browsing/triggers/ad_redirect_trigger.h
@@ -0,0 +1,131 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPONENTS_SAFE_BROWSING_TRIGGERS_AD_REDIRECT_TRIGGER_H_ +#define COMPONENTS_SAFE_BROWSING_TRIGGERS_AD_REDIRECT_TRIGGER_H_ + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "content/public/browser/web_contents_user_data.h" + +class PrefService; + +namespace history { +class HistoryService; +} + +namespace network { +class SharedURLLoaderFactory; +} // namespace network + +namespace safe_browsing { +class TriggerManager; + +using FrameTreeNodeId = int; + +// Metric for tracking what the Ad Redirect trigger does on each navigation. +extern const char kAdRedirectTriggerActionMetricName[]; + +// Actions performed by this trigger. These values are written to logs. New enum +// values can be added, but existing enums must never be renumbered or deleted +// and reused. +enum class AdRedirectTriggerAction { + // A redirect event occurred that caused the trigger to perform its checks. + REDIRECT_CHECK = 0, + // A redirect caused by an ad was detected and a report was collected. + AD_REDIRECT = 1, + // No google ad was detected from the frame causing an autoredirect. + REDIRECT_NO_GOOGLE_AD = 2, + // An ad was detected on the page causing the redirect and could have been + // reported, but the trigger manager rejected the report (eg: because user is + // incognito or has not opted into extended reporting). + REDIRECT_COULD_NOT_START_REPORT = 3, + // Daily quota for blocked ad redirect reporting was met. + REDIRECT_DAILY_QUOTA_EXCEEDED = 4, + // New events must be added before kMaxValue, and the value of kMaxValue + // updated. + kMaxValue = REDIRECT_DAILY_QUOTA_EXCEEDED +}; + +// This class if notified when a redirect navigation is blocked in the renderer +// because there was no user gesture(an autoredirect). If the frame causing the +// autoredirect navigation is a Google Ad frame, this class sends a report to +// Google. +// Design doc: go/extending-chrind-q2-2019-1 +class AdRedirectTrigger + : public content::WebContentsUserData<AdRedirectTrigger> { + public: + ~AdRedirectTrigger() override; + + // |web_contents| is the WebContent of the page that a redirect event took + // place on. |trigger_manager| ensures the trigger is only fired when + // appropriate and keeps track of how often the trigger is fired. |prefs| + // allows us to check that the user has opted in to Extended Reporting. + // |url_loader_factory| allows us to access mojom::URLLoaderFactory. + // |history_service| records page titles, visit times, and favicons, as well + // as information about downloads. + static void CreateForWebContents( + content::WebContents* web_contents, + TriggerManager* trigger_manager, + PrefService* prefs, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + history::HistoryService* history_service); + + // This method is called on the browser thread when a frame tries to navigate + // its top level frame from the |initiator_url| without ever having received a + // user gesture. If the frame causing the redirect navigation is a Google Ad + // frame a report is sent to Google. + void OnDidBlockNavigation(const GURL& initiator_url); + + private: + friend class AdRedirectTriggerBrowserTest; + friend class content::WebContentsUserData<AdRedirectTrigger>; + + AdRedirectTrigger( + content::WebContents* web_contents, + TriggerManager* trigger_manager, + PrefService* prefs, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + history::HistoryService* history_service); + + // Called to create an ad redirect report. + void CreateAdRedirectReport(); + + // Sets report delay for test. + void SetDelayForTest(int start_report_delay, int finish_report_delay); + + // WebContents of the current tab. + content::WebContents* web_contents_; + + // The delay (in milliseconds) to wait before starting a report. Can be + // ovewritten for tests. + int64_t start_report_delay_ms_; + + // The delay (in milliseconds) to wait before finishing a report. Can be + // overwritten for tests. + int64_t finish_report_delay_ms_; + + // TriggerManager gets called if this trigger detects an autoredirect caused + // by a page with an ad and wants to collect some data about it. Not owned. + TriggerManager* trigger_manager_; + + PrefService* prefs_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; + history::HistoryService* history_service_; + + // Task runner for posting delayed tasks. Normally set to the runner for the + // UI thread, but can be overwritten for tests. + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + base::WeakPtrFactory<AdRedirectTrigger> weak_ptr_factory_; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); + + DISALLOW_COPY_AND_ASSIGN(AdRedirectTrigger); +}; + +} // namespace safe_browsing + +#endif // COMPONENTS_SAFE_BROWSING_TRIGGERS_AD_REDIRECT_TRIGGER_H_
diff --git a/components/safe_browsing/triggers/trigger_manager.cc b/components/safe_browsing/triggers/trigger_manager.cc index 9158ec9..3a9e6ed 100644 --- a/components/safe_browsing/triggers/trigger_manager.cc +++ b/components/safe_browsing/triggers/trigger_manager.cc
@@ -27,6 +27,7 @@ // trigger runs, so collection can begin without opt-in. return false; case TriggerType::AD_POPUP: + case TriggerType::AD_REDIRECT: case TriggerType::AD_SAMPLE: // Ad samples happen in the background so the user must already be opted // in before the trigger is allowed to run. @@ -162,7 +163,8 @@ return false; bool should_trim_threat_details = (trigger_type == TriggerType::AD_POPUP || - trigger_type == TriggerType::AD_SAMPLE); + trigger_type == TriggerType::AD_SAMPLE || + trigger_type == TriggerType::AD_REDIRECT); collectors->threat_details = ThreatDetails::NewThreatDetails( ui_manager_, web_contents, resource, url_loader_factory, history_service, referrer_chain_provider_, should_trim_threat_details,
diff --git a/components/safe_browsing/triggers/trigger_throttler.cc b/components/safe_browsing/triggers/trigger_throttler.cc index f8f4ed08a..480d011 100644 --- a/components/safe_browsing/triggers/trigger_throttler.cc +++ b/components/safe_browsing/triggers/trigger_throttler.cc
@@ -16,9 +16,11 @@ namespace safe_browsing { const size_t kAdPopupTriggerDefaultQuota = 1; +const size_t kAdRedirectTriggerDefaultQuota = 1; const size_t kAdSamplerTriggerDefaultQuota = 10; const size_t kSuspiciousSiteTriggerDefaultQuota = 5; const char kAdPopupTriggerQuotaParam[] = "ad_popup_trigger_quota"; +const char kAdRedirectTriggerQuotaParam[] = "ad_redirect_trigger_quota"; const char kSuspiciousSiteTriggerQuotaParam[] = "suspicious_site_trigger_quota"; const char kTriggerTypeAndQuotaParam[] = "trigger_type_and_quota_csv"; @@ -60,6 +62,14 @@ std::make_pair(TriggerType::AD_POPUP, ad_popup_quota)); } + int ad_redirect_quota = base::GetFieldTrialParamByFeatureAsInt( + kAdRedirectTriggerFeature, kAdRedirectTriggerQuotaParam, + kAdRedirectTriggerDefaultQuota); + if (ad_redirect_quota > 0) { + trigger_type_and_quota_list->push_back( + std::make_pair(TriggerType::AD_REDIRECT, ad_redirect_quota)); + } + // If the feature is disabled we just use the default list. Otherwise the list // from the Finch param will be the one used. if (!base::FeatureList::IsEnabled(kTriggerThrottlerDailyQuotaFeature)) { @@ -264,6 +274,13 @@ return quota_from_finch; } break; + case TriggerType::AD_REDIRECT: + // Ad Redirects are disabled unless they are configured through Finch. + if (TryFindQuotaForTrigger(trigger_type, trigger_type_and_quota_list_, + "a_from_finch)) { + return quota_from_finch; + } + break; case TriggerType::AD_SAMPLE: // Ad Samples have a non-zero default quota, but it can be overwritten // through Finch.
diff --git a/components/safe_browsing/triggers/trigger_throttler.h b/components/safe_browsing/triggers/trigger_throttler.h index 0d8621b..f158455 100644 --- a/components/safe_browsing/triggers/trigger_throttler.h +++ b/components/safe_browsing/triggers/trigger_throttler.h
@@ -41,8 +41,9 @@ SUSPICIOUS_SITE = 4, APK_DOWNLOAD = 5, AD_POPUP = 6, + AD_REDIRECT = 7, kMinTriggerType = SECURITY_INTERSTITIAL, - kMaxTriggerType = AD_POPUP, + kMaxTriggerType = AD_REDIRECT, }; struct TriggerTypeHash {
diff --git a/components/safe_browsing/triggers/trigger_util.h b/components/safe_browsing/triggers/trigger_util.h index 61d44ea..98babba1 100644 --- a/components/safe_browsing/triggers/trigger_util.h +++ b/components/safe_browsing/triggers/trigger_util.h
@@ -19,6 +19,7 @@ // Ad, or the |frame_url| is a Google Ad URL. bool DetectGoogleAd(content::RenderFrameHost* render_frame_host, const GURL& frame_url); + } // namespace safe_browsing #endif // COMPONENTS_SAFE_BROWSING_TRIGGERS_TRIGGER_UTIL_H_
diff --git a/components/security_interstitials/content/unsafe_resource.cc b/components/security_interstitials/content/unsafe_resource.cc index ae046912..a22e6bef 100644 --- a/components/security_interstitials/content/unsafe_resource.cc +++ b/components/security_interstitials/content/unsafe_resource.cc
@@ -47,6 +47,7 @@ case safe_browsing::SB_THREAT_TYPE_URL_CLIENT_SIDE_MALWARE: // Malicious ad activity reporting happens in the background. case safe_browsing::SB_THREAT_TYPE_BLOCKED_AD_POPUP: + case safe_browsing::SB_THREAT_TYPE_BLOCKED_AD_REDIRECT: // Ad sampling happens in the background. case safe_browsing::SB_THREAT_TYPE_AD_SAMPLE: // Sign-in password reuse warning happens after the page is finished
diff --git a/components/sync_bookmarks/bookmark_change_processor.cc b/components/sync_bookmarks/bookmark_change_processor.cc index b12124d..b8ca5af 100644 --- a/components/sync_bookmarks/bookmark_change_processor.cc +++ b/components/sync_bookmarks/bookmark_change_processor.cc
@@ -628,12 +628,11 @@ return; } } - for (int i = dst->child_count() - 1; i >= 0; --i) { - model->Move(dst->GetChild(i), foster_parent, + while (!dst->children().empty()) { + model->Move(dst->children().back().get(), foster_parent, foster_parent->children().size()); } } - DCHECK_EQ(dst->child_count(), 0) << "Node being deleted has children"; model_associator_->Disassociate(it->id); @@ -739,7 +738,7 @@ // Clean up the temporary node. if (foster_parent) { // There should be no nodes left under the foster parent. - DCHECK_EQ(foster_parent->child_count(), 0); + DCHECK(foster_parent->children().empty()); model->Remove(foster_parent); foster_parent = nullptr; }
diff --git a/components/sync_bookmarks/bookmark_model_associator.cc b/components/sync_bookmarks/bookmark_model_associator.cc index 4c5c0d0d..103c7f56 100644 --- a/components/sync_bookmarks/bookmark_model_associator.cc +++ b/components/sync_bookmarks/bookmark_model_associator.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "base/containers/adapters.h" #include "base/format_macros.h" #include "base/location.h" #include "base/single_thread_task_runner.h" @@ -127,13 +128,10 @@ BookmarkNodeFinder::BookmarkNodeFinder(const BookmarkNode* parent_node) : parent_node_(parent_node) { - for (int i = 0; i < parent_node_->child_count(); ++i) { - const BookmarkNode* child_node = parent_node_->GetChild(i); - + for (const auto& child_node : parent_node_->children()) { std::string title = base::UTF16ToUTF8(child_node->GetTitle()); ConvertTitleToSyncInternalFormat(title, &title); - - child_nodes_.insert(std::make_pair(title, child_node)); + child_nodes_.insert(std::make_pair(title, child_node.get())); } } @@ -541,17 +539,12 @@ int BookmarkModelAssociator::GetTotalBookmarkCountAndRecordDuplicates( const bookmarks::BookmarkNode* node, Context* context) const { - int count = 1; // Start with one to include the node itself. - - if (!node->is_root()) { + if (!node->is_root()) context->UpdateDuplicateCount(node->GetTitle(), node->url()); - } - for (int i = 0; i < node->child_count(); ++i) { - count += - GetTotalBookmarkCountAndRecordDuplicates(node->GetChild(i), context); - } - + int count = 1; // Start with one to include the node itself. + for (const auto& child : node->children()) + count += GetTotalBookmarkCountAndRecordDuplicates(child.get(), context); return count; } @@ -826,11 +819,11 @@ // Enumerate folder children in reverse order to make it easier to remove // bookmarks matching entries in the delete journal. - for (int child_index = parent->child_count() - 1; - child_index >= 0 && num_journals_unmatched > 0; --child_index) { - const BookmarkNode* child = parent->GetChild(child_index); + for (const auto& child : base::Reversed(parent->children())) { + if (num_journals_unmatched == 0) + break; if (child->is_folder()) - dfs_stack.push(child); + dfs_stack.push(child.get()); if (journaled_external_ids.find(child->id()) == journaled_external_ids.end()) { @@ -848,16 +841,16 @@ bk_delete_journals[journal_index]; if (child->id() == delete_entry.external_id && BookmarkNodeFinder::NodeMatches( - child, GURL(delete_entry.specifics.bookmark().url()), + child.get(), GURL(delete_entry.specifics.bookmark().url()), delete_entry.specifics.bookmark().title(), delete_entry.is_folder)) { if (child->is_folder()) { // Remember matched folder without removing and delete only empty // ones later. folders_matched.push_back( - FolderInfo(child, parent, delete_entry.id)); + FolderInfo(child.get(), parent, delete_entry.id)); } else { - bookmark_model_->Remove(child); + bookmark_model_->Remove(child.get()); context->IncrementLocalItemsDeleted(); } // Move unmatched journal here and decrement counter. @@ -875,7 +868,7 @@ // Remove empty folders from bottom to top. for (auto it = folders_matched.rbegin(); it != folders_matched.rend(); ++it) { - if (it->folder->child_count() == 0) { + if (it->folder->children().empty()) { bookmark_model_->Remove(it->folder); context->IncrementLocalItemsDeleted(); } else {
diff --git a/components/sync_bookmarks/bookmark_model_merger.cc b/components/sync_bookmarks/bookmark_model_merger.cc index 6394150..ac2d40f 100644 --- a/components/sync_bookmarks/bookmark_model_merger.cc +++ b/components/sync_bookmarks/bookmark_model_merger.cc
@@ -98,15 +98,15 @@ size_t FindMatchingChildFor(const UpdateResponseData* remote_node, const bookmarks::BookmarkNode* local_parent, size_t search_starting_child_index) { - const EntityData& remote_node_update_entity = *remote_node->entity; - for (int i = search_starting_child_index; i < local_parent->child_count(); - ++i) { - const bookmarks::BookmarkNode* local_child = local_parent->GetChild(i); - if (NodesMatch(local_child, remote_node_update_entity)) { - return i; - } - } - return kInvalidIndex; + const auto& children = local_parent->children(); + DCHECK_LE(search_starting_child_index, children.size()); + const EntityData& remote_entity = *remote_node->entity; + const auto it = + std::find_if(children.cbegin() + search_starting_child_index, + children.cend(), [&remote_entity](const auto& child) { + return NodesMatch(child.get(), remote_entity); + }); + return (it == children.cend()) ? kInvalidIndex : (it - children.cbegin()); } bool UniquePositionLessThan(const UpdateResponseData* a,
diff --git a/components/sync_bookmarks/bookmark_model_merger_unittest.cc b/components/sync_bookmarks/bookmark_model_merger_unittest.cc index 4fa2865..54cdd44 100644 --- a/components/sync_bookmarks/bookmark_model_merger_unittest.cc +++ b/components/sync_bookmarks/bookmark_model_merger_unittest.cc
@@ -82,25 +82,25 @@ bool PositionsInTrackerMatchModel(const bookmarks::BookmarkNode* node, const SyncedBookmarkTracker& tracker) { - if (node->child_count() == 0) { + if (node->children().empty()) { return true; } - syncer::UniquePosition pos = PositionOf(node->GetChild(0), tracker); - for (int i = 1; i < node->child_count(); ++i) { - if (PositionOf(node->GetChild(i), tracker).LessThan(pos)) { - DLOG(ERROR) << "Position of " << node->GetChild(i)->GetTitle() + syncer::UniquePosition last_pos = PositionOf(node->GetChild(0), tracker); + for (size_t i = 1; i < node->children().size(); ++i) { + syncer::UniquePosition pos = PositionOf(node->children()[i].get(), tracker); + if (pos.LessThan(last_pos)) { + DLOG(ERROR) << "Position of " << node->children()[i]->GetTitle() << " is less than position of " - << node->GetChild(i - 1)->GetTitle(); + << node->children()[i - 1]->GetTitle(); return false; } - pos = PositionOf(node->GetChild(i), tracker); + last_pos = pos; } - for (int i = 0; i < node->child_count(); ++i) { - if (!PositionsInTrackerMatchModel(node->GetChild(i), tracker)) { - return false; - } - } - return true; + return std::all_of(node->children().cbegin(), node->children().cend(), + [&tracker](const auto& child) { + return PositionsInTrackerMatchModel(child.get(), + tracker); + }); } } // namespace @@ -232,12 +232,12 @@ BookmarkModelMerger(&updates, bookmark_model.get(), &favicon_service, &tracker) .Merge(); - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(3)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(3u)); // Verify Folder 1. EXPECT_THAT(bookmark_bar_node->GetChild(0)->GetTitle(), Eq(base::ASCIIToUTF16(kFolder1Title))); - ASSERT_THAT(bookmark_bar_node->GetChild(0)->child_count(), Eq(3)); + ASSERT_THAT(bookmark_bar_node->GetChild(0)->children().size(), Eq(3u)); EXPECT_THAT(bookmark_bar_node->GetChild(0)->GetChild(0)->GetTitle(), Eq(base::ASCIIToUTF16(kUrl1Title))); @@ -257,7 +257,7 @@ // Verify Folder 3. EXPECT_THAT(bookmark_bar_node->GetChild(1)->GetTitle(), Eq(base::ASCIIToUTF16(kFolder3Title))); - ASSERT_THAT(bookmark_bar_node->GetChild(1)->child_count(), Eq(2)); + ASSERT_THAT(bookmark_bar_node->GetChild(1)->children().size(), Eq(2u)); EXPECT_THAT(bookmark_bar_node->GetChild(1)->GetChild(0)->GetTitle(), Eq(base::ASCIIToUTF16(kUrl3Title))); @@ -271,7 +271,7 @@ // Verify Folder 2. EXPECT_THAT(bookmark_bar_node->GetChild(2)->GetTitle(), Eq(base::ASCIIToUTF16(kFolder2Title))); - ASSERT_THAT(bookmark_bar_node->GetChild(2)->child_count(), Eq(2)); + ASSERT_THAT(bookmark_bar_node->GetChild(2)->children().size(), Eq(2u)); EXPECT_THAT(bookmark_bar_node->GetChild(2)->GetChild(0)->GetTitle(), Eq(base::ASCIIToUTF16(kUrl3Title))); @@ -380,7 +380,7 @@ BookmarkModelMerger(&updates, bookmark_model.get(), &favicon_service, &tracker) .Merge(); - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(3)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(3u)); EXPECT_THAT(bookmark_bar_node->GetChild(0)->GetTitle(), Eq(base::ASCIIToUTF16(kFolder1Title))); @@ -493,7 +493,7 @@ // Both titles should have matched against each other and only node is in the // model and the tracker. - EXPECT_THAT(bookmark_bar_node->child_count(), Eq(1)); + EXPECT_THAT(bookmark_bar_node->children().size(), Eq(1u)); EXPECT_THAT(tracker.TrackedEntitiesCountForTest(), Eq(2U)); } @@ -545,7 +545,7 @@ // Both titles should have matched against each other and only node is in the // model and the tracker. - EXPECT_THAT(bookmark_bar_node->child_count(), Eq(1)); + EXPECT_THAT(bookmark_bar_node->children().size(), Eq(1u)); EXPECT_THAT(tracker.TrackedEntitiesCountForTest(), Eq(2U)); }
diff --git a/components/sync_bookmarks/bookmark_model_observer_impl.cc b/components/sync_bookmarks/bookmark_model_observer_impl.cc index efb08761..6622ffc 100644 --- a/components/sync_bookmarks/bookmark_model_observer_impl.cc +++ b/components/sync_bookmarks/bookmark_model_observer_impl.cc
@@ -137,13 +137,10 @@ void BookmarkModelObserverImpl::OnWillRemoveAllUserBookmarks( bookmarks::BookmarkModel* model) { const bookmarks::BookmarkNode* root_node = model->root_node(); - for (int i = 0; i < root_node->child_count(); ++i) { - const bookmarks::BookmarkNode* permanent_node = root_node->GetChild(i); - for (int j = permanent_node->child_count() - 1; j >= 0; --j) { - if (!model->client()->CanSyncNode(permanent_node->GetChild(j))) { - continue; - } - ProcessDelete(permanent_node, permanent_node->GetChild(j)); + for (const auto& permanent_node : root_node->children()) { + for (const auto& child : permanent_node->children()) { + if (model->client()->CanSyncNode(child.get())) + ProcessDelete(permanent_node.get(), child.get()); } } nudge_for_commit_closure_.Run(); @@ -249,12 +246,9 @@ // 4. Sort the middle, using Between (e.g. recursive implementation). syncer::UniquePosition position; - syncer::UniquePosition previous_position; - for (int i = 0; i < node->child_count(); ++i) { - const bookmarks::BookmarkNode* child = node->GetChild(i); - + for (const auto& child : node->children()) { const SyncedBookmarkTracker::Entity* entity = - bookmark_tracker_->GetEntityForBookmarkNode(child); + bookmark_tracker_->GetEntityForBookmarkNode(child.get()); DCHECK(entity); const std::string& sync_id = entity->metadata()->server_id(); @@ -262,13 +256,9 @@ bookmark_tracker_->model_type_state().cache_guid(), sync_id); const base::Time modification_time = base::Time::Now(); - if (i == 0) { - position = syncer::UniquePosition::InitialPosition(suffix); - } else { - position = syncer::UniquePosition::After(previous_position, suffix); - } - - previous_position = position; + position = (child == node->children().front()) + ? syncer::UniquePosition::InitialPosition(suffix) + : syncer::UniquePosition::After(position, suffix); const sync_pb::EntitySpecifics specifics = CreateSpecificsFromBookmarkNode( node, model, /*force_favicon_load=*/true); @@ -287,7 +277,7 @@ const std::string& sync_id) { const std::string& suffix = syncer::GenerateSyncableBookmarkHash( bookmark_tracker_->model_type_state().cache_guid(), sync_id); - DCHECK_NE(0, parent.child_count()); + DCHECK(!parent.children().empty()); const SyncedBookmarkTracker::Entity* predecessor_entity = nullptr; const SyncedBookmarkTracker::Entity* successor_entity = nullptr; @@ -347,10 +337,8 @@ const bookmarks::BookmarkNode* parent, const bookmarks::BookmarkNode* node) { // If not a leaf node, process all children first. - for (int i = 0; i < node->child_count(); ++i) { - const bookmarks::BookmarkNode* child = node->GetChild(i); - ProcessDelete(node, child); - } + for (const auto& child : node->children()) + ProcessDelete(node, child.get()); // Process the current node. const SyncedBookmarkTracker::Entity* entity = bookmark_tracker_->GetEntityForBookmarkNode(node);
diff --git a/components/sync_bookmarks/bookmark_model_type_processor.cc b/components/sync_bookmarks/bookmark_model_type_processor.cc index 9715dfc..0da0e33 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor.cc +++ b/components/sync_bookmarks/bookmark_model_type_processor.cc
@@ -535,11 +535,9 @@ all_nodes->Append(std::move(root_node)); const bookmarks::BookmarkNode* model_root_node = bookmark_model_->root_node(); - for (int i = 0; i < model_root_node->child_count(); ++i) { - const bookmarks::BookmarkNode* model_permanent_node = - model_root_node->GetChild(i); - AppendNodeAndChildrenForDebugging(model_permanent_node, i, all_nodes.get()); - } + int i = 0; + for (const auto& child : model_root_node->children()) + AppendNodeAndChildrenForDebugging(child.get(), i++, all_nodes.get()); std::move(callback).Run(syncer::BOOKMARKS, std::move(all_nodes)); } @@ -605,9 +603,9 @@ data_dictionary->SetString("modelType", "Bookmarks"); all_nodes->Append(std::move(data_dictionary)); - for (int i = 0; i < node->child_count(); ++i) { - AppendNodeAndChildrenForDebugging(node->GetChild(i), i, all_nodes); - } + int i = 0; + for (const auto& child : node->children()) + AppendNodeAndChildrenForDebugging(child.get(), i++, all_nodes); } void BookmarkModelTypeProcessor::GetStatusCountersForDebugging(
diff --git a/components/sync_bookmarks/bookmark_remote_updates_handler.cc b/components/sync_bookmarks/bookmark_remote_updates_handler.cc index 29fac16..cac4fea 100644 --- a/components/sync_bookmarks/bookmark_remote_updates_handler.cc +++ b/components/sync_bookmarks/bookmark_remote_updates_handler.cc
@@ -626,10 +626,8 @@ DCHECK(entity); bookmark_tracker_->Remove(entity->metadata()->server_id()); - for (int i = 0; i < node->child_count(); ++i) { - const bookmarks::BookmarkNode* child = node->GetChild(i); - RemoveEntityAndChildrenFromTracker(child); - } + for (const auto& child : node->children()) + RemoveEntityAndChildrenFromTracker(child.get()); } const bookmarks::BookmarkNode* BookmarkRemoteUpdatesHandler::GetParentNode(
diff --git a/components/sync_bookmarks/bookmark_remote_updates_handler_unittest.cc b/components/sync_bookmarks/bookmark_remote_updates_handler_unittest.cc index 57fa918..241401f 100644 --- a/components/sync_bookmarks/bookmark_remote_updates_handler_unittest.cc +++ b/components/sync_bookmarks/bookmark_remote_updates_handler_unittest.cc
@@ -273,20 +273,16 @@ // All nodes should have been added to the model. const bookmarks::BookmarkNode* bookmark_bar_node = bookmark_model()->bookmark_bar_node(); - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(1)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(1u)); EXPECT_THAT(bookmark_bar_node->GetChild(0)->GetTitle(), Eq(ASCIIToUTF16(kId0))); - ASSERT_THAT(bookmark_bar_node->GetChild(0)->child_count(), Eq(1)); - EXPECT_THAT(bookmark_bar_node->GetChild(0)->GetChild(0)->GetTitle(), - Eq(ASCIIToUTF16(kId1))); - ASSERT_THAT(bookmark_bar_node->GetChild(0)->GetChild(0)->child_count(), - Eq(1)); - EXPECT_THAT( - bookmark_bar_node->GetChild(0)->GetChild(0)->GetChild(0)->GetTitle(), - Eq(ASCIIToUTF16(kId2))); - EXPECT_THAT( - bookmark_bar_node->GetChild(0)->GetChild(0)->GetChild(0)->child_count(), - Eq(0)); + ASSERT_THAT(bookmark_bar_node->GetChild(0)->children().size(), Eq(1u)); + const bookmarks::BookmarkNode* grandchild = + bookmark_bar_node->GetChild(0)->GetChild(0); + EXPECT_THAT(grandchild->GetTitle(), Eq(ASCIIToUTF16(kId1))); + ASSERT_THAT(grandchild->children().size(), Eq(1u)); + EXPECT_THAT(grandchild->GetChild(0)->GetTitle(), Eq(ASCIIToUTF16(kId2))); + EXPECT_THAT(grandchild->GetChild(0)->children().size(), Eq(0u)); } TEST_F(BookmarkRemoteUpdatesHandlerWithInitialMergeTest, @@ -382,7 +378,7 @@ // All nodes should have been added to the model in the correct order. const bookmarks::BookmarkNode* bookmark_bar_node = bookmark_model()->bookmark_bar_node(); - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(3)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(3u)); EXPECT_THAT(bookmark_bar_node->GetChild(0)->GetTitle(), Eq(ASCIIToUTF16(kId0))); EXPECT_THAT(bookmark_bar_node->GetChild(1)->GetTitle(), @@ -422,7 +418,7 @@ /*got_new_encryption_requirements=*/false); const bookmarks::BookmarkNode* bookmark_bar_node = bookmark_model()->bookmark_bar_node(); - EXPECT_THAT(bookmark_bar_node->child_count(), Eq(5)); + EXPECT_THAT(bookmark_bar_node->children().size(), Eq(5u)); // Change it to this structure by moving node3 after node1. // bookmark_bar @@ -446,7 +442,7 @@ /*got_new_encryption_requirements=*/false); // Model should have been updated. - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(5)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(5u)); EXPECT_THAT(bookmark_bar_node->GetChild(2)->GetTitle(), Eq(ASCIIToUTF16(ids[3]))); } @@ -482,7 +478,7 @@ /*got_new_encryption_requirements=*/false); const bookmarks::BookmarkNode* bookmark_bar_node = bookmark_model()->bookmark_bar_node(); - EXPECT_THAT(bookmark_bar_node->child_count(), Eq(5)); + EXPECT_THAT(bookmark_bar_node->children().size(), Eq(5u)); // Change it to this structure by moving node1 after node3. // bookmark_bar @@ -506,7 +502,7 @@ /*got_new_encryption_requirements=*/false); // Model should have been updated. - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(5)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(5u)); EXPECT_THAT(bookmark_bar_node->GetChild(3)->GetTitle(), Eq(ASCIIToUTF16(ids[1]))); } @@ -542,7 +538,7 @@ /*got_new_encryption_requirements=*/false); const bookmarks::BookmarkNode* bookmark_bar_node = bookmark_model()->bookmark_bar_node(); - EXPECT_THAT(bookmark_bar_node->child_count(), Eq(5)); + EXPECT_THAT(bookmark_bar_node->children().size(), Eq(5u)); // Change it to this structure by moving node4 under node1. // bookmark_bar @@ -566,8 +562,8 @@ /*got_new_encryption_requirements=*/false); // Model should have been updated. - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(4)); - ASSERT_THAT(bookmark_bar_node->GetChild(1)->child_count(), Eq(1)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(4u)); + ASSERT_THAT(bookmark_bar_node->GetChild(1)->children().size(), Eq(1u)); EXPECT_THAT(bookmark_bar_node->GetChild(1)->GetChild(0)->GetTitle(), Eq(ASCIIToUTF16(ids[4]))); } @@ -810,12 +806,12 @@ // The bookmark has been added and tracked. const bookmarks::BookmarkNode* bookmark_bar_node = bookmark_model->bookmark_bar_node(); - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(1)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(1u)); ASSERT_THAT(tracker.GetEntityForSyncId(kId), NotNull()); // Remove the bookmark from the local bookmark model. bookmark_model->Remove(bookmark_bar_node->GetChild(0)); - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(0)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(0u)); // Mark the entity as deleted locally. tracker.MarkDeleted(/*sync_id=*/kId); @@ -898,11 +894,11 @@ ASSERT_THAT(tracker()->GetEntityForSyncId(kId)->IsUnsynced(), Eq(false)); const bookmarks::BookmarkNode* bookmark_bar_node = bookmark_model()->bookmark_bar_node(); - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(1)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(1u)); // Remove the bookmark from the local bookmark model. bookmark_model()->Remove(bookmark_bar_node->GetChild(0)); - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(0)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(0u)); // Mark the entity as deleted locally. tracker()->MarkDeleted(/*sync_id=*/kId); @@ -929,7 +925,7 @@ // removing local entity since both changes. EXPECT_THAT(tracker()->GetEntityForSyncId(kId), IsNull()); // Make sure the bookmark hasn't been resurrected. - EXPECT_THAT(bookmark_bar_node->child_count(), Eq(0)); + EXPECT_THAT(bookmark_bar_node->children().size(), Eq(0u)); histogram_tester.ExpectBucketCount( "Sync.ResolveConflict", @@ -983,7 +979,7 @@ EXPECT_THAT(tracker()->GetEntityForSyncId(kId)->IsUnsynced(), Eq(true)); const bookmarks::BookmarkNode* bookmark_bar_node = bookmark_model()->bookmark_bar_node(); - EXPECT_THAT(bookmark_bar_node->child_count(), Eq(1)); + EXPECT_THAT(bookmark_bar_node->children().size(), Eq(1u)); histogram_tester.ExpectBucketCount( "Sync.ResolveConflict", @@ -1013,11 +1009,11 @@ ASSERT_THAT(tracker()->GetEntityForSyncId(kId)->IsUnsynced(), Eq(false)); const bookmarks::BookmarkNode* bookmark_bar_node = bookmark_model()->bookmark_bar_node(); - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(1)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(1u)); // Remove the bookmark from the local bookmark model. bookmark_model()->Remove(bookmark_bar_node->GetChild(0)); - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(0)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(0u)); // Mark the entity as deleted locally. tracker()->MarkDeleted(/*sync_id=*/kId); @@ -1047,7 +1043,7 @@ Eq(false)); // The bookmark should have been resurrected. - EXPECT_THAT(bookmark_bar_node->child_count(), Eq(1)); + EXPECT_THAT(bookmark_bar_node->children().size(), Eq(1u)); histogram_tester.ExpectBucketCount( "Sync.ResolveConflict", @@ -1152,7 +1148,7 @@ EXPECT_THAT(tracker()->GetEntityForSyncId(kId)->IsUnsynced(), Eq(false)); const bookmarks::BookmarkNode* bookmark_bar_node = bookmark_model()->bookmark_bar_node(); - ASSERT_THAT(bookmark_bar_node->child_count(), Eq(1)); + ASSERT_THAT(bookmark_bar_node->children().size(), Eq(1u)); EXPECT_THAT(bookmark_bar_node->GetChild(0)->GetTitle(), Eq(ASCIIToUTF16(kNewRemoteTitle)));
diff --git a/components/sync_bookmarks/synced_bookmark_tracker.cc b/components/sync_bookmarks/synced_bookmark_tracker.cc index 40636dd0..5f3edc8 100644 --- a/components/sync_bookmarks/synced_bookmark_tracker.cc +++ b/components/sync_bookmarks/synced_bookmark_tracker.cc
@@ -424,9 +424,8 @@ // Remove those who are direct children of another node. for (const SyncedBookmarkTracker::Entity* entity : entities) { const bookmarks::BookmarkNode* node = entity->bookmark_node(); - for (int i = 0; i < node->child_count(); ++i) { - nodes.erase(node->GetChild(i)); - } + for (const auto& child : node->children()) + nodes.erase(child.get()); } // |nodes| contains only roots of all trees in the forest all of which are // ready to be processed because their parents have no pending updates. @@ -446,10 +445,9 @@ DCHECK(!entity->metadata()->is_deleted()); ordered_entities->push_back(entity); // Recurse for all children. - for (int i = 0; i < node->child_count(); ++i) { - const bookmarks::BookmarkNode* child = node->GetChild(i); + for (const auto& child : node->children()) { const SyncedBookmarkTracker::Entity* child_entity = - GetEntityForBookmarkNode(child); + GetEntityForBookmarkNode(child.get()); DCHECK(child_entity); if (!child_entity->IsUnsynced()) { // If the entity has no local change, no need to check its children. If @@ -464,7 +462,7 @@ // added later. continue; } - TraverseAndAppend(child, ordered_entities); + TraverseAndAppend(child.get(), ordered_entities); } }
diff --git a/components/test/data/autofill/heuristics/input/157_bug_971402_opentable_checkout.html b/components/test/data/autofill/heuristics/input/157_bug_971402_opentable_checkout.html new file mode 100644 index 0000000..1e77c1b --- /dev/null +++ b/components/test/data/autofill/heuristics/input/157_bug_971402_opentable_checkout.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html lang="en-US"> +<fieldset class="sc-hgHYgh lhrbby sc-iGPElx eAzJBS" aria-label="Credit Card Information"> + <div> + <legend class="sc-jeCdPy dahPyF">Credit Card Required</legend> + <p class="sc-bGbJRg kZFiqY">Campton Place requires a credit card for all dinner reservations. Kindly note that + a charge for cancellations that are made within 48 hours of your reservation will be $100 per person.</p><button + class="sc-bEjcJn bFhkkA" type="button" aria-expanded="false" aria-controls="creditCardTerms">Show terms</button> + <div class="sc-likbZx iaAhzB" id="creditCardTerms" aria-expanded="false" style="opacity: 0; height: 0px; margin-bottom: 0px;"> + <div class="sc-ePZHVD cGrllf"> + <p>Campton Place requires a credit card for all dinner reservations. Kindly note that a charge for + cancellations that are made within 48 hours of your reservation will be $100 per person.</p> + <p>Online modifications can be made until 5pm on June 11, 2019. Any modifications or cancellations + after 5pm on June 11, 2019 will require you to contact the restaurant directly and are held to the + restaurant's policy and may be subject to fees.</p> + </div> + </div> + </div> + <div class="sc-caSCKo iMlxXu"><input class="sc-hzDEsm vxwLV sc-eqIVtm jsKnUL" type="text" required="" aria-required="true" + name="creditCardName" placeholder="Name on card" aria-label="Name on card" autocomplete="cc-name" value=""> + <div class="sc-gisBJw jCigBZ"></div> + </div> + <div class="sc-caSCKo iMlxXu"><input type="text" class="sc-hzDEsm vxwLV sc-dVhcbM hxItjU" required="" aria-required="true" + name="creditCardNumber" placeholder="Credit card number" aria-label="Credit card number" autocomplete="cc-number" + value=""> + <div class="sc-gisBJw jCigBZ"></div> + </div> + <div class="sc-gtfDJT eTsJUg"> + <div class="sc-caSCKo iMlxXu"><input type="text" class="sc-hzDEsm vxwLV sc-dVhcbM hxItjU" required="" + aria-required="true" name="creditCardExpiry" placeholder="MM / YY" aria-label="MM / YY" autocomplete="cc-exp" + value=""> + <div class="sc-gisBJw jCigBZ"></div> + </div> + <div class="sc-caSCKo iMlxXu"><input type="text" class="sc-hzDEsm vxwLV sc-dVhcbM hxItjU" required="" + aria-required="true" name="creditCardCode" placeholder="CVC" aria-label="CVC" autocomplete="cc-csc" + value=""> + <div class="sc-gisBJw jCigBZ"></div> + </div> + </div> +</fieldset> +</body> + +</html> \ No newline at end of file
diff --git a/components/test/data/autofill/heuristics/output/157_bug_971402_opentable_checkout.out b/components/test/data/autofill/heuristics/output/157_bug_971402_opentable_checkout.out new file mode 100644 index 0000000..86323bf --- /dev/null +++ b/components/test/data/autofill/heuristics/output/157_bug_971402_opentable_checkout.out
@@ -0,0 +1,4 @@ +HTML_TYPE_CREDIT_CARD_NAME_FULL | creditCardName | Name on card | | credit-card-cc +HTML_TYPE_CREDIT_CARD_NUMBER | creditCardNumber | Credit card number | | credit-card-cc +CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR | creditCardExpiry | MM / YY | | credit-card-cc +HTML_TYPE_CREDIT_CARD_VERIFICATION_CODE | creditCardCode | CVC | | credit-card-cc
diff --git a/components/undo/bookmark_undo_service.cc b/components/undo/bookmark_undo_service.cc index e24a856..452f563 100644 --- a/components/undo/bookmark_undo_service.cc +++ b/components/undo/bookmark_undo_service.cc
@@ -293,9 +293,10 @@ const BookmarkNode* parent) : BookmarkUndoOperation(bookmark_model), parent_id_(parent->id()) { - ordered_bookmarks_.resize(parent->child_count()); - for (int i = 0; i < parent->child_count(); ++i) - ordered_bookmarks_[i] = parent->GetChild(i)->id(); + ordered_bookmarks_.resize(parent->children().size()); + std::transform(parent->children().cbegin(), parent->children().cend(), + ordered_bookmarks_.begin(), + [](const auto& child) { return child->id(); }); } BookmarkReorderOperation::~BookmarkReorderOperation() {
diff --git a/components/undo/bookmark_undo_service_test.cc b/components/undo/bookmark_undo_service_test.cc index 411f51f..d393b0b2 100644 --- a/components/undo/bookmark_undo_service_test.cc +++ b/components/undo/bookmark_undo_service_test.cc
@@ -74,7 +74,7 @@ // Undo bookmark creation and test for no bookmarks. undo_service->undo_manager()->Undo(); - EXPECT_EQ(0, model->other_node()->child_count()); + EXPECT_EQ(0u, model->other_node()->children().size()); // Redo bookmark creation and ensure bookmark information is valid. undo_service->undo_manager()->Redo(); @@ -97,7 +97,7 @@ // Undo the deletion of the only bookmark and check the bookmark values. undo_service->undo_manager()->Undo(); - EXPECT_EQ(1, model->other_node()->child_count()); + EXPECT_EQ(1u, model->other_node()->children().size()); const BookmarkNode* node = parent->GetChild(0); EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo")); EXPECT_EQ(node->url(), GURL("http://www.bar.com")); @@ -107,7 +107,7 @@ // Redo the deletion and check that there are no bookmarks left. undo_service->undo_manager()->Redo(); - EXPECT_EQ(0, model->other_node()->child_count()); + EXPECT_EQ(0u, model->other_node()->children().size()); EXPECT_EQ(2U, undo_service->undo_manager()->undo_count()); EXPECT_EQ(0U, undo_service->undo_manager()->redo_count()); @@ -133,14 +133,14 @@ // Undo the modification of the bookmark and check for the original values. undo_service->undo_manager()->Undo(); - EXPECT_EQ(1, model->other_node()->child_count()); + EXPECT_EQ(1u, model->other_node()->children().size()); const BookmarkNode* node = model->other_node()->GetChild(0); EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo")); EXPECT_EQ(node->url(), GURL("http://www.foo.com")); // Redo the modifications and ensure the newer values are present. undo_service->undo_manager()->Redo(); - EXPECT_EQ(1, model->other_node()->child_count()); + EXPECT_EQ(1u, model->other_node()->children().size()); node = model->other_node()->GetChild(0); EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar")); EXPECT_EQ(node->url(), GURL("http://www.bar.com")); @@ -204,20 +204,20 @@ // Undo the move and check that the bookmark and folder are in place. undo_service->undo_manager()->Undo(); - ASSERT_EQ(4, model->other_node()->child_count()); + ASSERT_EQ(4u, model->other_node()->children().size()); EXPECT_EQ(model->other_node()->GetChild(0), n1); EXPECT_EQ(model->other_node()->GetChild(1), n2); EXPECT_EQ(model->other_node()->GetChild(2), n3); EXPECT_EQ(model->other_node()->GetChild(3), f1); - EXPECT_EQ(0, f1->child_count()); + EXPECT_EQ(0u, f1->children().size()); // Redo the move back into the folder and check validity. undo_service->undo_manager()->Redo(); - ASSERT_EQ(3, model->other_node()->child_count()); + ASSERT_EQ(3u, model->other_node()->children().size()); EXPECT_EQ(model->other_node()->GetChild(0), n1); EXPECT_EQ(model->other_node()->GetChild(1), n2); EXPECT_EQ(model->other_node()->GetChild(2), f1); - ASSERT_EQ(1, f1->child_count()); + ASSERT_EQ(1u, f1->children().size()); EXPECT_EQ(f1->GetChild(0), n3); } @@ -236,8 +236,8 @@ // Undo the folder removal and ensure the folder and bookmark were restored. undo_service->undo_manager()->Undo(); - ASSERT_EQ(1, model->other_node()->child_count()); - ASSERT_EQ(1, model->other_node()->GetChild(0)->child_count()); + ASSERT_EQ(1u, model->other_node()->children().size()); + ASSERT_EQ(1u, model->other_node()->GetChild(0)->children().size()); const BookmarkNode* node = model->other_node()->GetChild(0); EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("Renamed")); @@ -253,18 +253,18 @@ // Undo bookmark creation and test for removal of bookmark. undo_service->undo_manager()->Undo(); - ASSERT_EQ(0, model->other_node()->GetChild(0)->child_count()); + ASSERT_EQ(0u, model->other_node()->GetChild(0)->children().size()); // Undo folder creation and confirm the bookmark model is empty. undo_service->undo_manager()->Undo(); - ASSERT_EQ(0, model->other_node()->child_count()); + ASSERT_EQ(0u, model->other_node()->children().size()); // Redo all the actions and ensure the folder and bookmark are restored. undo_service->undo_manager()->Redo(); // folder creation undo_service->undo_manager()->Redo(); // bookmark creation undo_service->undo_manager()->Redo(); // bookmark title change - ASSERT_EQ(1, model->other_node()->child_count()); - ASSERT_EQ(1, model->other_node()->GetChild(0)->child_count()); + ASSERT_EQ(1u, model->other_node()->children().size()); + ASSERT_EQ(1u, model->other_node()->GetChild(0)->children().size()); node = model->other_node()->GetChild(0); EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("Renamed")); node = model->other_node()->GetChild(0)->GetChild(0); @@ -272,7 +272,7 @@ EXPECT_EQ(node->url(), GURL("http://www.foo.com")); undo_service->undo_manager()->Redo(); // folder deletion - EXPECT_EQ(0, model->other_node()->child_count()); + EXPECT_EQ(0u, model->other_node()->children().size()); } // Test the undo of SortChildren and ReorderChildren. @@ -338,22 +338,22 @@ // bookmarks. undo_service->undo_manager()->Undo(); - ASSERT_EQ(2, model->other_node()->child_count()); - EXPECT_EQ(1, model->other_node()->GetChild(1)->child_count()); + ASSERT_EQ(2u, model->other_node()->children().size()); + EXPECT_EQ(1u, model->other_node()->GetChild(1)->children().size()); const BookmarkNode* node = model->other_node()->GetChild(1)->GetChild(0); EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar")); EXPECT_EQ(node->url(), GURL("http://www.bar.com")); - ASSERT_EQ(2, model->bookmark_bar_node()->child_count()); - EXPECT_EQ(1, model->bookmark_bar_node()->GetChild(1)->child_count()); + ASSERT_EQ(2u, model->bookmark_bar_node()->children().size()); + EXPECT_EQ(1u, model->bookmark_bar_node()->GetChild(1)->children().size()); node = model->bookmark_bar_node()->GetChild(1)->GetChild(0); EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("b")); EXPECT_EQ(node->url(), GURL("http://www.b.com")); // Test that the redo removes all folders and bookmarks. undo_service->undo_manager()->Redo(); - EXPECT_EQ(0, model->other_node()->child_count()); - EXPECT_EQ(0, model->bookmark_bar_node()->child_count()); + EXPECT_EQ(0u, model->other_node()->children().size()); + EXPECT_EQ(0u, model->bookmark_bar_node()->children().size()); } TEST_F(BookmarkUndoServiceTest, UndoRemoveFolderWithBookmarks) { @@ -371,9 +371,9 @@ // Test that the undo restores the bookmark and folder. undo_service->undo_manager()->Undo(); - ASSERT_EQ(1, model->other_node()->child_count()); + ASSERT_EQ(1u, model->other_node()->children().size()); new_folder = model->other_node()->GetChild(0); - EXPECT_EQ(1, new_folder->child_count()); + EXPECT_EQ(1u, new_folder->children().size()); const BookmarkNode* node = new_folder->GetChild(0); EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar")); EXPECT_EQ(node->url(), GURL("http://www.bar.com")); @@ -381,14 +381,14 @@ // Test that the redo restores the bookmark and folder. undo_service->undo_manager()->Redo(); - ASSERT_EQ(0, model->other_node()->child_count()); + ASSERT_EQ(0u, model->other_node()->children().size()); // Test that the undo after a redo restores the bookmark and folder. undo_service->undo_manager()->Undo(); - ASSERT_EQ(1, model->other_node()->child_count()); + ASSERT_EQ(1u, model->other_node()->children().size()); new_folder = model->other_node()->GetChild(0); - EXPECT_EQ(1, new_folder->child_count()); + EXPECT_EQ(1u, new_folder->children().size()); node = new_folder->GetChild(0); EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar")); EXPECT_EQ(node->url(), GURL("http://www.bar.com")); @@ -420,17 +420,17 @@ // Test that the undo restores the subfolders and their contents. undo_service->undo_manager()->Undo(); - ASSERT_EQ(1, model->other_node()->child_count()); + ASSERT_EQ(1u, model->other_node()->children().size()); const BookmarkNode* restored_new_folder = model->other_node()->GetChild(0); - EXPECT_EQ(2, restored_new_folder->child_count()); + EXPECT_EQ(2u, restored_new_folder->children().size()); const BookmarkNode* restored_sub_folder1 = restored_new_folder->GetChild(0); EXPECT_EQ(ASCIIToUTF16("subfolder1"), restored_sub_folder1->GetTitle()); - EXPECT_EQ(0, restored_sub_folder1->child_count()); + EXPECT_EQ(0u, restored_sub_folder1->children().size()); const BookmarkNode* restored_sub_folder2 = restored_new_folder->GetChild(1); EXPECT_EQ(ASCIIToUTF16("subfolder2"), restored_sub_folder2->GetTitle()); - EXPECT_EQ(1, restored_sub_folder2->child_count()); + EXPECT_EQ(1u, restored_sub_folder2->children().size()); const BookmarkNode* node = restored_sub_folder2->GetChild(0); EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("bar")); @@ -455,7 +455,7 @@ while (undo_service->undo_manager()->undo_count()) undo_service->undo_manager()->Undo(); - EXPECT_EQ(1, parent->child_count()); + EXPECT_EQ(1u, parent->children().size()); const BookmarkNode* node = model->other_node()->GetChild(0); EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("foo")); EXPECT_EQ(node->url(), GURL("http://www.foo.com"));
diff --git a/content/browser/browsing_instance.cc b/content/browser/browsing_instance.cc index 094629d..cfcf10a6 100644 --- a/content/browser/browsing_instance.cc +++ b/content/browser/browsing_instance.cc
@@ -110,14 +110,8 @@ // have multiple unisolated sites share a process. We don't use the default // instance when kProcessSharingWithStrictSiteInstances is enabled because in // that case we want each site to have their own SiteInstance object and logic - // elsewhere ensures that those SiteInstances share a process. We also don't - // use default SiteInstances when SiteInstance doesn't assign a site URL for - // |url|, since in that case the SiteInstance should remain unused, and a - // subsequent navigation should always be able to reuse it, whether or not - // it's to a site requiring a dedicated process or to a site that will use - // the default SiteInstance. + // elsewhere ensures that those SiteInstances share a process. if (allow_default_instance && !url.SchemeIs(kGuestScheme) && - SiteInstanceImpl::ShouldAssignSiteForURL(url) && !base::FeatureList::IsEnabled( features::kProcessSharingWithStrictSiteInstances) && !SiteInstanceImpl::DoesSiteRequireDedicatedProcess(isolation_context_,
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index c29790a3..433274e 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -2288,8 +2288,7 @@ params.source_site_instance = source_site_instance; params.load_type = method == "POST" ? LOAD_TYPE_HTTP_POST : LOAD_TYPE_DEFAULT; params.transition_type = page_transition; - params.frame_tree_node_id = - render_frame_host->frame_tree_node()->frame_tree_node_id(); + params.frame_tree_node_id = node->frame_tree_node_id(); params.referrer = referrer; /* params.redirect_chain: skip */ params.extra_headers = extra_headers; @@ -2313,15 +2312,15 @@ std::unique_ptr<NavigationRequest> request = CreateNavigationRequestFromLoadParams( - render_frame_host->frame_tree_node(), params, override_user_agent, - should_replace_current_entry, false /* has_user_gesture */, - download_policy, ReloadType::NONE, entry.get(), frame_entry.get()); + node, params, override_user_agent, should_replace_current_entry, + false /* has_user_gesture */, download_policy, ReloadType::NONE, + entry.get(), frame_entry.get()); if (!request) return; - render_frame_host->frame_tree_node()->navigator()->Navigate( - std::move(request), ReloadType::NONE, RestoreType::NONE); + node->navigator()->Navigate(std::move(request), ReloadType::NONE, + RestoreType::NONE); } void NavigationControllerImpl::SetSessionStorageNamespace(
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h index 282c7f2..a8e8866 100644 --- a/content/browser/frame_host/navigation_handle_impl.h +++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -175,8 +175,6 @@ return navigation_request_->navigation_ui_data(); } - const GURL& base_url() { return navigation_request_->base_url(); } - NavigationType navigation_type() { return navigation_request_->navigation_type(); }
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 2948001c..0c4d563 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -2706,7 +2706,6 @@ did_replace_entry_ = did_replace_entry; should_update_history_ = params.should_update_history; previous_url_ = previous_url; - base_url_ = params.base_url; navigation_type_ = navigation_type; // If an error page reloads, net_error_code might be 200 but we still want to
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index 0048ff7..e222663 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -375,8 +375,6 @@ return navigation_type_; } - const GURL& base_url() { return base_url_; } - bool did_replace_entry() const { DCHECK(handle_state_ == DID_COMMIT || handle_state_ == DID_COMMIT_ERROR_PAGE); @@ -868,9 +866,6 @@ // there was no last committed entry. GURL previous_url_; - // The base URL for the page's document when the frame was committed. - GURL base_url_; - // The type of navigation that just occurred. Note that not all types of // navigations in the enum are valid here, since some of them don't actually // cause a "commit" and won't generate this notification.
diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h index 26ca226..b9f50c4 100644 --- a/content/browser/frame_host/render_frame_host_delegate.h +++ b/content/browser/frame_host/render_frame_host_delegate.h
@@ -28,6 +28,7 @@ #include "services/device/public/mojom/geolocation_context.mojom.h" #include "services/device/public/mojom/wake_lock.mojom.h" #include "services/metrics/public/cpp/ukm_source_id.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" #include "third_party/blink/public/common/mediastream/media_stream_request.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom.h" #include "ui/base/window_open_disposition.h" @@ -104,8 +105,13 @@ // Notification from the renderer host that a suspicious navigation of the // main frame has been blocked. Allows the delegate to provide some UI to let // the user know about the blocked navigation and give them the option to - // recover from it. The given URL is the blocked navigation target. - virtual void OnDidBlockFramebust(const GURL& url) {} + // recover from it. + // |blocked_url| is the blocked navigation target, |initiator_url| is the URL + // of the frame initiating the navigation, |reason| specifies why the + // navigation was blocked. + virtual void OnDidBlockNavigation(const GURL& blocked_url, + const GURL& initiator_url, + blink::NavigationBlockedReason reason) {} // Gets the last committed URL. See WebContents::GetLastCommittedURL for a // description of the semantics.
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index cb17b89..0f1ea54 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -429,7 +429,7 @@ base::debug::SetCrashKeyString(site_url_key, site_url.spec()); } -base::Optional<url::Origin> GetOriginForURLLoaderFactory( +base::Optional<url::Origin> GetOriginForURLLoaderFactoryUnchecked( NavigationRequest* navigation_request) { // Return a safe unique origin when there is no |navigation_request| (e.g. // when RFHI::CommitNavigation is called via RFHI::NavigateToInterstitialURL). @@ -464,6 +464,13 @@ return url::Origin::Create(common_params.base_url_for_data_url); } + // MHTML frames should commit as unique origin (and should not be able to make + // network requests on behalf of the real origin). + // + // TODO(lukasza): Cover MHTML main frames here. + if (navigation_request->IsForMhtmlSubframe()) + return url::Origin(); + // TODO(lukasza, nasko): https://crbug.com/888079: Use exact origin, instead // of falling back to site URL for about:blank and about:srcdoc. if (common_params.url.SchemeIs(url::kAboutScheme)) { @@ -489,6 +496,23 @@ return url::Origin::Create(common_params.url); } +base::Optional<url::Origin> GetOriginForURLLoaderFactory( + NavigationRequest* navigation_request) { + base::Optional<url::Origin> result = + GetOriginForURLLoaderFactoryUnchecked(navigation_request); + + // Any non-opaque |result| must be an origin that is allowed to be accessed + // from the process that is the target of this navigation. + if (result.has_value() && !result->opaque()) { + auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); + CHECK(policy->CanAccessDataForOrigin( + navigation_request->render_frame_host()->GetProcess()->GetID(), + *result)); + } + + return result; +} + std::unique_ptr<blink::URLLoaderFactoryBundleInfo> CloneFactoryBundle( scoped_refptr<blink::URLLoaderFactoryBundle> bundle) { return base::WrapUnique(static_cast<blink::URLLoaderFactoryBundleInfo*>( @@ -1469,7 +1493,7 @@ IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeFrameOwnerProperties, OnDidChangeFrameOwnerProperties) IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateTitle, OnUpdateTitle) - IPC_MESSAGE_HANDLER(FrameHostMsg_DidBlockFramebust, OnDidBlockFramebust) + IPC_MESSAGE_HANDLER(FrameHostMsg_DidBlockNavigation, OnDidBlockNavigation) IPC_MESSAGE_HANDLER(FrameHostMsg_AbortNavigation, OnAbortNavigation) IPC_MESSAGE_HANDLER(FrameHostMsg_DispatchLoad, OnDispatchLoad) IPC_MESSAGE_HANDLER(FrameHostMsg_ForwardResourceTimingToParent, @@ -3180,8 +3204,11 @@ commit_callback_interceptor_ = interceptor; } -void RenderFrameHostImpl::OnDidBlockFramebust(const GURL& url) { - delegate_->OnDidBlockFramebust(url); +void RenderFrameHostImpl::OnDidBlockNavigation( + const GURL& blocked_url, + const GURL& initiator_url, + blink::NavigationBlockedReason reason) { + delegate_->OnDidBlockNavigation(blocked_url, initiator_url, reason); } void RenderFrameHostImpl::OnAbortNavigation() {
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index f4007e0..7feb38c 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -67,6 +67,7 @@ #include "services/service_manager/public/mojom/interface_provider.mojom.h" #include "services/viz/public/interfaces/hit_test/input_target_client.mojom.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/frame/user_activation_update_type.h" #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h" @@ -1136,7 +1137,9 @@ const FrameOwnerProperties& properties); void OnUpdateTitle(const base::string16& title, blink::WebTextDirection title_direction); - void OnDidBlockFramebust(const GURL& url); + void OnDidBlockNavigation(const GURL& blocked_url, + const GURL& initiator_url, + blink::NavigationBlockedReason reason); // Only used with PerNavigationMojoInterface disabled. void OnAbortNavigation(); void OnForwardResourceTimingToParent(
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc index 7d4cc74..dce01da 100644 --- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -64,7 +64,6 @@ #include "content/public/test/url_loader_interceptor.h" #include "content/shell/browser/shell.h" #include "content/test/content_browser_test_utils_internal.h" -#include "content/test/did_commit_navigation_interceptor.h" #include "content/test/test_content_browser_client.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/controllable_http_response.h" @@ -5727,8 +5726,7 @@ EXPECT_EQ(speculative_rph, web_contents->GetMainFrame()->GetProcess()); } -// ContentBrowserClient that skips assigning a site URL for all URLs that match -// a given URL's scheme and host. +// ContentBrowserClient that skips assigning a site URL for a given URL. class DontAssignSiteContentBrowserClient : public TestContentBrowserClient { public: // Any visit to |url_to_skip| will not cause the site to be assigned to the @@ -5737,8 +5735,7 @@ : url_to_skip_(url_to_skip) {} bool ShouldAssignSiteForURL(const GURL& url) override { - return url.host() != url_to_skip_.host() || - url.scheme() != url_to_skip_.scheme(); + return url != url_to_skip_; } private: @@ -5823,172 +5820,4 @@ SetBrowserClientForTesting(old_client); } -namespace { - -// A helper class to run a predefined callback just before processing the -// DidCommitProvisionalLoad IPC for |deferred_url|. -class CommitMessageDelayer : public DidCommitNavigationInterceptor { - public: - using DidCommitCallback = base::OnceCallback<void(RenderFrameHost*)>; - - explicit CommitMessageDelayer(WebContents* web_contents, - const GURL& deferred_url, - DidCommitCallback deferred_action) - : DidCommitNavigationInterceptor(web_contents), - deferred_url_(deferred_url), - deferred_action_(std::move(deferred_action)) {} - - void Wait() { - run_loop_.reset(new base::RunLoop()); - run_loop_->Run(); - run_loop_.reset(); - } - - private: - // DidCommitNavigationInterceptor: - bool WillProcessDidCommitNavigation( - RenderFrameHost* render_frame_host, - NavigationRequest* navigation_request, - ::FrameHostMsg_DidCommitProvisionalLoad_Params* params, - mojom::DidCommitProvisionalLoadInterfaceParamsPtr* interface_params) - override { - if (params->url == deferred_url_) { - std::move(deferred_action_).Run(render_frame_host); - if (run_loop_) - run_loop_->Quit(); - } - return true; - } - - std::unique_ptr<base::RunLoop> run_loop_; - - const GURL deferred_url_; - DidCommitCallback deferred_action_; - - DISALLOW_COPY_AND_ASSIGN(CommitMessageDelayer); -}; - -} // namespace - -// Check that when a navigation to a URL that doesn't require assigning a site -// URL is in progress, another navigation can't reuse the same process in the -// meantime. Such reuse previously led to a renderer kill when the siteless -// URL later committed; a real-world example of the siteless URL was -// chrome-native://newtab. See https://crbug.com/970046. -IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, - NavigationRacesWithCommitInUnassignedSiteInstance) { - ASSERT_TRUE(embedded_test_server()->Start()); - WebContentsImpl* web_contents = - static_cast<WebContentsImpl*>(shell()->web_contents()); - FrameTreeNode* root = web_contents->GetFrameTree()->root(); - - // Set up a URL for which ShouldAssignSiteForURL will return false. The - // corresponding SiteInstance's site will be left unassigned, and its process - // won't be locked. The test will navigate to this URL first. - GURL siteless_url( - embedded_test_server()->GetURL("siteless.com", "/title1.html")); - DontAssignSiteContentBrowserClient content_browser_client(siteless_url); - ContentBrowserClient* old_client = - SetBrowserClientForTesting(&content_browser_client); - - // Prepare for a second navigation to a normal URL. Ensure it's isolated so - // that it requires a process lock on all platforms. - GURL foo_url(embedded_test_server()->GetURL("foo.com", "/title1.html")); - TestNavigationManager foo_manager(web_contents, foo_url); - auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); - policy->AddIsolatedOrigins( - {url::Origin::Create(foo_url)}, - ChildProcessSecurityPolicy::IsolatedOriginSource::TEST); - RenderProcessHost* foo_process = nullptr; - base::HistogramTester histograms; - - // Set up the work to be done after the renderer is asked to commit - // |siteless_url|, but before the corresponding DidCommitProvisionalLoad IPC - // is processed. This will start a navigation to |foo_url| and wait for its - // response. - auto did_commit_callback = - base::BindLambdaForTesting([&](RenderFrameHost* rfh) { - // The navigation should stay in the initial empty SiteInstance, with - // the site still unassigned. - EXPECT_FALSE( - static_cast<SiteInstanceImpl*>(rfh->GetSiteInstance())->HasSite()); - EXPECT_FALSE(root->render_manager()->speculative_frame_host()); - - shell()->LoadURL(foo_url); - - // The foo.com navigation should swap to a new process, since it is not - // safe to reuse |siteless_url|'s process before |siteless_url| - // commits. - EXPECT_TRUE(root->render_manager()->speculative_frame_host()); - foo_process = - root->render_manager()->speculative_frame_host()->GetProcess(); - - // Wait for response. This will cause |foo_manager| to spin up a - // nested message loop while we're blocked in the current message loop - // (within DidCommitNavigationInterceptor). Thus, it's important to - // allow nestable tasks in |foo_manager|'s message loop, so that it can - // process the response before we unblock the - // DidCommitNavigationInterceptor's message loop and finish processing - // the commit. - foo_manager.AllowNestableTasks(); - EXPECT_TRUE(foo_manager.WaitForResponse()); - - foo_manager.ResumeNavigation(); - // After returning here, the commit for |siteless_url| will be - // processed. - }); - - CommitMessageDelayer commit_delayer(web_contents, - siteless_url /* deferred_url */, - std::move(did_commit_callback)); - - // Start the first navigation, which does not assign a site URL. - shell()->LoadURL(siteless_url); - - // The navigation should stay in the initial empty SiteInstance, so there - // shouldn't be a speculative RFH at this point. - EXPECT_FALSE(root->render_manager()->speculative_frame_host()); - - // Wait for the DidCommit IPC for |siteless_url|, and before processing it, - // trigger a navigation to |foo_url| and wait for its response. - commit_delayer.Wait(); - - // Check that the renderer hasn't been killed. At this point, it should've - // successfully committed the navigation to |siteless_url|, and it shouldn't - // be locked. - EXPECT_TRUE(web_contents->GetMainFrame()->IsRenderFrameLive()); - EXPECT_EQ(siteless_url, web_contents->GetMainFrame()->GetLastCommittedURL()); - RenderProcessHost* process1 = web_contents->GetMainFrame()->GetProcess(); - EXPECT_FALSE(web_contents->GetMainFrame()->GetSiteInstance()->HasSite()); - EXPECT_EQ(GURL(), policy->GetOriginLock(process1->GetID())); - - // Now wait for second navigation to finish and ensure it also succeeds. - foo_manager.WaitForNavigationFinished(); - EXPECT_TRUE(foo_manager.was_successful()); - EXPECT_TRUE(web_contents->GetMainFrame()->IsRenderFrameLive()); - EXPECT_EQ(foo_url, web_contents->GetMainFrame()->GetLastCommittedURL()); - - // The foo.com navigation should've used a different process, locked to - // foo.com. - RenderProcessHost* process2 = web_contents->GetMainFrame()->GetProcess(); - EXPECT_NE(process1, process2); - EXPECT_EQ(GURL("http://foo.com"), - web_contents->GetMainFrame()->GetSiteInstance()->GetSiteURL()); - EXPECT_EQ(GURL("http://foo.com"), policy->GetOriginLock(process2->GetID())); - - // Ensure also that the foo.com process didn't change midway through the - // navigation. - EXPECT_EQ(foo_process, process2); - - // Ensure we've logged the UMA for disallowing problematic process reuse. - // Since IsSuitableHost() is checked multiple times during a particular - // navigation, just make sure that this is logged at least once. - EXPECT_GE(histograms.GetBucketCount( - "SiteIsolation.PendingSitelessNavigationDisallowsProcessReuse", - 1 /* has_disqualifying_pending_navigation */), - 1); - - SetBrowserClientForTesting(old_client); -} - } // namespace content
diff --git a/content/browser/indexed_db/docs/open_and_verify_leveldb_database.code2flow b/content/browser/indexed_db/docs/open_and_verify_leveldb_database.code2flow index 6f3804ac0..bb2e241 100644 --- a/content/browser/indexed_db/docs/open_and_verify_leveldb_database.code2flow +++ b/content/browser/indexed_db/docs/open_and_verify_leveldb_database.code2flow
@@ -4,117 +4,109 @@ // open_and_verify_leveldb_database.pdf was created from this file by // https://www.code2flow.com/app -OpenOriginState; +function OpenLevelDB { + |Read free disk space|; + Histogram(FreeDiskSpace); + switch (leveldb_env::OpenDB) { + case Status Not OK:{ + Histogram(LevelDBOpenErrors); + if (disk space < 100kb) + Report disk space as failure reason; + return leveldb_env::OpenDB error status; + } + case Status OK: { + Histogram(LevelDB.OpenTime); + return Status::OK; + } + } +} + +OpenAndVerifyLevelDBDatabase; switch (Create IDB Directory) { case Failure: Histogram(FAILED_DIRECTORY); - return **IOError("Unable to create IndexedDB database path")**; + return IOError("Unable to create IndexedDB database path"); case Success: } Create File path & blob path; if (File Path is too long) { Histogram(ORIGIN_TOO_LONG); - return **IOError("File path too long)**; + return IOError("File path too long); } -open-loop-start: -Start; -switch(Read corruption info from disk) { - case Corruption Info Exists, - first open attempt: - Histogram(PRIOR_CORRUPTION); - case Corruption Info Exists, - NOT first open attempt: - switch (Destroy the database) { - case Success: - break; - case Failure: - goto open-loop-restart; - } +call OpenLevelDB; + +switch(OpenLevelDB status) { + case IOError: + Histogram(OPEN_NO_RECOVERY); + return OpenLevelDB error status; + case Corruption: + Set data loss info; break; - case No Corruption file found: + case OK: + if (Corruption Info Exists & Last Open was corrupt) { + Histogram(FAILED_PRIOR_CORRUPTION); + db_.reset(); + Populate data loss info + (previous corruption); + break; + } + switch (try to read schema) { + case Failure reading schema: + Histogram(FAILED_IO_ERROR_CHECKING_SCHEMA); + db_.reset(); + Populate data loss info + (schema checking failure); + break; + case Schema is unknown: + Histogram(FAILED_UNKNOWN_SCHEMA); + db_.reset(); + Populate data loss info + (unknown schema); + break; + case Success & Valid: + Histogram(OPEN_SUCCESS); + goto end; + } +} +switch(DestroyLevelDB(file_path)) { + case Not OK: + Histogram(CLEANUP_DESTROY_FAILED); + return DestroyLevelDB error status; + case OK: +} +call OpenLevelDB; +switch(OpenLevelDB status) { + case Not OK: + Histogram(CLEANUP_REOPEN_FAILED); + return OpenLevelDB error status; + case OK: + Histogram(CLEANUP_REOPEN_SUCCESS); } -block Open LevelDB { - |Read free disk space|; - switch (leveldb_env::OpenDB) { - case Status Not OK:{ - Histogram(LevelDBOpenErrors); - if (disk space < 100kb) { - goto error; - } - goto open-loop-restart; - } - case Status OK: { - Histogram(LevelDB.OpenTime); - } - } -} - -Create LevelDB Scopes; -switch (Initialize LevelDB Scopes) { +end: +Histogram(OPEN_SUCCESS); +block { +Create BackingStore; +switch (Parse schema & metadata) { case Failure: - Histogram(SCOPES); - goto open-loop-restart; + Delete Database & BackingStore; break; case Success: -} - -block Open LevelDBDatabase { - Create LevelDBDatabase; - switch (Try to read schema) { - case Corruption - - Failure reading schema: - Histogram(CHECKING_SCHEMA); - goto open-loop-restart; - case Corruption - - Schema is unknown: - Histogram(UNKNOWN_SCHEMA); - goto open-loop-restart; - case Success & Valid: + if (Should we clean blob journal?) { + switch(CleanUpBlobJournal) { + case OK: + report `Status::OK`; + goto done; + case Not OK: + Histogram(FAILED_CLEANUP_JOURNAL_ERROR); + return CleanUpBlobJournal error status; + } } } - -block Open IndexedDBBackingStore { - Create IndexedDBBackingStore; - switch (Parse schema & metadata) { - case Failure: - Histogram(SETUP_METADATA); - goto open-loop-restart; - break; - case Success: - if (Should we clean blob journal?) { - switch(CleanUpBlobJournal) { - case OK: - goto open-loop-end; - case Not OK: - |Histogram(CLEANUP_JOURNAL)|; - goto open-loop-restart; - } - } - goto open-loop-end; - } +return BackingStore error status; } -open-loop-restart: -|Cleanup from open failure|; -if (Was open failure - due to corruption?) { - Save corruption info to file; -} -if (Has 'Open' been - tried >=2 times?) { - goto error; -} -Go to start; -goto open-loop-start; - -open-loop-end: -if (Is database on disk - (instead of in memory)?) - |Histogram(OPEN_SUCCESS)|; -return **SUCCESS AND DONE**; - -error: -return **ERROR**; \ No newline at end of file +done: +return done; \ No newline at end of file
diff --git a/content/browser/indexed_db/docs/open_and_verify_leveldb_database.pdf b/content/browser/indexed_db/docs/open_and_verify_leveldb_database.pdf index 64a23ca..29ba7e5 100644 --- a/content/browser/indexed_db/docs/open_and_verify_leveldb_database.pdf +++ b/content/browser/indexed_db/docs/open_and_verify_leveldb_database.pdf Binary files differ
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc index 2f28916..b35db7e4 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -699,21 +699,17 @@ s = transaction->Commit(); if (!s.ok()) { - indexed_db::ReportOpenStatus( - indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_METADATA_SETUP, - origin_); INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA); return s; } - if (clean_live_journal) { + if (clean_live_journal) s = CleanUpBlobJournal(LiveBlobJournalKey::Encode()); - if (!s.ok()) { - indexed_db::ReportOpenStatus( - indexed_db:: - INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, - origin_); - } + if (!s.ok()) { + indexed_db::ReportOpenStatus( + indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, + origin_); + return s; } #if DCHECK_IS_ON() initialized_ = true;
diff --git a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc index 46f948a..2bbbe2ef 100644 --- a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc +++ b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
@@ -40,7 +40,6 @@ #include "storage/browser/test/mock_special_storage_policy.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" using base::ASCIIToUTF16; using blink::IndexedDBDatabaseMetadata; @@ -192,8 +191,7 @@ idb_factory_ = std::make_unique<TestIDBFactory>(idb_context_.get()); leveldb::Status s; - std::tie(origin_state_handle_, s, std::ignore, data_loss_info_, - std::ignore) = + std::tie(origin_state_handle_, s, std::ignore, std::ignore, std::ignore) = idb_factory_->GetOrOpenOriginFactory(origin, idb_context_->data_path()); if (!origin_state_handle_.IsHeld()) { backing_store_ = nullptr; @@ -228,7 +226,6 @@ IndexedDBOriginStateHandle origin_state_handle_; TestableIndexedDBBackingStore* backing_store_ = nullptr; - IndexedDBDataLossInfo data_loss_info_; // Sample keys and values that are consistent. IndexedDBKey key1_; @@ -1491,7 +1488,7 @@ // The factory returns a null backing store pointer when there is a corrupt // database. - EXPECT_TRUE(data_loss_info_.status == blink::mojom::IDBDataLoss::Total); + EXPECT_EQ(nullptr, backing_store()); } } // namespace indexed_db_backing_store_unittest
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index 60fe46a..f3c5c7e3 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -9,7 +9,6 @@ #include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/command_line.h" #include "base/files/file.h" #include "base/files/file_enumerator.h" @@ -31,9 +30,6 @@ #include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_factory_impl.h" -#include "content/browser/indexed_db/indexed_db_leveldb_coding.h" -#include "content/browser/indexed_db/indexed_db_origin_state.h" -#include "content/browser/indexed_db/indexed_db_origin_state_handle.h" #include "content/browser/indexed_db/leveldb/leveldb_env.h" #include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -230,21 +226,6 @@ return status; } - // Synchronously writes to the IndexedDB database at the given origin by - // posting a task to the idb task runner and waiting. - void WriteToIndexedDB(const Origin& origin, - std::string key, - std::string value) { - base::RunLoop loop; - GetContext()->TaskRunner()->PostTask( - FROM_HERE, - base::BindOnce(&IndexedDBBrowserTest::WriteToIndexedDBOnIDBSequence, - base::Unretained(this), - base::WrapRefCounted(GetContext()), origin, - std::move(key), std::move(value), loop.QuitClosure())); - loop.Run(); - } - protected: static MockBrowserTestIndexedDBClassFactory* GetTestClassFactory() { static ::base::LazyInstance<MockBrowserTestIndexedDBClassFactory>::Leaky @@ -261,32 +242,6 @@ } private: - void WriteToIndexedDBOnIDBSequence( - scoped_refptr<IndexedDBContextImpl> context, - const Origin& origin, - std::string key, - std::string value, - base::OnceClosure done) { - base::ScopedClosureRunner done_runner(std::move(done)); - IndexedDBOriginStateHandle handle; - leveldb::Status s; - std::tie(handle, s, std::ignore, std::ignore, std::ignore) = - context->GetIDBFactory()->GetOrOpenOriginFactory(origin, - context->data_path()); - CHECK(s.ok()) << s.ToString(); - CHECK(handle.IsHeld()); - - LevelDBDatabase* db = handle.origin_state()->backing_store()->db(); - s = db->Put(key, &value); - CHECK(s.ok()) << s.ToString(); - - // Force close to ensure a cold start on the next database open. - handle.origin_state()->ForceClose(); - handle.Release(); - CHECK(!context->GetIDBFactory()->IsBackingStoreOpen(origin)); - context.reset(); - } - DISALLOW_COPY_AND_ASSIGN(IndexedDBBrowserTest); }; @@ -381,28 +336,6 @@ incognito_browser->Close(); } -IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, NegativeDBSchemaVersion) { - const GURL database_open_url = GetTestUrl("indexeddb", "database_test.html"); - const Origin origin = Origin::Create(database_open_url); - // Create the database. - SimpleTest(database_open_url); - std::string value; - EncodeInt(-10, &value); - WriteToIndexedDB(origin, SchemaVersionKey::Encode(), value); - SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html")); -} - -IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, NegativeDBDataVersion) { - const GURL database_open_url = GetTestUrl("indexeddb", "database_test.html"); - const Origin origin = Origin::Create(database_open_url); - // Create the database. - SimpleTest(database_open_url); - std::string value; - EncodeInt(-10, &value); - WriteToIndexedDB(origin, DataVersionKey::Encode(), value); - SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html")); -} - class IndexedDBBrowserTestWithLowQuota : public IndexedDBBrowserTest { public: IndexedDBBrowserTestWithLowQuota() {}
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.cc b/content/browser/indexed_db/indexed_db_factory_impl.cc index e3fda74..9e47840d 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.cc +++ b/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -6,38 +6,31 @@ #include <stdint.h> -#include <tuple> #include <utility> #include <vector> #include "base/bind.h" #include "base/callback_helpers.h" #include "base/command_line.h" -#include "base/compiler_specific.h" #include "base/feature_list.h" #include "base/files/file_path.h" -#include "base/files/file_util.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/sequenced_task_runner.h" #include "base/stl_util.h" -#include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/timer/timer.h" #include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/indexed_db_connection.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" -#include "content/browser/indexed_db/indexed_db_data_format_version.h" #include "content/browser/indexed_db/indexed_db_database_error.h" #include "content/browser/indexed_db/indexed_db_leveldb_operations.h" #include "content/browser/indexed_db/indexed_db_metadata_coding.h" #include "content/browser/indexed_db/indexed_db_origin_state.h" #include "content/browser/indexed_db/indexed_db_pre_close_task_queue.h" -#include "content/browser/indexed_db/indexed_db_reporting.h" #include "content/browser/indexed_db/indexed_db_tombstone_sweeper.h" #include "content/browser/indexed_db/indexed_db_tracing.h" -#include "content/browser/indexed_db/leveldb/leveldb_database.h" #include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" #include "third_party/leveldatabase/env_chromium.h" @@ -47,7 +40,6 @@ namespace content { namespace { -constexpr static const int kNumOpenTries = 2; leveldb::Status GetDBSizeFromEnv(leveldb::Env* env, const std::string& path, @@ -82,69 +74,6 @@ " for indexedDB.open.")); } -// Creates the leveldb and blob storage directories for IndexedDB. -std::tuple<base::FilePath /*leveldb_path*/, - base::FilePath /*blob_path*/, - leveldb::Status> -CreateDatabaseDirectories(const base::FilePath& path_base, - const url::Origin& origin) { - leveldb::Status status; - if (!base::CreateDirectoryAndGetError(path_base, nullptr)) { - status = - leveldb::Status::IOError("Unable to create IndexedDB database path"); - LOG(ERROR) << status.ToString() << ": \"" << path_base.AsUTF8Unsafe() - << "\""; - ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY, - origin); - return {base::FilePath(), base::FilePath(), status}; - } - - base::FilePath leveldb_path = - path_base.Append(indexed_db::GetLevelDBFileName(origin)); - base::FilePath blob_path = - path_base.Append(indexed_db::GetBlobStoreFileName(origin)); - if (indexed_db::IsPathTooLong(leveldb_path)) { - ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, - origin); - status = leveldb::Status::IOError("File path too long"); - return {base::FilePath(), base::FilePath(), status}; - } - return {leveldb_path, blob_path, status}; -} - -std::tuple<bool, leveldb::Status> AreSchemasKnown(LevelDBDatabase* db) { - int64_t db_schema_version = 0; - bool found = false; - leveldb::Status s = indexed_db::GetInt(db, SchemaVersionKey::Encode(), - &db_schema_version, &found); - if (!s.ok()) - return {false, s}; - if (!found) { - return {true, s}; - } - if (db_schema_version < 0) - return {false, leveldb::Status::Corruption( - "Invalid IndexedDB database schema version.")}; - if (db_schema_version > indexed_db::kLatestKnownSchemaVersion) { - return {false, s}; - } - - int64_t raw_db_data_version = 0; - s = indexed_db::GetInt(db, DataVersionKey::Encode(), &raw_db_data_version, - &found); - if (!s.ok()) - return {false, s}; - if (!found) { - return {true, s}; - } - if (raw_db_data_version < 0) - return {false, - leveldb::Status::Corruption("Invalid IndexedDB data version.")}; - - return {IndexedDBDataFormatVersion::GetCurrent().IsAtLeast( - IndexedDBDataFormatVersion::Decode(raw_db_data_version)), - s}; -} } // namespace IndexedDBFactoryImpl::IndexedDBFactoryImpl( @@ -608,16 +537,10 @@ leveldb::Status, IndexedDBDatabaseError, IndexedDBDataLossInfo, - /*is_cold_open=*/bool> + bool> IndexedDBFactoryImpl::GetOrOpenOriginFactory( const Origin& origin, const base::FilePath& data_directory) { - IDB_TRACE("indexed_db::GetOrOpenOriginFactory"); - // Please see docs/open_and_verify_leveldb_database.code2flow, and the - // generated pdf (from https://code2flow.com). - // The intended strategy here is to have this function match that flowchart, - // where the flowchart should be seen as the 'master' logic template. Please - // check the git history of both to make sure they are in sync. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto it = factories_per_origin_.find(origin); if (it != factories_per_origin_.end()) { @@ -626,46 +549,25 @@ /*was_cold_open=*/false}; } - bool is_incognito_and_in_memory = data_directory.empty(); base::FilePath blob_path; base::FilePath database_path; - leveldb::Status s = leveldb::Status::OK(); - if (!is_incognito_and_in_memory) { + leveldb::Status s; + if (!data_directory.empty()) { // The database will be on-disk and not in-memory. std::tie(database_path, blob_path, s) = - CreateDatabaseDirectories(data_directory, origin); + indexed_db::CreateDatabaseDirectories(data_directory, origin); if (!s.ok()) return {IndexedDBOriginStateHandle(), s, CreateDefaultError(), IndexedDBDataLossInfo(), /*was_cold_open=*/true}; } + std::unique_ptr<LevelDBDatabase> database; IndexedDBDataLossInfo data_loss_info; - std::unique_ptr<IndexedDBBackingStore> backing_store; - bool disk_full = false; - for (int i = 0; i < kNumOpenTries; ++i) { - std::tie(backing_store, s, data_loss_info, disk_full) = - OpenAndVerifyIndexedDBBackingStore(origin, data_directory, - database_path, blob_path, - /*is_first_attempt=*/i == 0); - if (LIKELY(s.ok())) - break; - DCHECK(!backing_store); - // If the disk is full, always exit immediately. - if (disk_full) - break; - if (s.IsCorruption()) { - std::string sanitized_message = leveldb_env::GetCorruptionMessage(s); - base::ReplaceSubstringsAfterOffset(&sanitized_message, 0u, - data_directory.AsUTF8Unsafe(), "..."); - LOG(ERROR) << "Got corruption for " << origin.Serialize() << ", " - << sanitized_message; - IndexedDBBackingStore::RecordCorruptionInfo(data_directory, origin, - sanitized_message); - } - } - - if (UNLIKELY(!s.ok())) { - ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, - origin); + bool disk_full; + std::tie(database, s, data_loss_info, disk_full) = + indexed_db::OpenAndVerifyLevelDBDatabase(origin, data_directory, + database_path, leveldb_factory_, + context_->TaskRunner()); + if (!s.ok()) { if (disk_full) { return {IndexedDBOriginStateHandle(), s, IndexedDBDatabaseError( @@ -679,19 +581,35 @@ data_loss_info, /*was_cold_open=*/true}; } } - if (!is_incognito_and_in_memory) - ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_SUCCESS, origin); - it = factories_per_origin_ - .emplace(origin, - std::make_unique<IndexedDBOriginState>( - /*persist_for_incognito=*/is_incognito_and_in_memory, - clock_, leveldb_factory_, &earliest_sweep_, - base::BindOnce( - &IndexedDBFactoryImpl::RemoveOriginState, - origin_state_destruction_weak_factory_.GetWeakPtr(), - origin), - std::move(backing_store))) - .first; + bool is_in_memory = data_directory.empty(); + IndexedDBBackingStore::Mode backing_store_mode = + is_in_memory ? IndexedDBBackingStore::Mode::kInMemory + : IndexedDBBackingStore::Mode::kOnDisk; + std::unique_ptr<IndexedDBBackingStore> backing_store = CreateBackingStore( + backing_store_mode, leveldb_factory_, origin, blob_path, + std::move(database), context_->TaskRunner()); + + bool first_open_since_startup = + backends_opened_since_startup_.insert(origin).second; + s = backing_store->Initialize( + /*cleanup_live_journal=*/!database_path.empty() && + first_open_since_startup); + + if (!s.ok()) + return {IndexedDBOriginStateHandle(), s, CreateDefaultError(), + data_loss_info, /*was_cold_open=*/true}; + + it = + factories_per_origin_ + .emplace(origin, + std::make_unique<IndexedDBOriginState>( + is_in_memory, clock_, leveldb_factory_, &earliest_sweep_, + base::BindOnce( + &IndexedDBFactoryImpl::RemoveOriginState, + origin_state_destruction_weak_factory_.GetWeakPtr(), + origin), + std::move(backing_store))) + .first; context_->FactoryOpened(origin); return {it->second->CreateHandle(), s, IndexedDBDatabaseError(), data_loss_info, /*was_cold_open=*/true}; @@ -709,114 +627,6 @@ std::move(db), task_runner); } -std::tuple<std::unique_ptr<IndexedDBBackingStore>, - leveldb::Status, - IndexedDBDataLossInfo, - bool /* is_disk_full */> -IndexedDBFactoryImpl::OpenAndVerifyIndexedDBBackingStore( - const url::Origin& origin, - base::FilePath data_directory, - base::FilePath database_path, - base::FilePath blob_path, - bool is_first_attempt) { - // Please see docs/open_and_verify_leveldb_database.code2flow, and the - // generated pdf (from https://code2flow.com). - // The intended strategy here is to have this function match that flowchart, - // where the flowchart should be seen as the 'master' logic template. Please - // check the git history of both to make sure they are in sync. - DCHECK_EQ(database_path.empty(), data_directory.empty()); - DCHECK_EQ(blob_path.empty(), data_directory.empty()); - IDB_TRACE("indexed_db::OpenAndVerifyLevelDBDatabase"); - - bool is_incognito_and_in_memory = data_directory.empty(); - leveldb::Status status; - IndexedDBDataLossInfo data_loss_info; - data_loss_info.status = blink::mojom::IDBDataLoss::None; - if (!is_incognito_and_in_memory) { - // Check for previous corruption, and if found then try to delete the - // database. - std::string corruption_message = - indexed_db::ReadCorruptionInfo(data_directory, origin); - if (UNLIKELY(!corruption_message.empty())) { - LOG(ERROR) << "IndexedDB recovering from a corrupted (and deleted) " - "database."; - if (is_first_attempt) { - ReportOpenStatus( - indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION, - origin); - } - data_loss_info.status = blink::mojom::IDBDataLoss::Total; - data_loss_info.message = base::StrCat( - {"IndexedDB (database was corrupt): ", corruption_message}); - // This is a special case where we want to make sure the database is - // deleted, so we try to delete again. - status = leveldb_factory_->DestroyLevelDB(database_path); - UMA_HISTOGRAM_ENUMERATION( - "WebCore.IndexedDB.DestroyCorruptBackingStoreStatus", - leveldb_env::GetLevelDBStatusUMAValue(status), - leveldb_env::LEVELDB_STATUS_MAX); - if (UNLIKELY(!status.ok())) { - LOG(ERROR) << "Unable to delete backing store: " << status.ToString(); - return {nullptr, status, data_loss_info, /*is_disk_full=*/false}; - } - } - } - - bool is_disk_full; - scoped_refptr<LevelDBState> state; - - // Open the leveldb database. - std::tie(state, status, is_disk_full) = leveldb_factory_->OpenLevelDBState( - database_path, indexed_db::GetDefaultIndexedDBComparator(), - indexed_db::GetDefaultLevelDBComparator()); - - if (UNLIKELY(!status.ok())) - return {nullptr, status, IndexedDBDataLossInfo(), is_disk_full}; - - std::unique_ptr<LevelDBDatabase> database = std::make_unique<LevelDBDatabase>( - std::move(state), leveldb_factory_, context_->TaskRunner(), - LevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase); - - bool are_schemas_known = false; - std::tie(are_schemas_known, status) = AreSchemasKnown(database.get()); - if (UNLIKELY(!status.ok())) { - LOG(ERROR) << "IndexedDB had an error checking schema, treating it as " - "failure to open: " - << status.ToString(); - ReportOpenStatus( - indexed_db:: - INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, - origin); - return {nullptr, status, std::move(data_loss_info), /*is_disk_full=*/false}; - } else if (UNLIKELY(!are_schemas_known)) { - LOG(ERROR) << "IndexedDB backing store had unknown schema, treating it as " - "failure to open."; - ReportOpenStatus( - indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_SCHEMA, - origin); - return {nullptr, leveldb::Status::Corruption("Unknown IndexedDB schema"), - std::move(data_loss_info), /*is_disk_full=*/false}; - } - - bool first_open_since_startup = - backends_opened_since_startup_.insert(origin).second; - IndexedDBBackingStore::Mode backing_store_mode = - is_incognito_and_in_memory ? IndexedDBBackingStore::Mode::kInMemory - : IndexedDBBackingStore::Mode::kOnDisk; - std::unique_ptr<IndexedDBBackingStore> backing_store = CreateBackingStore( - backing_store_mode, leveldb_factory_, origin, blob_path, - std::move(database), context_->TaskRunner()); - status = backing_store->Initialize( - /*cleanup_live_journal=*/(!is_incognito_and_in_memory && - first_open_since_startup)); - - if (UNLIKELY(!status.ok())) - return {nullptr, status, IndexedDBDataLossInfo(), /*is_disk_full=*/false}; - - return {std::move(backing_store), status, std::move(data_loss_info), - /*is_disk_full=*/false}; -} - void IndexedDBFactoryImpl::RemoveOriginState(const url::Origin& origin) { factories_per_origin_.erase(origin); }
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.h b/content/browser/indexed_db/indexed_db_factory_impl.h index 48c24efc..08bcac8 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.h +++ b/content/browser/indexed_db/indexed_db_factory_impl.h
@@ -143,8 +143,7 @@ IndexedDBContextImpl* context() const { return context_; } private: - friend class IndexedDBBrowserTest; - friend class IndexedDBOriginState; + friend IndexedDBOriginState; FRIEND_TEST_ALL_PREFIXES(IndexedDBFactoryTest, BackingStoreReleasedOnForcedClose); @@ -164,20 +163,6 @@ FRIEND_TEST_ALL_PREFIXES(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure); - // |path_base| is the directory that will contain the database directory, the - // blob directory, and any data loss info. |database_path| is the directory - // for the leveldb database, and |blob_path| is the directory to store blob - // files. If |path_base| is empty, then an in-memory database is opened. - std::tuple<std::unique_ptr<IndexedDBBackingStore>, - leveldb::Status, - IndexedDBDataLossInfo, - bool /* is_disk_full */> - OpenAndVerifyIndexedDBBackingStore(const url::Origin& origin, - base::FilePath data_directory, - base::FilePath database_path, - base::FilePath blob_path, - bool is_first_attempt); - void RemoveOriginState(const url::Origin& origin); void OnDatabaseError(const url::Origin& origin, @@ -197,8 +182,8 @@ SEQUENCE_CHECKER(sequence_checker_); IndexedDBContextImpl* context_; indexed_db::LevelDBFactory* const leveldb_factory_; - IndexedDBClassFactory* const indexed_db_class_factory_; - base::Clock* const clock_; + IndexedDBClassFactory* indexed_db_class_factory_; + base::Clock* clock_; base::Time earliest_sweep_; base::flat_map<url::Origin, std::unique_ptr<IndexedDBOriginState>>
diff --git a/content/browser/indexed_db/indexed_db_leveldb_coding.h b/content/browser/indexed_db/indexed_db_leveldb_coding.h index 42b04ac..539d31f 100644 --- a/content/browser/indexed_db/indexed_db_leveldb_coding.h +++ b/content/browser/indexed_db/indexed_db_leveldb_coding.h
@@ -215,7 +215,7 @@ class DataVersionKey { public: - CONTENT_EXPORT static std::string Encode(); + static std::string Encode(); }; class BlobJournalKey {
diff --git a/content/browser/indexed_db/indexed_db_leveldb_operations.cc b/content/browser/indexed_db/indexed_db_leveldb_operations.cc index eb9f7f3..e4a0c0b 100644 --- a/content/browser/indexed_db/indexed_db_leveldb_operations.cc +++ b/content/browser/indexed_db/indexed_db_leveldb_operations.cc
@@ -9,7 +9,6 @@ #include "base/metrics/histogram_macros.h" #include "base/no_destructor.h" #include "base/values.h" -#include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_data_format_version.h" #include "content/browser/indexed_db/indexed_db_data_loss_info.h" #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" @@ -19,8 +18,6 @@ #include "content/browser/indexed_db/leveldb/leveldb_env.h" #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" -#include "content/browser/indexed_db/leveldb/leveldb_write_batch.h" -#include "content/browser/indexed_db/scopes/leveldb_scopes.h" #include "storage/common/database/database_identifier.h" #include "third_party/leveldatabase/env_chromium.h" @@ -58,6 +55,33 @@ void FindShortSuccessor(std::string* key) const override {} }; +bool IsPathTooLong(const base::FilePath& leveldb_dir) { + int limit = base::GetMaximumPathComponentLength(leveldb_dir.DirName()); + if (limit == -1) { + DLOG(WARNING) << "GetMaximumPathComponentLength returned -1"; +// In limited testing, ChromeOS returns 143, other OSes 255. +#if defined(OS_CHROMEOS) + limit = 143; +#else + limit = 255; +#endif + } + size_t component_length = leveldb_dir.BaseName().value().length(); + if (component_length > static_cast<uint32_t>(limit)) { + DLOG(WARNING) << "Path component length (" << component_length + << ") exceeds maximum (" << limit + << ") allowed by this filesystem."; + const int min = 140; + const int max = 300; + const int num_buckets = 12; + UMA_HISTOGRAM_CUSTOM_COUNTS( + "WebCore.IndexedDB.BackingStore.OverlyLargeOriginLength", + component_length, min, max, num_buckets); + return true; + } + return false; +} + template <typename DBOrTransaction> Status GetIntInternal(DBOrTransaction* db, const StringPiece& key, @@ -74,6 +98,83 @@ return s; return InternalInconsistencyStatus(); } + +WARN_UNUSED_RESULT bool IsSchemaKnown(LevelDBDatabase* db, bool* known) { + int64_t db_schema_version = 0; + bool found = false; + Status s = GetInt(db, SchemaVersionKey::Encode(), &db_schema_version, &found); + if (!s.ok()) + return false; + if (!found) { + *known = true; + return true; + } + if (db_schema_version < 0) + return false; // Only corruption should cause this. + if (db_schema_version > indexed_db::kLatestKnownSchemaVersion) { + *known = false; + return true; + } + + int64_t raw_db_data_version = 0; + s = GetInt(db, DataVersionKey::Encode(), &raw_db_data_version, &found); + if (!s.ok()) + return false; + if (!found) { + *known = true; + return true; + } + if (raw_db_data_version < 0) + return false; // Only corruption should cause this. + + *known = IndexedDBDataFormatVersion::GetCurrent().IsAtLeast( + IndexedDBDataFormatVersion::Decode(raw_db_data_version)); + return true; +} +std::tuple<std::unique_ptr<LevelDBDatabase>, + leveldb::Status, + bool /* is_disk_full */> +DeleteAndRecreateDatabase( + const url::Origin& origin, + base::FilePath database_path, + LevelDBFactory* ldb_factory, + scoped_refptr<base::SequencedTaskRunner> task_runner) { + scoped_refptr<LevelDBState> state; + DCHECK(!database_path.empty()) + << "Opening an in-memory database should not have failed."; + LOG(ERROR) << "IndexedDB backing store open failed, attempting cleanup"; + state.reset(); + leveldb::Status status = ldb_factory->DestroyLevelDB(database_path); + if (!status.ok()) { + LOG(ERROR) << "IndexedDB backing store cleanup failed"; + ReportOpenStatus( + indexed_db::INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_DESTROY_FAILED, + origin); + return {nullptr, status, false}; + } + + LOG(ERROR) << "IndexedDB backing store cleanup succeeded, reopening"; + state.reset(); + bool is_disk_full; + std::tie(state, status, is_disk_full) = ldb_factory->OpenLevelDBState( + database_path, GetDefaultIndexedDBComparator(), + GetDefaultLevelDBComparator()); + if (!status.ok()) { + LOG(ERROR) << "IndexedDB backing store reopen after recovery failed"; + ReportOpenStatus( + indexed_db::INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_FAILED, + origin); + return {nullptr, status, is_disk_full}; + } + std::unique_ptr<LevelDBDatabase> database = std::make_unique<LevelDBDatabase>( + std::move(state), ldb_factory, std::move(task_runner), + LevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase); + ReportOpenStatus( + indexed_db::INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_SUCCESS, origin); + + return {std::move(database), status, is_disk_full}; +} + } // namespace const base::FilePath::CharType kBlobExtension[] = FILE_PATH_LITERAL(".blob"); @@ -105,37 +206,10 @@ FILE_PATH_LITERAL("corruption_info.json")); } -bool IsPathTooLong(const base::FilePath& leveldb_dir) { - int limit = base::GetMaximumPathComponentLength(leveldb_dir.DirName()); - if (limit == -1) { - DLOG(WARNING) << "GetMaximumPathComponentLength returned -1"; -// In limited testing, ChromeOS returns 143, other OSes 255. -#if defined(OS_CHROMEOS) - limit = 143; -#else - limit = 255; -#endif - } - size_t component_length = leveldb_dir.BaseName().value().length(); - if (component_length > static_cast<uint32_t>(limit)) { - DLOG(WARNING) << "Path component length (" << component_length - << ") exceeds maximum (" << limit - << ") allowed by this filesystem."; - const int min = 140; - const int max = 300; - const int num_buckets = 12; - UMA_HISTOGRAM_CUSTOM_COUNTS( - "WebCore.IndexedDB.BackingStore.OverlyLargeOriginLength", - component_length, min, max, num_buckets); - return true; - } - return false; -} - std::string ReadCorruptionInfo(const base::FilePath& path_base, const url::Origin& origin) { const base::FilePath info_path = - path_base.Append(indexed_db::ComputeCorruptionFileName(origin)); + path_base.Append(ComputeCorruptionFileName(origin)); std::string message; if (IsPathTooLong(info_path)) return message; @@ -179,21 +253,19 @@ return leveldb::Status::IOError("IO Error"); } -template <typename DBOrTransaction> -Status GetInt(DBOrTransaction* db, +Status GetInt(LevelDBTransaction* txn, + const StringPiece& key, + int64_t* found_int, + bool* found) { + return GetIntInternal(txn, key, found_int, found); +} + +Status GetInt(LevelDBDatabase* db, const StringPiece& key, int64_t* found_int, bool* found) { return GetIntInternal(db, key, found_int, found); } -template Status GetInt<LevelDBTransaction>(LevelDBTransaction* db, - const StringPiece& key, - int64_t* found_int, - bool* found); -template Status GetInt<LevelDBDatabase>(LevelDBDatabase* db, - const StringPiece& key, - int64_t* found_int, - bool* found); void PutBool(LevelDBTransaction* transaction, const StringPiece& key, @@ -203,29 +275,14 @@ transaction->Put(key, &buffer); } -template <typename Transaction> -void PutInt(Transaction* transaction, const StringPiece& key, int64_t value) { +void PutInt(LevelDBTransaction* transaction, + const StringPiece& key, + int64_t value) { DCHECK_GE(value, 0); std::string buffer; EncodeInt(value, &buffer); transaction->Put(key, &buffer); } -template void PutInt<LevelDBTransaction>(LevelDBTransaction* transaction, - const StringPiece& key, - int64_t value); -template void PutInt<LevelDBDirectTransaction>( - LevelDBDirectTransaction* transaction, - const StringPiece& key, - int64_t value); -template <> -void PutInt<LevelDBWriteBatch>(LevelDBWriteBatch* write_batch, - const StringPiece& key, - int64_t value) { - DCHECK_GE(value, 0); - std::string buffer; - EncodeInt(value, &buffer); - write_batch->Put(key, base::StringPiece(buffer)); -} template <typename DBOrTransaction> Status GetVarInt(DBOrTransaction* db, @@ -243,6 +300,7 @@ return s; return InternalInconsistencyStatus(); } + template Status GetVarInt<LevelDBTransaction>(LevelDBTransaction* txn, const StringPiece& key, int64_t* found_int, @@ -252,29 +310,13 @@ int64_t* found_int, bool* found); -template <typename Transaction> -void PutVarInt(Transaction* transaction, +void PutVarInt(LevelDBTransaction* transaction, const StringPiece& key, int64_t value) { std::string buffer; EncodeVarInt(value, &buffer); transaction->Put(key, &buffer); } -template void PutVarInt<LevelDBTransaction>(LevelDBTransaction* transaction, - const StringPiece& key, - int64_t value); -template void PutVarInt<LevelDBDirectTransaction>( - LevelDBDirectTransaction* transaction, - const StringPiece& key, - int64_t value); -template <> -void PutVarInt<LevelDBWriteBatch>(LevelDBWriteBatch* write_batch, - const StringPiece& key, - int64_t value) { - std::string buffer; - EncodeVarInt(value, &buffer); - write_batch->Put(key, base::StringPiece(buffer)); -} template <typename DBOrTransaction> Status GetString(DBOrTransaction* db, @@ -456,16 +498,7 @@ return s; } -template Status GetNewDatabaseId<LevelDBDirectTransaction>( - LevelDBDirectTransaction* transaction, - int64_t* new_id); - -template Status GetNewDatabaseId<LevelDBTransaction>( - LevelDBTransaction* transaction, - int64_t* new_id); - -template <typename Transaction> -Status GetNewDatabaseId(Transaction* transaction, int64_t* new_id) { +Status GetNewDatabaseId(LevelDBTransaction* transaction, int64_t* new_id) { *new_id = -1; int64_t max_database_id = -1; bool found = false; @@ -621,15 +654,7 @@ return s; } -template void SetEarliestSweepTime<LevelDBTransaction>( - LevelDBTransaction* db, - base::Time earliest_sweep); -template void SetEarliestSweepTime<LevelDBDirectTransaction>( - LevelDBDirectTransaction* db, - base::Time earliest_sweep); - -template <typename Transaction> -void SetEarliestSweepTime(Transaction* txn, base::Time earliest_sweep) { +void SetEarliestSweepTime(LevelDBTransaction* txn, base::Time earliest_sweep) { const std::string earliest_sweep_time_key = EarliestSweepKey::Encode(); int64_t time_micros = (earliest_sweep - base::Time()).InMicroseconds(); indexed_db::PutInt(txn, earliest_sweep_time_key, time_micros); @@ -645,5 +670,132 @@ return ldb_comparator.get(); } +std::tuple<base::FilePath /*leveldb_path*/, + base::FilePath /*blob_path*/, + leveldb::Status> +CreateDatabaseDirectories(const base::FilePath& path_base, + const url::Origin& origin) { + leveldb::Status status; + if (!base::CreateDirectoryAndGetError(path_base, nullptr)) { + status = Status::IOError("Unable to create IndexedDB database path"); + LOG(ERROR) << status.ToString() << ": \"" << path_base.AsUTF8Unsafe() + << "\""; + ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY, + origin); + return {base::FilePath(), base::FilePath(), status}; + } + + base::FilePath leveldb_path = path_base.Append(GetLevelDBFileName(origin)); + base::FilePath blob_path = path_base.Append(GetBlobStoreFileName(origin)); + if (IsPathTooLong(leveldb_path)) { + ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, + origin); + status = Status::IOError("File path too long"); + return {base::FilePath(), base::FilePath(), status}; + } + return {leveldb_path, blob_path, status}; +} + +std::tuple<std::unique_ptr<LevelDBDatabase>, + leveldb::Status, + IndexedDBDataLossInfo, + bool /* is_disk_full */> +OpenAndVerifyLevelDBDatabase( + const url::Origin& origin, + base::FilePath path_base, + base::FilePath database_path, + LevelDBFactory* ldb_factory, + scoped_refptr<base::SequencedTaskRunner> task_runner) { + // Please see docs/open_and_verify_leveldb_database.code2flow, and the + // generated pdf (from https://code2flow.com). + // The intended strategy here is to have this function match that flowchart, + // where the flowchart should be seen as the 'master' logic template. Please + // check the git history of both to make sure they are supposed to be in sync. + DCHECK_EQ(database_path.empty(), path_base.empty()); + IDB_TRACE("indexed_db::OpenAndVerifyLevelDBDatabase"); + bool is_disk_full; + std::unique_ptr<LevelDBDatabase> database; + leveldb::Status status; + scoped_refptr<LevelDBState> state; + std::tie(state, status, is_disk_full) = ldb_factory->OpenLevelDBState( + database_path, GetDefaultIndexedDBComparator(), + GetDefaultLevelDBComparator()); + bool is_schema_known = false; + // On I/O error the database isn't deleted, in case the issue is temporary. + if (status.IsIOError()) { + ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, + origin); + return {std::move(database), status, IndexedDBDataLossInfo(), is_disk_full}; + } + + IndexedDBDataLossInfo data_loss_info; + data_loss_info.status = blink::mojom::IDBDataLoss::None; + if (status.IsCorruption()) { + // On corruption, recovery will happen in the next section. + data_loss_info.status = blink::mojom::IDBDataLoss::Total; + data_loss_info.message = leveldb_env::GetCorruptionMessage(status); + std::tie(database, status, is_disk_full) = DeleteAndRecreateDatabase( + origin, database_path, ldb_factory, task_runner); + // If successful, then the database should be empty and doesn't need any of + // the corruption or schema checks below. + if (status.ok()) { + ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_SUCCESS, + origin); + } + return {std::move(database), status, data_loss_info, is_disk_full}; + } + // The leveldb database is successfully opened. + DCHECK(status.ok()); + database = std::make_unique<LevelDBDatabase>( + std::move(state), ldb_factory, std::move(task_runner), + LevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase); + + // Check for previous corruption or invalid schemas. + std::string corruption_message; + if (!path_base.empty()) + corruption_message = ReadCorruptionInfo(path_base, origin); + if (!corruption_message.empty()) { + LOG(ERROR) << "IndexedDB recovering from a corrupted (and deleted) " + "database."; + ReportOpenStatus( + indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION, + origin); + status = leveldb::Status::Corruption(corruption_message); + database.reset(); + data_loss_info.status = blink::mojom::IDBDataLoss::Total; + data_loss_info.message = + "IndexedDB (database was corrupt): " + corruption_message; + } else if (!IsSchemaKnown(database.get(), &is_schema_known)) { + LOG(ERROR) << "IndexedDB had IO error checking schema, treating it as " + "failure to open"; + ReportOpenStatus( + indexed_db:: + INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, + origin); + database.reset(); + data_loss_info.status = blink::mojom::IDBDataLoss::Total; + data_loss_info.message = "I/O error checking schema"; + } else if (!is_schema_known) { + LOG(ERROR) << "IndexedDB backing store had unknown schema, treating it " + "as failure to open"; + ReportOpenStatus( + indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_SCHEMA, + origin); + database.reset(); + data_loss_info.status = blink::mojom::IDBDataLoss::Total; + data_loss_info.message = "Unknown schema"; + } + // Try to delete & recreate the database for any of the above issues. + if (!database.get()) { + DCHECK(!is_schema_known || status.IsCorruption()); + std::tie(database, status, is_disk_full) = DeleteAndRecreateDatabase( + origin, database_path, ldb_factory, task_runner); + } + + if (status.ok()) + ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_SUCCESS, origin); + return {std::move(database), status, data_loss_info, is_disk_full}; +} + } // namespace indexed_db } // namespace content
diff --git a/content/browser/indexed_db/indexed_db_leveldb_operations.h b/content/browser/indexed_db/indexed_db_leveldb_operations.h index 66848fb..dfa747e 100644 --- a/content/browser/indexed_db/indexed_db_leveldb_operations.h +++ b/content/browser/indexed_db/indexed_db_leveldb_operations.h
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include <tuple> #include "base/files/file_path.h" #include "base/macros.h" @@ -15,9 +16,7 @@ #include "base/strings/string16.h" #include "base/strings/string_piece.h" #include "base/time/time.h" -#include "content/browser/indexed_db/indexed_db_data_loss_info.h" #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" -#include "content/browser/indexed_db/scopes/leveldb_scopes_factory.h" #include "content/common/content_export.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key_path.h" #include "third_party/leveldatabase/src/include/leveldb/comparator.h" @@ -30,8 +29,10 @@ class LevelDBDatabase; class LevelDBIterator; class LevelDBTransaction; +struct IndexedDBDataLossInfo; namespace indexed_db { +class LevelDBFactory; extern const base::FilePath::CharType kBlobExtension[]; extern const base::FilePath::CharType kIndexedDBExtension[]; @@ -41,10 +42,6 @@ base::FilePath GetLevelDBFileName(const url::Origin& origin); base::FilePath ComputeCorruptionFileName(const url::Origin& origin); -// Returns if the given file path is too long for the current operating system's -// file system. -bool IsPathTooLong(const base::FilePath& leveldb_dir); - // If a corruption file for the given |origin| at the given |path_base| exists // it is deleted, and the message is returned. If the file does not exist, or if // there is an error parsing the message, then this method returns an empty @@ -60,8 +57,11 @@ leveldb::Status IOErrorStatus(); -template <typename DBOrTransaction> -leveldb::Status CONTENT_EXPORT GetInt(DBOrTransaction* db, +leveldb::Status CONTENT_EXPORT GetInt(LevelDBDatabase* db, + const base::StringPiece& key, + int64_t* found_int, + bool* found); +leveldb::Status CONTENT_EXPORT GetInt(LevelDBTransaction* txn, const base::StringPiece& key, int64_t* found_int, bool* found); @@ -69,9 +69,7 @@ void PutBool(LevelDBTransaction* transaction, const base::StringPiece& key, bool value); - -template <typename TransactionOrWriteBatch> -void CONTENT_EXPORT PutInt(TransactionOrWriteBatch* transaction, +void CONTENT_EXPORT PutInt(LevelDBTransaction* transaction, const base::StringPiece& key, int64_t value); @@ -81,8 +79,7 @@ int64_t* found_int, bool* found); -template <typename TransactionOrWriteBatch> -void PutVarInt(TransactionOrWriteBatch* transaction, +void PutVarInt(LevelDBTransaction* transaction, const base::StringPiece& key, int64_t value); @@ -131,9 +128,9 @@ const std::string& encoded_primary_key, bool* exists); -template <typename Transaction> -WARN_UNUSED_RESULT leveldb::Status GetNewDatabaseId(Transaction* transaction, - int64_t* new_id); +WARN_UNUSED_RESULT leveldb::Status GetNewDatabaseId( + LevelDBTransaction* transaction, + int64_t* new_id); WARN_UNUSED_RESULT bool CheckObjectStoreAndMetaDataType( const LevelDBIterator* it, @@ -166,13 +163,34 @@ LevelDBDatabase* db, base::Time* earliest_sweep); -template <typename Transaction> -void SetEarliestSweepTime(Transaction* txn, base::Time earliest_sweep); +void SetEarliestSweepTime(LevelDBTransaction* txn, base::Time earliest_sweep); CONTENT_EXPORT const LevelDBComparator* GetDefaultIndexedDBComparator(); CONTENT_EXPORT const leveldb::Comparator* GetDefaultLevelDBComparator(); +// Creates the leveldb and blob storage directories for IndexedDB. +std::tuple<base::FilePath /*leveldb_path*/, + base::FilePath /*blob_path*/, + leveldb::Status> +CreateDatabaseDirectories(const base::FilePath& path_base, + const url::Origin& origin); + +// |path_base| is the directory that will contain the database directory, the +// blob directory, and any data loss info. |database_path| is the directory for +// the leveldb database. If |path_base| is empty, then an in-memory database is +// opened. +std::tuple<std::unique_ptr<LevelDBDatabase>, + leveldb::Status, + IndexedDBDataLossInfo, + bool /* is_disk_full */> +OpenAndVerifyLevelDBDatabase( + const url::Origin& origin, + base::FilePath path_base, + base::FilePath database_path, + LevelDBFactory* ldb_factory, + scoped_refptr<base::SequencedTaskRunner> task_runner); + } // namespace indexed_db } // namespace content
diff --git a/content/browser/indexed_db/indexed_db_origin_state_handle.h b/content/browser/indexed_db/indexed_db_origin_state_handle.h index 12a780a..bfa2326 100644 --- a/content/browser/indexed_db/indexed_db_origin_state_handle.h +++ b/content/browser/indexed_db/indexed_db_origin_state_handle.h
@@ -36,7 +36,6 @@ protected: friend class IndexedDBFactoryImpl; friend class IndexedDBFactoryTest; - friend class IndexedDBBrowserTest; friend class indexed_db_backing_store_unittest::IndexedDBBackingStoreTest; // Returns null if the factory was destroyed, which should only happen on
diff --git a/content/browser/indexed_db/indexed_db_reporting.h b/content/browser/indexed_db/indexed_db_reporting.h index f5579fe..6fe9fde 100644 --- a/content/browser/indexed_db/indexed_db_reporting.h +++ b/content/browser/indexed_db/indexed_db_reporting.h
@@ -70,7 +70,6 @@ INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION, INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, - INDEXED_DB_BACKING_STORE_OPEN_FAILED_METADATA_SETUP, INDEXED_DB_BACKING_STORE_OPEN_MAX, };
diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc index fc4fd6d6..5f9e8f7 100644 --- a/content/browser/loader/resource_loader_unittest.cc +++ b/content/browser/loader/resource_loader_unittest.cc
@@ -276,7 +276,7 @@ base::RunLoop().RunUntilIdle(); } - void SelectClientCertificate( + base::OnceClosure SelectClientCertificate( WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs, @@ -287,6 +287,7 @@ passed_identities_ = std::move(client_certs); delegate_ = std::move(delegate); select_certificate_run_loop_.Quit(); + return base::OnceClosure(); } std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
diff --git a/content/browser/media/android/browser_gpu_video_accelerator_factories.cc b/content/browser/media/android/browser_gpu_video_accelerator_factories.cc index 063edef..fc9c720 100644 --- a/content/browser/media/android/browser_gpu_video_accelerator_factories.cc +++ b/content/browser/media/android/browser_gpu_video_accelerator_factories.cc
@@ -117,26 +117,6 @@ return nullptr; } -bool BrowserGpuVideoAcceleratorFactories::CreateTextures( - int32_t count, - const gfx::Size& size, - std::vector<uint32_t>* texture_ids, - std::vector<gpu::Mailbox>* texture_mailboxes, - uint32_t texture_target) { - return false; -} - -void BrowserGpuVideoAcceleratorFactories::DeleteTexture(uint32_t texture_id) {} - -gpu::SyncToken BrowserGpuVideoAcceleratorFactories::CreateSyncToken() { - return gpu::SyncToken(); -} - -void BrowserGpuVideoAcceleratorFactories::ShallowFlushCHROMIUM() {} - -void BrowserGpuVideoAcceleratorFactories::WaitSyncToken( - const gpu::SyncToken& sync_token) {} - void BrowserGpuVideoAcceleratorFactories::SignalSyncToken( const gpu::SyncToken& sync_token, base::OnceClosure callback) {} @@ -165,10 +145,6 @@ return GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED; } -gpu::gles2::GLES2Interface* BrowserGpuVideoAcceleratorFactories::ContextGL() { - return nullptr; -} - gpu::SharedImageInterface* BrowserGpuVideoAcceleratorFactories::SharedImageInterface() { NOTREACHED(); @@ -202,11 +178,6 @@ return context_provider_; } -gpu::ContextSupport* -BrowserGpuVideoAcceleratorFactories::GetMediaContextProviderContextSupport() { - return GetMediaContextProvider()->ContextSupport(); -} - void BrowserGpuVideoAcceleratorFactories::SetRenderingColorSpace( const gfx::ColorSpace& color_space) {}
diff --git a/content/browser/media/android/browser_gpu_video_accelerator_factories.h b/content/browser/media/android/browser_gpu_video_accelerator_factories.h index b4c9a5c..984df2e 100644 --- a/content/browser/media/android/browser_gpu_video_accelerator_factories.h +++ b/content/browser/media/android/browser_gpu_video_accelerator_factories.h
@@ -33,15 +33,6 @@ const media::RequestOverlayInfoCB& request_overlay_info_cb) override; std::unique_ptr<media::VideoEncodeAccelerator> CreateVideoEncodeAccelerator() override; - bool CreateTextures(int32_t count, - const gfx::Size& size, - std::vector<uint32_t>* texture_ids, - std::vector<gpu::Mailbox>* texture_mailboxes, - uint32_t texture_target) override; - void DeleteTexture(uint32_t texture_id) override; - gpu::SyncToken CreateSyncToken() override; - void ShallowFlushCHROMIUM() override; - void WaitSyncToken(const gpu::SyncToken& sync_token) override; void SignalSyncToken(const gpu::SyncToken& sync_token, base::OnceClosure callback) override; std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer( @@ -53,7 +44,6 @@ unsigned ImageTextureTarget(gfx::BufferFormat format) override; media::GpuVideoAcceleratorFactories::OutputFormat VideoFrameOutputFormat( media::VideoPixelFormat pixel_format) override; - gpu::gles2::GLES2Interface* ContextGL() override; gpu::SharedImageInterface* SharedImageInterface() override; gpu::GpuMemoryBufferManager* GpuMemoryBufferManager() override; std::unique_ptr<base::SharedMemory> CreateSharedMemory(size_t size) override; @@ -62,7 +52,6 @@ GetVideoEncodeAcceleratorSupportedProfiles() override; scoped_refptr<viz::ContextProviderCommandBuffer> GetMediaContextProvider() override; - gpu::ContextSupport* GetMediaContextProviderContextSupport() override; void SetRenderingColorSpace(const gfx::ColorSpace& color_space) override; scoped_refptr<viz::ContextProviderCommandBuffer> context_provider_;
diff --git a/content/browser/network_service_instance_impl.cc b/content/browser/network_service_instance_impl.cc index a0f1fde..1d8c3893 100644 --- a/content/browser/network_service_instance_impl.cc +++ b/content/browser/network_service_instance_impl.cc
@@ -118,6 +118,28 @@ GetCrashHandlersList().Notify(); } +// Parses the desired granularity of NetLog capturing specified by the command +// line. +net::NetLogCaptureMode GetNetCaptureModeFromCommandLine( + const base::CommandLine& command_line) { + base::StringPiece switch_name = network::switches::kNetLogCaptureMode; + + if (command_line.HasSwitch(switch_name)) { + std::string value = command_line.GetSwitchValueASCII(switch_name); + + if (value == "Default") + return net::NetLogCaptureMode::Default(); + if (value == "IncludeCookiesAndCredentials") + return net::NetLogCaptureMode::IncludeCookiesAndCredentials(); + if (value == "IncludeSocketBytes") + return net::NetLogCaptureMode::IncludeSocketBytes(); + + LOG(ERROR) << "Unrecognized value for --" << switch_name; + } + + return net::NetLogCaptureMode::Default(); +} + } // namespace network::mojom::NetworkService* GetNetworkService() { @@ -191,14 +213,11 @@ base::File file(log_path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); if (!file.IsValid()) { - LOG(ERROR) << "Failed opening: " << log_path.value(); + LOG(ERROR) << "Failed opening NetLog: " << log_path.value(); } else { - net::NetLogCaptureMode capture_mode = - net::GetNetCaptureModeFromCommandLine( - *command_line, network::switches::kNetLogCaptureMode); - (*g_network_service_ptr) - ->StartNetLog(std::move(file), capture_mode, + ->StartNetLog(std::move(file), + GetNetCaptureModeFromCommandLine(*command_line), std::move(client_constants)); } }
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index fcbe860..e43d9c4 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -867,26 +867,6 @@ } } - // Check whether |host| is associated with at least one URL for which - // SiteInstance does not assign site URLs. This is used to disqualify |host| - // from being reused if it has pending navigations to such URLs. - bool ContainsNonReusableSiteForHost(RenderProcessHost* host) { - for (auto iter : map_) { - // If SiteInstance doesn't assign a site URL for the current entry, check - // whether |host| is on the list of processes the entry is associated - // with. - // - // TODO(alexmos): ShouldAssignSiteForURL() expects a full URL, whereas we - // only have a site URL here. For now, this mismatch is ok since - // ShouldAssignSiteForURL() only cares about schemes in practice, but - // this should be cleaned up. - if (!SiteInstanceImpl::ShouldAssignSiteForURL(iter.first) && - base::Contains(iter.second, host->GetID())) - return true; - } - return false; - } - private: void RenderProcessHostDestroyed(RenderProcessHost* host) override { #ifndef NDEBUG @@ -3720,30 +3700,7 @@ } } - if (!GetContentClient()->browser()->IsSuitableHost(host, site_url)) - return false; - - // Check whether this process has a pending navigation to a URL for - // which SiteInstance does not assign site URLs. If this is the case, it is - // not safe to reuse this process for a navigation which itself assigns site - // URLs, since in that case the latter navigation could lock this process - // before the commit for the siteless URL arrives, resulting in a renderer - // kill. See https://crbug.com/970046. - if (SiteInstanceImpl::ShouldAssignSiteForURL(site_url)) { - SiteProcessCountTracker* pending_tracker = - static_cast<SiteProcessCountTracker*>( - browser_context->GetUserData(kPendingSiteProcessCountTrackerKey)); - bool has_disqualifying_pending_navigation = - pending_tracker && - pending_tracker->ContainsNonReusableSiteForHost(host); - UMA_HISTOGRAM_BOOLEAN( - "SiteIsolation.PendingSitelessNavigationDisallowsProcessReuse", - has_disqualifying_pending_navigation); - if (has_disqualifying_pending_navigation) - return false; - } - - return true; + return GetContentClient()->browser()->IsSuitableHost(host, site_url); } // static
diff --git a/content/browser/renderer_host/render_view_host_browsertest.cc b/content/browser/renderer_host/render_view_host_browsertest.cc index 23670873e..68dbbe23 100644 --- a/content/browser/renderer_host/render_view_host_browsertest.cc +++ b/content/browser/renderer_host/render_view_host_browsertest.cc
@@ -45,10 +45,7 @@ return; } - NavigationHandleImpl* impl = - static_cast<NavigationHandleImpl*>(navigation_handle); observed_remote_endpoint_ = navigation_handle->GetSocketAddress(); - base_url_ = impl->base_url(); ++navigation_count_; } @@ -56,15 +53,10 @@ return observed_remote_endpoint_; } - GURL base_url() const { - return base_url_; - } - int navigation_count() const { return navigation_count_; } private: net::IPEndPoint observed_remote_endpoint_; - GURL base_url_; int navigation_count_; DISALLOW_COPY_AND_ASSIGN(RenderViewHostTestWebContentsObserver); @@ -83,21 +75,6 @@ EXPECT_EQ(1, observer.navigation_count()); } -IN_PROC_BROWSER_TEST_F(RenderViewHostTest, BaseURLParam) { - ASSERT_TRUE(embedded_test_server()->Start()); - RenderViewHostTestWebContentsObserver observer(shell()->web_contents()); - - // Base URL is not set if it is the same as the URL. - GURL test_url = embedded_test_server()->GetURL("/simple_page.html"); - NavigateToURL(shell(), test_url); - EXPECT_TRUE(observer.base_url().is_empty()); - EXPECT_EQ(1, observer.navigation_count()); - - // But should be set to the original page when reading MHTML. - NavigateToURL(shell(), GetTestUrl(nullptr, "google.mht")); - EXPECT_EQ("http://www.google.com/", observer.base_url().spec()); -} - // This test ensures a RenderFrameHost object is created for the top level frame // in each RenderViewHost. IN_PROC_BROWSER_TEST_F(RenderViewHostTest, BasicRenderFrameHost) {
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc index 600799b..f346b897 100644 --- a/content/browser/site_instance_impl.cc +++ b/content/browser/site_instance_impl.cc
@@ -766,7 +766,6 @@ if (allow_default_site_url && !base::FeatureList::IsEnabled( features::kProcessSharingWithStrictSiteInstances) && - SiteInstanceImpl::ShouldAssignSiteForURL(url) && !DoesSiteURLRequireDedicatedProcess(isolation_context, site_url)) { return GetDefaultSiteURL(); }
diff --git a/content/browser/sms/sms_parser.cc b/content/browser/sms/sms_parser.cc index 4fd5370..a348d2e51 100644 --- a/content/browser/sms/sms_parser.cc +++ b/content/browser/sms/sms_parser.cc
@@ -14,7 +14,7 @@ namespace content { -constexpr base::StringPiece kToken = "From: "; +constexpr base::StringPiece kToken = "To: "; // static base::Optional<url::Origin> SmsParser::Parse(base::StringPiece sms) {
diff --git a/content/browser/sms/sms_parser_unittest.cc b/content/browser/sms/sms_parser_unittest.cc index 015151a..f9d608b 100644 --- a/content/browser/sms/sms_parser_unittest.cc +++ b/content/browser/sms/sms_parser_unittest.cc
@@ -16,32 +16,32 @@ } TEST(SmsParserTest, WithTokenInvalidUrl) { - ASSERT_FALSE(SmsParser::Parse("From: foo")); + ASSERT_FALSE(SmsParser::Parse("To: foo")); } TEST(SmsParserTest, NoSpace) { - ASSERT_FALSE(SmsParser::Parse("From:https://example.com")); + ASSERT_FALSE(SmsParser::Parse("To:https://example.com")); } TEST(SmsParserTest, InvalidUrl) { - ASSERT_FALSE(SmsParser::Parse("From: //example.com")); + ASSERT_FALSE(SmsParser::Parse("To: //example.com")); } TEST(SmsParserTest, FtpScheme) { - ASSERT_FALSE(SmsParser::Parse("From: ftp://example.com")); + ASSERT_FALSE(SmsParser::Parse("To: ftp://example.com")); } TEST(SmsParserTest, HttpScheme) { - ASSERT_FALSE(SmsParser::Parse("From: http://example.com")); + ASSERT_FALSE(SmsParser::Parse("To: http://example.com")); } TEST(SmsParserTest, Mailto) { - ASSERT_FALSE(SmsParser::Parse("From: mailto:goto@chromium.org")); + ASSERT_FALSE(SmsParser::Parse("To: mailto:goto@chromium.org")); } TEST(SmsParserTest, Basic) { base::Optional<url::Origin> origin = - SmsParser::Parse("From: https://example.com"); + SmsParser::Parse("To: https://example.com"); GURL url("https://example.com"); ASSERT_EQ(origin, url::Origin::Create(url)); @@ -49,7 +49,7 @@ TEST(SmsParserTest, Realistic) { base::Optional<url::Origin> origin = SmsParser::Parse( - "<#> Your OTP is 1234ABC.\nFrom: https://example.com?s3LhKBB0M33"); + "<#> Your OTP is 1234ABC.\nTo: https://example.com?s3LhKBB0M33"); GURL url("https://example.com"); ASSERT_EQ(origin, url::Origin::Create(url)); @@ -57,7 +57,7 @@ TEST(SmsParserTest, Paths) { base::Optional<url::Origin> origin = - SmsParser::Parse("From: https://example.com/foobar"); + SmsParser::Parse("To: https://example.com/foobar"); GURL url("https://example.com"); ASSERT_EQ(origin, url::Origin::Create(url)); @@ -65,7 +65,7 @@ TEST(SmsParserTest, Message) { base::Optional<url::Origin> origin = - SmsParser::Parse("hello world\nFrom: https://example.com"); + SmsParser::Parse("hello world\nTo: https://example.com"); GURL url("https://example.com"); ASSERT_EQ(origin, url::Origin::Create(url)); @@ -73,7 +73,7 @@ TEST(SmsParserTest, Whitespace) { base::Optional<url::Origin> origin = - SmsParser::Parse("hello world\nFrom: https://example.com "); + SmsParser::Parse("hello world\nTo: https://example.com "); GURL url("https://example.com"); ASSERT_EQ(origin, url::Origin::Create(url)); @@ -81,7 +81,7 @@ TEST(SmsParserTest, Newlines) { base::Optional<url::Origin> origin = - SmsParser::Parse("hello world\nFrom: https://example.com\n"); + SmsParser::Parse("hello world\nTo: https://example.com\n"); GURL url("https://example.com"); ASSERT_EQ(origin, url::Origin::Create(url)); @@ -89,15 +89,15 @@ TEST(SmsParserTest, TwoTokens) { base::Optional<url::Origin> origin = - SmsParser::Parse("From: https://a.com From: https://b.com"); + SmsParser::Parse("To: https://a.com To: https://b.com"); GURL url("https://b.com"); ASSERT_EQ(origin, url::Origin::Create(url)); } TEST(SmsParserTest, AppHash) { - base::Optional<url::Origin> origin = SmsParser::Parse( - "<#> Hello World\nFrom: https://example.com?s3LhKBB0M33"); + base::Optional<url::Origin> origin = + SmsParser::Parse("<#> Hello World\nTo: https://example.com?s3LhKBB0M33"); GURL url("https://example.com"); ASSERT_EQ(origin, url::Origin::Create(url));
diff --git a/content/browser/ssl/ssl_client_auth_handler.cc b/content/browser/ssl/ssl_client_auth_handler.cc index e2a1dbd..b8e6b02 100644 --- a/content/browser/ssl/ssl_client_auth_handler.cc +++ b/content/browser/ssl/ssl_client_auth_handler.cc
@@ -56,6 +56,22 @@ DISALLOW_COPY_AND_ASSIGN(ClientCertificateDelegateImpl); }; +// This function is used to pass the UI cancellation callback from the UI thread +// to the SSLClientAuthHandler |handler| on the IO thread. If |handler| has +// already expired, the UI elements are considered orphaned, so we post the +// cancellation callback to the UI thread immediately. +void TrySetCancellationCallback( + const base::WeakPtr<SSLClientAuthHandler>& handler, + base::OnceClosure callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (handler) { + handler->SetCancellationCallback(std::move(callback)); + } else if (callback) { + base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, + std::move(callback)); + } +} + void SelectCertificateOnUIThread( const ResourceRequestInfo::WebContentsGetter& wc_getter, net::SSLCertRequestInfo* cert_request_info, @@ -70,9 +86,19 @@ if (!web_contents) return; - GetContentClient()->browser()->SelectClientCertificate( - web_contents, cert_request_info, std::move(client_certs), - std::move(delegate)); + base::OnceClosure cancellation_callback = + GetContentClient()->browser()->SelectClientCertificate( + web_contents, cert_request_info, std::move(client_certs), + std::move(delegate)); + + // Attempt to pass the callback to |handler|. If |handler| has already been + // destroyed, TrySetCancellationCallback will just invoke the callback. In + // contrast, simply posting SetCancellationCallback to the IO thread would + // result in |cancellation_callback| never being called if |handler| had + // already been destroyed when the task ran. + base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&TrySetCancellationCallback, handler, + std::move(cancellation_callback))); } } // namespace @@ -136,6 +162,10 @@ } SSLClientAuthHandler::~SSLClientAuthHandler() { + if (cancellation_callback_) { + base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, + std::move(cancellation_callback_)); + } } void SSLClientAuthHandler::SelectCertificate() { @@ -145,6 +175,11 @@ core_->GetClientCerts(); } +void SSLClientAuthHandler::SetCancellationCallback(base::OnceClosure callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + cancellation_callback_ = std::move(callback); +} + // static void SSLClientAuthHandler::ContinueWithCertificate( const base::WeakPtr<SSLClientAuthHandler>& handler,
diff --git a/content/browser/ssl/ssl_client_auth_handler.h b/content/browser/ssl/ssl_client_auth_handler.h index 7fb94df..937e2067 100644 --- a/content/browser/ssl/ssl_client_auth_handler.h +++ b/content/browser/ssl/ssl_client_auth_handler.h
@@ -64,6 +64,11 @@ // Selects a certificate and resumes the URL request with that certificate. void SelectCertificate(); + // Sets a UI-thread callback that can be used to close the UI associated with + // this certificate selection. The callback is run when SSLClientAuthHandler + // is destroyed. + void SetCancellationCallback(base::OnceClosure callback); + // Called to continue the request associated with |handler| using |cert|. This // is static to avoid deleting |handler| while it is on the stack. static void ContinueWithCertificate( @@ -87,6 +92,10 @@ // ClientCertStore is in progress. scoped_refptr<Core> core_; + // A callback that may be set by the UI implementation. If set, the callback + // will cancel the dialog corresponding to this certificate request. + base::OnceClosure cancellation_callback_; + ResourceRequestInfo::WebContentsGetter web_contents_getter_; // The certs to choose from.
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index becc966..5cbb7018 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5238,9 +5238,12 @@ } } -void WebContentsImpl::OnDidBlockFramebust(const GURL& url) { +void WebContentsImpl::OnDidBlockNavigation( + const GURL& blocked_url, + const GURL& initiator_url, + blink::NavigationBlockedReason reason) { if (delegate_) - delegate_->OnDidBlockFramebust(this, url); + delegate_->OnDidBlockNavigation(this, blocked_url, initiator_url, reason); } const GURL& WebContentsImpl::GetMainFrameLastCommittedURL() {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 3b7c4a0c..f996bf7 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -57,6 +57,7 @@ #include "ppapi/buildflags/buildflags.h" #include "services/device/public/mojom/geolocation_context.mojom.h" #include "services/metrics/public/cpp/ukm_recorder.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" #include "third_party/blink/public/mojom/choosers/color_chooser.mojom.h" #include "third_party/blink/public/mojom/page/display_cutout.mojom.h" #include "third_party/blink/public/mojom/renderer_preferences.mojom.h" @@ -488,7 +489,9 @@ RenderFrameHost* render_frame_host, const std::string& interface_name, mojo::ScopedMessagePipeHandle* interface_pipe) override; - void OnDidBlockFramebust(const GURL& url) override; + void OnDidBlockNavigation(const GURL& blocked_url, + const GURL& initiator_url, + blink::NavigationBlockedReason reason) override; const GURL& GetMainFrameLastCommittedURL() override; void RenderFrameCreated(RenderFrameHost* render_frame_host) override; void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 4c53747..5c51807 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -54,6 +54,7 @@ #include "mojo/public/cpp/system/message_pipe.h" #include "ppapi/buildflags/buildflags.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/frame/frame_policy.h" #include "third_party/blink/public/common/frame/occlusion_state.h" @@ -162,6 +163,8 @@ IPC_ENUM_TRAITS_MIN_MAX_VALUE(blink::FrameOcclusionState, blink::FrameOcclusionState::kUnknown, blink::FrameOcclusionState::kMaxValue) +IPC_ENUM_TRAITS_MAX_VALUE(blink::NavigationBlockedReason, + blink::NavigationBlockedReason::kMaxValue) IPC_STRUCT_TRAITS_BEGIN(content::NavigationDownloadPolicy) IPC_STRUCT_TRAITS_MEMBER(observed_types) @@ -1476,9 +1479,12 @@ base::Optional<url::Origin> /* top frame origin */, content::ResourceType /* resource type */) -// This frame attempted to navigate the main frame to the given url, even -// though this frame has never received a user gesture. -IPC_MESSAGE_ROUTED1(FrameHostMsg_DidBlockFramebust, GURL /* url */) +// This frame attempted to navigate the main frame from the |initiator_url| to +// the |blocked_url|, but the navigation was blocked because of |reason|. +IPC_MESSAGE_ROUTED3(FrameHostMsg_DidBlockNavigation, + GURL /* blocked_url */, + GURL /* initiator_url */, + blink::NavigationBlockedReason /* reason */) // PlzNavigate // Tells the browser to abort an ongoing renderer-initiated navigation. This is
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 1bbeb6b..440244ed 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -431,11 +431,13 @@ callback.Run(CERTIFICATE_REQUEST_RESULT_TYPE_DENY); } -void ContentBrowserClient::SelectClientCertificate( +base::OnceClosure ContentBrowserClient::SelectClientCertificate( WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs, - std::unique_ptr<ClientCertificateDelegate> delegate) {} + std::unique_ptr<ClientCertificateDelegate> delegate) { + return base::OnceClosure(); +} net::CookieStore* ContentBrowserClient::OverrideCookieStoreForURL( const GURL& url,
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 163694c7..46eed09 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -781,8 +781,12 @@ // Selects a SSL client certificate and returns it to the |delegate|. Note: // |delegate| may be called synchronously or asynchronously. // + // Returns a callback that cancels the UI element corresponding to this + // request. The callback should expect to be invoked on the UI thread. The + // callback may be null. The callback is not required to be invoked. + // // TODO(davidben): Move this hook to WebContentsDelegate. - virtual void SelectClientCertificate( + virtual base::OnceClosure SelectClientCertificate( WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs,
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index ec0252d..7d74692 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h
@@ -24,6 +24,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/previews_state.h" #include "content/public/common/window_container_type.mojom-forward.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" #include "third_party/blink/public/common/manifest/web_display_mode.h" #include "third_party/blink/public/common/mediastream/media_stream_request.h" #include "third_party/blink/public/mojom/choosers/color_chooser.mojom-forward.h" @@ -573,10 +574,14 @@ // Called when a suspicious navigation of the main frame has been blocked. // Allows the delegate to provide some UI to let the user know about the - // blocked navigation and give them the option to recover from it. The given - // URL is the blocked navigation target. - virtual void OnDidBlockFramebust(WebContents* web_contents, const GURL& url) { - } + // blocked navigation and give them the option to recover from it. + // |blocked_url| is the blocked navigation target, |initiator_url| is the URL + // of the frame initiating the navigation, |reason| specifies why the + // navigation was blocked. + virtual void OnDidBlockNavigation(WebContents* web_contents, + const GURL& blocked_url, + const GURL& initiator_url, + blink::NavigationBlockedReason reason) {} // Reports that passive mixed content was found at the specified url. virtual void PassiveInsecureContentFound(const GURL& resource_url) {}
diff --git a/content/public/common/resource_load_info.mojom b/content/public/common/resource_load_info.mojom index 6e17f0c..5194656 100644 --- a/content/public/common/resource_load_info.mojom +++ b/content/public/common/resource_load_info.mojom
@@ -9,6 +9,7 @@ import "services/network/public/mojom/ip_address.mojom"; import "services/network/public/mojom/ip_endpoint.mojom"; import "services/network/public/mojom/network_param.mojom"; +import "services/network/public/mojom/url_loader.mojom"; import "url/mojom/url.mojom"; // Network related information reported for loads and redirects. @@ -55,6 +56,9 @@ // The resource type. ResourceType resource_type; + // Loading priority of the corresponding request. + network.mojom.RequestPriority request_priority; + // The mime type. string mime_type;
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h index 6ef4f14..bfc62d17 100644 --- a/content/public/renderer/content_renderer_client.h +++ b/content/public/renderer/content_renderer_client.h
@@ -45,6 +45,7 @@ class WebLocalFrame; class WebPlugin; class WebPrescientNetworking; +class WebServiceWorkerContextProxy; class WebSpeechSynthesizer; class WebSpeechSynthesizerClient; class WebMediaStreamRendererFactory; @@ -336,8 +337,11 @@ // Notifies that a service worker context has been created. This function // is called from the worker thread. + // |context_proxy| is valid until + // WillDestroyServiceWorkerContextOnWorkerThread() is called. virtual void DidInitializeServiceWorkerContextOnWorkerThread( - v8::Local<v8::Context> context, + blink::WebServiceWorkerContextProxy* context_proxy, + v8::Local<v8::Context> v8_context, int64_t service_worker_version_id, const GURL& service_worker_scope, const GURL& script_url) {}
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 2947bc8e..fed51f79 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -2765,7 +2765,7 @@ // Wait for the desired state if needed. if (current_state_ < desired_state_) { DCHECK(!quit_closure_); - base::RunLoop run_loop(message_loop_type_); + base::RunLoop run_loop; quit_closure_ = run_loop.QuitClosure(); run_loop.Run(); } @@ -2797,10 +2797,6 @@ return true; } -void TestNavigationManager::AllowNestableTasks() { - message_loop_type_ = base::RunLoop::Type::kNestableTasksAllowed; -} - NavigationHandleCommitObserver::NavigationHandleCommitObserver( content::WebContents* web_contents, const GURL& url)
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 8456549..8ba8639 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -1380,10 +1380,6 @@ // Whether the navigation successfully committed. bool was_successful() const { return was_successful_; } - // Allows nestable tasks when running a message loop in the Wait* functions. - // This is useful for utilizing this class from within another message loop. - void AllowNestableTasks(); - protected: // Derived classes can override if they want to filter out navigations. This // is called from DidStartNavigation. @@ -1425,7 +1421,6 @@ NavigationState desired_state_; bool was_successful_ = false; base::OnceClosure quit_closure_; - base::RunLoop::Type message_loop_type_ = base::RunLoop::Type::kDefault; base::WeakPtrFactory<TestNavigationManager> weak_factory_;
diff --git a/content/renderer/loader/navigation_body_loader.cc b/content/renderer/loader/navigation_body_loader.cc index 6b6a6ea..3571acf 100644 --- a/content/renderer/loader/navigation_body_loader.cc +++ b/content/renderer/loader/navigation_body_loader.cc
@@ -37,8 +37,8 @@ !commit_params.original_method.empty() ? commit_params.original_method : common_params.method, common_params.referrer.url, - is_main_frame ? ResourceType::kMainFrame : ResourceType::kSubFrame); - + is_main_frame ? ResourceType::kMainFrame : ResourceType::kSubFrame, + is_main_frame ? net::HIGHEST : net::LOWEST); size_t redirect_count = commit_params.redirect_response.size(); navigation_params->redirects.reserve(redirect_count); navigation_params->redirects.resize(redirect_count);
diff --git a/content/renderer/loader/resource_dispatcher.cc b/content/renderer/loader/resource_dispatcher.cc index 62a83b1f..e8514fae 100644 --- a/content/renderer/loader/resource_dispatcher.cc +++ b/content/renderer/loader/resource_dispatcher.cc
@@ -523,7 +523,7 @@ pending_request->resource_load_info = NotifyResourceLoadInitiated( request->render_frame_id, request_id, request->url, request->method, - request->referrer, pending_request->resource_type); + request->referrer, pending_request->resource_type, request->priority); pending_request->previews_state = request->previews_state;
diff --git a/content/renderer/loader/resource_load_stats.cc b/content/renderer/loader/resource_load_stats.cc index d0567fd..774cd4c 100644 --- a/content/renderer/loader/resource_load_stats.cc +++ b/content/renderer/loader/resource_load_stats.cc
@@ -106,7 +106,8 @@ const GURL& request_url, const std::string& http_method, const GURL& referrer, - ResourceType resource_type) { + ResourceType resource_type, + net::RequestPriority request_priority) { auto resource_load_info = mojom::ResourceLoadInfo::New(); resource_load_info->method = http_method; resource_load_info->original_url = request_url; @@ -115,6 +116,7 @@ resource_load_info->request_id = request_id; resource_load_info->referrer = referrer; resource_load_info->network_info = mojom::CommonNetworkInfo::New(); + resource_load_info->request_priority = request_priority; return resource_load_info; }
diff --git a/content/renderer/loader/resource_load_stats.h b/content/renderer/loader/resource_load_stats.h index 966f94b1..df0b175 100644 --- a/content/renderer/loader/resource_load_stats.h +++ b/content/renderer/loader/resource_load_stats.h
@@ -40,7 +40,8 @@ const GURL& request_url, const std::string& http_method, const GURL& referrer, - ResourceType resource_type); + ResourceType resource_type, + net::RequestPriority request_priority); void NotifyResourceRedirectReceived( int render_frame_id,
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc index 491b692..dd1cbcf5 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
@@ -258,76 +258,6 @@ .video_encode_accelerator_supported_profiles)); } -bool GpuVideoAcceleratorFactoriesImpl::CreateTextures( - int32_t count, - const gfx::Size& size, - std::vector<uint32_t>* texture_ids, - std::vector<gpu::Mailbox>* texture_mailboxes, - uint32_t texture_target) { - DCHECK(task_runner_->BelongsToCurrentThread()); - DCHECK(texture_target); - - if (CheckContextLost()) - return false; - gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); - texture_ids->resize(count); - texture_mailboxes->resize(count); - gles2->GenTextures(count, &texture_ids->at(0)); - for (int i = 0; i < count; ++i) { - gles2->ActiveTexture(GL_TEXTURE0); - uint32_t texture_id = texture_ids->at(i); - gles2->BindTexture(texture_target, texture_id); - gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (texture_target == GL_TEXTURE_2D) { - gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(), - 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - } - gles2->ProduceTextureDirectCHROMIUM(texture_id, - texture_mailboxes->at(i).name); - } - - // We need ShallowFlushCHROMIUM() here to order the command buffer commands - // with respect to IPC to the GPU process, to guarantee that the decoder in - // the GPU process can use these textures as soon as it receives IPC - // notification of them. - gles2->ShallowFlushCHROMIUM(); - DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); - return true; -} - -void GpuVideoAcceleratorFactoriesImpl::DeleteTexture(uint32_t texture_id) { - DCHECK(task_runner_->BelongsToCurrentThread()); - if (CheckContextLost()) - return; - - gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); - gles2->DeleteTextures(1, &texture_id); - DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); -} - -gpu::SyncToken GpuVideoAcceleratorFactoriesImpl::CreateSyncToken() { - gpu::SyncToken sync_token; - context_provider_->ContextGL()->GenSyncTokenCHROMIUM(sync_token.GetData()); - return sync_token; -} - -void GpuVideoAcceleratorFactoriesImpl::WaitSyncToken( - const gpu::SyncToken& sync_token) { - DCHECK(task_runner_->BelongsToCurrentThread()); - if (CheckContextLost()) - return; - - gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); - gles2->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); - - // Callers expect the WaitSyncToken to affect the next IPCs. Make sure to - // flush the command buffers to ensure that. - gles2->ShallowFlushCHROMIUM(); -} - void GpuVideoAcceleratorFactoriesImpl::SignalSyncToken( const gpu::SyncToken& sync_token, base::OnceClosure callback) { @@ -339,14 +269,6 @@ std::move(callback)); } -void GpuVideoAcceleratorFactoriesImpl::ShallowFlushCHROMIUM() { - DCHECK(task_runner_->BelongsToCurrentThread()); - if (CheckContextLost()) - return; - - context_provider_->ContextGL()->ShallowFlushCHROMIUM(); -} - std::unique_ptr<gfx::GpuMemoryBuffer> GpuVideoAcceleratorFactoriesImpl::CreateGpuMemoryBuffer( const gfx::Size& size, @@ -431,10 +353,6 @@ return media::GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED; } -gpu::gles2::GLES2Interface* GpuVideoAcceleratorFactoriesImpl::ContextGL() { - return CheckContextLost() ? nullptr : context_provider_->ContextGL(); -} - gpu::SharedImageInterface* GpuVideoAcceleratorFactoriesImpl::SharedImageInterface() { return CheckContextLost() ? nullptr @@ -472,12 +390,6 @@ return CheckContextLost() ? nullptr : context_provider_; } -gpu::ContextSupport* -GpuVideoAcceleratorFactoriesImpl::GetMediaContextProviderContextSupport() { - auto context_provider = GetMediaContextProvider(); - return context_provider ? context_provider->ContextSupport() : nullptr; -} - void GpuVideoAcceleratorFactoriesImpl::SetRenderingColorSpace( const gfx::ColorSpace& color_space) { rendering_color_space_ = color_space;
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h index d71fb02..0168d66 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h
@@ -79,19 +79,8 @@ const media::VideoDecoderConfig& config) override; std::unique_ptr<media::VideoEncodeAccelerator> CreateVideoEncodeAccelerator() override; - // Creates textures and produces them into mailboxes. Returns true on success - // or false on failure. - bool CreateTextures(int32_t count, - const gfx::Size& size, - std::vector<uint32_t>* texture_ids, - std::vector<gpu::Mailbox>* texture_mailboxes, - uint32_t texture_target) override; - void DeleteTexture(uint32_t texture_id) override; - gpu::SyncToken CreateSyncToken() override; - void WaitSyncToken(const gpu::SyncToken& sync_token) override; void SignalSyncToken(const gpu::SyncToken& sync_token, base::OnceClosure callback) override; - void ShallowFlushCHROMIUM() override; std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer( const gfx::Size& size, @@ -104,9 +93,6 @@ OutputFormat VideoFrameOutputFormat( media::VideoPixelFormat pixel_format) override; - // Called on the media thread. Returns the GLES2Interface unless the - // ContextProvider has been lost, in which case it returns null. - gpu::gles2::GLES2Interface* ContextGL() override; // Called on the media thread. Returns the SharedImageInterface unless the // ContextProvider has been lost, in which case it returns null. gpu::SharedImageInterface* SharedImageInterface() override; @@ -128,7 +114,6 @@ scoped_refptr<viz::ContextProviderCommandBuffer> GetMediaContextProvider() override; - gpu::ContextSupport* GetMediaContextProviderContextSupport() override; void SetRenderingColorSpace(const gfx::ColorSpace& color_space) override;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index ceeca7a0..a88fa307 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -5071,8 +5071,12 @@ return static_cast<WebURLRequest::PreviewsState>(previews_state_); } -void RenderFrameImpl::DidBlockFramebust(const WebURL& url) { - Send(new FrameHostMsg_DidBlockFramebust(GetRoutingID(), url)); +void RenderFrameImpl::DidBlockNavigation( + const WebURL& blocked_url, + const WebURL& initiator_url, + blink::NavigationBlockedReason reason) { + Send(new FrameHostMsg_DidBlockNavigation(GetRoutingID(), blocked_url, + initiator_url, reason)); } void RenderFrameImpl::NavigateBackForwardSoon(int offset,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index c36bd14..fb6ecb2 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -777,7 +777,9 @@ void SetEffectiveConnectionTypeForTesting( blink::WebEffectiveConnectionType) override; blink::WebURLRequest::PreviewsState GetPreviewsStateForFrame() const override; - void DidBlockFramebust(const blink::WebURL& url) override; + void DidBlockNavigation(const blink::WebURL& blocked_url, + const blink::WebURL& initiator_url, + blink::NavigationBlockedReason reason) override; void NavigateBackForwardSoon(int offset, bool has_user_gesture) override; base::UnguessableToken GetDevToolsFrameToken() override; void RenderFallbackContentInParentProcess() override;
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index 5d340e4..e99b957b 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -316,13 +316,14 @@ } void ServiceWorkerContextClient::DidInitializeWorkerContext( - v8::Local<v8::Context> context) { + blink::WebServiceWorkerContextProxy* context_proxy, + v8::Local<v8::Context> v8_context) { DCHECK(worker_task_runner_->RunsTasksInCurrentSequence()); GetContentClient() ->renderer() ->DidInitializeServiceWorkerContextOnWorkerThread( - context, service_worker_version_id_, service_worker_scope_, - script_url_); + context_proxy, v8_context, service_worker_version_id_, + service_worker_scope_, script_url_); } void ServiceWorkerContextClient::WillDestroyWorkerContext(
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index 91354b2..df5ebdf 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -114,7 +114,9 @@ void WillEvaluateScript() override; void DidEvaluateScript(bool success) override; void WillInitializeWorkerContext() override; - void DidInitializeWorkerContext(v8::Local<v8::Context> context) override; + void DidInitializeWorkerContext( + blink::WebServiceWorkerContextProxy* context_proxy, + v8::Local<v8::Context> v8_context) override; void WillDestroyWorkerContext(v8::Local<v8::Context> context) override; void WorkerContextDestroyed() override; void CountFeature(blink::mojom::WebFeature feature) override;
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 079604f..9ee532d 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -410,13 +410,14 @@ return GeneratedCodeCacheSettings(true, 0, context->GetPath()); } -void ShellContentBrowserClient::SelectClientCertificate( +base::OnceClosure ShellContentBrowserClient::SelectClientCertificate( WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs, std::unique_ptr<ClientCertificateDelegate> delegate) { if (select_client_certificate_callback_) std::move(select_client_certificate_callback_).Run(); + return base::OnceClosure(); } SpeechRecognitionManagerDelegate*
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h index 8b0949f..a8112f7 100644 --- a/content/shell/browser/shell_content_browser_client.h +++ b/content/shell/browser/shell_content_browser_client.h
@@ -65,7 +65,7 @@ storage::OptionalQuotaSettingsCallback callback) override; GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings( content::BrowserContext* context) override; - void SelectClientCertificate( + base::OnceClosure SelectClientCertificate( WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs,
diff --git a/content/test/data/indexeddb/open_missing_table.js b/content/test/data/indexeddb/open_missing_table.js index ad76f1a..1a1f4b9 100644 --- a/content/test/data/indexeddb/open_missing_table.js +++ b/content/test/data/indexeddb/open_missing_table.js
@@ -14,8 +14,7 @@ function upgradeNeeded(evt) { event = evt; shouldBe("event.dataLoss", "'total'"); - shouldBe("event.dataLossMessage", - "'IndexedDB (database was corrupt): missing files'"); + shouldBe("event.dataLossMessage", "'missing files'"); gotUpgradeNeeded = true; }
diff --git a/device/fido/authenticator_supported_options.cc b/device/fido/authenticator_supported_options.cc index 24459b0..0656016 100644 --- a/device/fido/authenticator_supported_options.cc +++ b/device/fido/authenticator_supported_options.cc
@@ -61,6 +61,17 @@ using BioEnrollmentAvailability = AuthenticatorSupportedOptions::BioEnrollmentAvailability; + switch (options.bio_enrollment_availability) { + case BioEnrollmentAvailability::kSupportedAndProvisioned: + option_map.emplace(kBioEnrollmentMapKey, true); + break; + case BioEnrollmentAvailability::kSupportedButUnprovisioned: + option_map.emplace(kBioEnrollmentMapKey, false); + break; + case BioEnrollmentAvailability::kNotSupported: + break; + } + switch (options.bio_enrollment_availability_preview) { case BioEnrollmentAvailability::kSupportedAndProvisioned: option_map.emplace(kBioEnrollmentPreviewMapKey, true);
diff --git a/device/fido/authenticator_supported_options.h b/device/fido/authenticator_supported_options.h index fcfa001..04d721f 100644 --- a/device/fido/authenticator_supported_options.h +++ b/device/fido/authenticator_supported_options.h
@@ -66,8 +66,12 @@ // Indicates whether the authenticator supports the vendor-specific preview of // the CTAP2 authenticatorCredentialManagement command. bool supports_credential_management_preview = false; - // Indicates whether the authenticator supports the vendor-specific preview of - // the CTAP 2.1 authenticatorBioEnrollment command + // Indicates whether the authenticator supports the CTAP 2.1 + // authenticatorBioEnrollment command. + BioEnrollmentAvailability bio_enrollment_availability = + BioEnrollmentAvailability::kNotSupported; + // Indicates whether the authenticator supports the CTAP 2.1 vendor-specific + // authenticatorBioEnrollment command. BioEnrollmentAvailability bio_enrollment_availability_preview = BioEnrollmentAvailability::kNotSupported; // supports_cred_protect is true if the authenticator supports the
diff --git a/device/fido/bio/enrollment.cc b/device/fido/bio/enrollment.cc index 1af1213..ccd6803 100644 --- a/device/fido/bio/enrollment.cc +++ b/device/fido/bio/enrollment.cc
@@ -28,15 +28,15 @@ } // static -BioEnrollmentRequest BioEnrollmentRequest::ForGetModality() { - BioEnrollmentRequest request; +BioEnrollmentRequest BioEnrollmentRequest::ForGetModality(Version version) { + BioEnrollmentRequest request(version); request.get_modality = true; return request; } // static -BioEnrollmentRequest BioEnrollmentRequest::ForGetSensorInfo() { - BioEnrollmentRequest request; +BioEnrollmentRequest BioEnrollmentRequest::ForGetSensorInfo(Version version) { + BioEnrollmentRequest request(version); request.modality = BioEnrollmentModality::kFingerprint; request.subcommand = BioEnrollmentSubCommand::kGetFingerprintSensorInfo; return request; @@ -44,8 +44,9 @@ // static BioEnrollmentRequest BioEnrollmentRequest::ForEnrollBegin( + Version version, const pin::TokenResponse& token) { - BioEnrollmentRequest request; + BioEnrollmentRequest request(version); request.subcommand = BioEnrollmentSubCommand::kEnrollBegin; SetPinAuth(&request, token); return request; @@ -53,9 +54,10 @@ // static BioEnrollmentRequest BioEnrollmentRequest::ForEnrollNextSample( + Version version, const pin::TokenResponse& token, std::vector<uint8_t> template_id) { - BioEnrollmentRequest request; + BioEnrollmentRequest request(version); request.subcommand = BioEnrollmentSubCommand::kEnrollCaptureNextSample; request.params = cbor::Value::MapValue(); request.params->emplace( @@ -66,8 +68,8 @@ } // static -BioEnrollmentRequest BioEnrollmentRequest::ForCancel() { - BioEnrollmentRequest request; +BioEnrollmentRequest BioEnrollmentRequest::ForCancel(Version version) { + BioEnrollmentRequest request(version); request.modality = BioEnrollmentModality::kFingerprint; request.subcommand = BioEnrollmentSubCommand::kCancelCurrentEnrollment; return request; @@ -75,8 +77,9 @@ // static BioEnrollmentRequest BioEnrollmentRequest::ForEnumerate( + Version version, const pin::TokenResponse& token) { - BioEnrollmentRequest request; + BioEnrollmentRequest request(version); request.subcommand = BioEnrollmentSubCommand::kEnumerateEnrollments; SetPinAuth(&request, token); return request; @@ -84,10 +87,11 @@ // static BioEnrollmentRequest BioEnrollmentRequest::ForRename( + Version version, const pin::TokenResponse& token, std::vector<uint8_t> id, std::string name) { - BioEnrollmentRequest request; + BioEnrollmentRequest request(version); request.subcommand = BioEnrollmentSubCommand::kSetFriendlyName; request.params = cbor::Value::MapValue(); request.params->emplace( @@ -99,9 +103,10 @@ // static BioEnrollmentRequest BioEnrollmentRequest::ForDelete( + Version version, const pin::TokenResponse& token, std::vector<uint8_t> id) { - BioEnrollmentRequest request; + BioEnrollmentRequest request(version); request.subcommand = BioEnrollmentSubCommand::kRemoveEnrollment; request.params = cbor::Value::MapValue(); request.params->emplace( @@ -114,7 +119,7 @@ BioEnrollmentRequest::BioEnrollmentRequest(BioEnrollmentRequest&&) = default; BioEnrollmentRequest& BioEnrollmentRequest::operator=(BioEnrollmentRequest&&) = default; -BioEnrollmentRequest::BioEnrollmentRequest() = default; +BioEnrollmentRequest::BioEnrollmentRequest(Version v) : version(v) {} BioEnrollmentRequest::~BioEnrollmentRequest() = default; template <typename T> @@ -297,7 +302,9 @@ map.emplace(static_cast<int>(Key::kGetModality), *request.get_modality); } - return {CtapRequestCommand::kAuthenticatorBioEnrollmentPreview, + return {request.version == BioEnrollmentRequest::Version::kDefault + ? CtapRequestCommand::kAuthenticatorBioEnrollment + : CtapRequestCommand::kAuthenticatorBioEnrollmentPreview, cbor::Value(std::move(map))}; }
diff --git a/device/fido/bio/enrollment.h b/device/fido/bio/enrollment.h index f58dcf3..9f4160bf 100644 --- a/device/fido/bio/enrollment.h +++ b/device/fido/bio/enrollment.h
@@ -97,24 +97,32 @@ }; struct BioEnrollmentRequest { - static std::pair<CtapRequestCommand, base::Optional<cbor::Value>> - EncodeAsCBOR(const BioEnrollmentRequest& request); + enum Version { + kDefault, + kPreview, + }; - static BioEnrollmentRequest ForGetModality(); - static BioEnrollmentRequest ForGetSensorInfo(); + static BioEnrollmentRequest ForGetModality(Version); + static BioEnrollmentRequest ForGetSensorInfo(Version); static BioEnrollmentRequest ForEnrollBegin( + Version, const pin::TokenResponse& pin_token); static BioEnrollmentRequest ForEnrollNextSample( + Version, const pin::TokenResponse& pin_token, std::vector<uint8_t> template_id); - static BioEnrollmentRequest ForCancel(); - static BioEnrollmentRequest ForEnumerate(const pin::TokenResponse& token); - static BioEnrollmentRequest ForRename(const pin::TokenResponse& token, + static BioEnrollmentRequest ForCancel(Version); + static BioEnrollmentRequest ForEnumerate(Version, + const pin::TokenResponse& token); + static BioEnrollmentRequest ForRename(Version, + const pin::TokenResponse& token, std::vector<uint8_t> id, std::string name); - static BioEnrollmentRequest ForDelete(const pin::TokenResponse& token, + static BioEnrollmentRequest ForDelete(Version, + const pin::TokenResponse& token, std::vector<uint8_t> id); + Version version; base::Optional<BioEnrollmentModality> modality; base::Optional<BioEnrollmentSubCommand> subcommand; base::Optional<cbor::Value::MapValue> params; @@ -127,7 +135,7 @@ ~BioEnrollmentRequest(); private: - BioEnrollmentRequest(); + BioEnrollmentRequest(Version); }; struct COMPONENT_EXPORT(DEVICE_FIDO) BioEnrollmentResponse {
diff --git a/device/fido/bio/enrollment_handler.cc b/device/fido/bio/enrollment_handler.cc index 78c3519..97f9b4b 100644 --- a/device/fido/bio/enrollment_handler.cc +++ b/device/fido/bio/enrollment_handler.cc
@@ -32,30 +32,14 @@ void BioEnrollmentHandler::GetModality(ResponseCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker); - - if (!authenticator_ || - authenticator_->Options()->bio_enrollment_availability_preview == - AuthenticatorSupportedOptions::BioEnrollmentAvailability:: - kNotSupported) { - std::move(callback).Run(CtapDeviceResponseCode::kCtap2ErrUnsupportedOption, - base::nullopt); - } else { - authenticator_->GetModality(std::move(callback)); - } + DCHECK(authenticator_); + authenticator_->GetModality(std::move(callback)); } void BioEnrollmentHandler::GetSensorInfo(ResponseCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker); - - if (!authenticator_ || - authenticator_->Options()->bio_enrollment_availability_preview == - AuthenticatorSupportedOptions::BioEnrollmentAvailability:: - kNotSupported) { - std::move(callback).Run(CtapDeviceResponseCode::kCtap2ErrUnsupportedOption, - base::nullopt); - } else { - authenticator_->GetSensorInfo(std::move(callback)); - } + DCHECK(authenticator_); + authenticator_->GetSensorInfo(std::move(callback)); } void BioEnrollmentHandler::EnrollTemplate(ResponseCallback callback) { @@ -135,9 +119,12 @@ CancelActiveAuthenticators(authenticator->GetId()); if (!authenticator->Options() || - authenticator->Options()->bio_enrollment_availability_preview == - AuthenticatorSupportedOptions::BioEnrollmentAvailability:: - kNotSupported) { + (authenticator->Options()->bio_enrollment_availability == + AuthenticatorSupportedOptions::BioEnrollmentAvailability:: + kNotSupported && + authenticator->Options()->bio_enrollment_availability_preview == + AuthenticatorSupportedOptions::BioEnrollmentAvailability:: + kNotSupported)) { std::move(error_callback_) .Run(FidoReturnCode::kAuthenticatorMissingBioEnrollment); return;
diff --git a/device/fido/bio/enrollment_handler_unittest.cc b/device/fido/bio/enrollment_handler_unittest.cc index 32a2ef4..7522235 100644 --- a/device/fido/bio/enrollment_handler_unittest.cc +++ b/device/fido/bio/enrollment_handler_unittest.cc
@@ -54,7 +54,7 @@ TEST_F(BioEnrollmentHandlerTest, Modality) { VirtualCtap2Device::Config config; config.pin_support = true; - config.bio_enrollment_support = true; + config.bio_enrollment_preview_support = true; virtual_device_factory_.SetCtap2Config(config); @@ -85,7 +85,7 @@ TEST_F(BioEnrollmentHandlerTest, FingerprintSensorInfo) { VirtualCtap2Device::Config config; config.pin_support = true; - config.bio_enrollment_support = true; + config.bio_enrollment_preview_support = true; virtual_device_factory_.SetCtap2Config(config); @@ -122,33 +122,13 @@ error_callback_.WaitForCallback(); EXPECT_EQ(error_callback_.value(), FidoReturnCode::kAuthenticatorMissingBioEnrollment); - - // Test unsupported bio-enrollment command. - test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>> - cb0; - handler->GetModality(cb0.callback()); - cb0.WaitForCallback(); - - EXPECT_EQ(cb0.status(), CtapDeviceResponseCode::kCtap2ErrUnsupportedOption); - EXPECT_FALSE(cb0.value()); - - // Test second command - handler should not crash after last command. - test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>> - cb1; - handler->GetSensorInfo(cb1.callback()); - cb1.WaitForCallback(); - - EXPECT_EQ(cb1.status(), CtapDeviceResponseCode::kCtap2ErrUnsupportedOption); - EXPECT_FALSE(cb1.value()); } // Tests fingerprint enrollment lifecycle. TEST_F(BioEnrollmentHandlerTest, Enroll) { VirtualCtap2Device::Config config; config.pin_support = true; - config.bio_enrollment_support = true; + config.bio_enrollment_preview_support = true; virtual_device_factory_.SetCtap2Config(config); @@ -176,7 +156,7 @@ TEST_F(BioEnrollmentHandlerTest, CancelNoEnroll) { VirtualCtap2Device::Config config; config.pin_support = true; - config.bio_enrollment_support = true; + config.bio_enrollment_preview_support = true; virtual_device_factory_.SetCtap2Config(config); @@ -194,7 +174,7 @@ TEST_F(BioEnrollmentHandlerTest, Enumerate) { VirtualCtap2Device::Config config; config.pin_support = true; - config.bio_enrollment_support = true; + config.bio_enrollment_preview_support = true; virtual_device_factory_.SetCtap2Config(config); @@ -223,7 +203,7 @@ TEST_F(BioEnrollmentHandlerTest, Rename) { VirtualCtap2Device::Config config; config.pin_support = true; - config.bio_enrollment_support = true; + config.bio_enrollment_preview_support = true; virtual_device_factory_.SetCtap2Config(config); @@ -249,7 +229,7 @@ TEST_F(BioEnrollmentHandlerTest, Delete) { VirtualCtap2Device::Config config; config.pin_support = true; - config.bio_enrollment_support = true; + config.bio_enrollment_preview_support = true; virtual_device_factory_.SetCtap2Config(config); @@ -271,5 +251,24 @@ EXPECT_EQ(cb1.value(), CtapDeviceResponseCode::kCtap2ErrInvalidOption); } +// Test cancelling using the non-preview command. +TEST_F(BioEnrollmentHandlerTest, NonPreviewCancel) { + VirtualCtap2Device::Config config; + config.pin_support = true; + config.bio_enrollment_support = true; + + virtual_device_factory_.SetCtap2Config(config); + + auto handler = MakeHandler(); + ready_callback_.WaitForCallback(); + + // Cancel enrollment. + test::ValueCallbackReceiver<CtapDeviceResponseCode> cb; + handler->Cancel(cb.callback()); + + cb.WaitForCallback(); + EXPECT_EQ(cb.value(), CtapDeviceResponseCode::kSuccess); +} + } // namespace } // namespace device
diff --git a/device/fido/device_response_converter.cc b/device/fido/device_response_converter.cc index 6611d4d..86b3518 100644 --- a/device/fido/device_response_converter.cc +++ b/device/fido/device_response_converter.cc
@@ -301,7 +301,20 @@ option_map_it->second.GetBool(); } - // TODO(noviv) add support for kBioEnrollmentMapKey + option_map_it = option_map.find(CBOR(kBioEnrollmentMapKey)); + if (option_map_it != option_map.end()) { + if (!option_map_it->second.is_bool()) { + return base::nullopt; + } + using Availability = + AuthenticatorSupportedOptions::BioEnrollmentAvailability; + + options.bio_enrollment_availability = + option_map_it->second.GetBool() + ? Availability::kSupportedAndProvisioned + : Availability::kSupportedButUnprovisioned; + } + option_map_it = option_map.find(CBOR(kBioEnrollmentPreviewMapKey)); if (option_map_it != option_map.end()) { if (!option_map_it->second.is_bool()) {
diff --git a/device/fido/fido_constants.cc b/device/fido/fido_constants.cc index e0a3261..a2151d2 100644 --- a/device/fido/fido_constants.cc +++ b/device/fido/fido_constants.cc
@@ -29,6 +29,7 @@ const char kCredentialAlgorithmMapKey[] = "alg"; const char kCredentialManagementMapKey[] = "credMgmt"; const char kCredentialManagementPreviewMapKey[] = "credentialMgmtPreview"; +const char kBioEnrollmentMapKey[] = "bioEnroll"; const char kBioEnrollmentPreviewMapKey[] = "userVerificationMgmtPreview"; const base::TimeDelta kDeviceTimeout = base::TimeDelta::FromSeconds(10);
diff --git a/device/fido/fido_constants.h b/device/fido/fido_constants.h index 3a932d8..48b2ce0a 100644 --- a/device/fido/fido_constants.h +++ b/device/fido/fido_constants.h
@@ -252,6 +252,7 @@ kAuthenticatorGetInfo = 0x04, kAuthenticatorClientPin = 0x06, kAuthenticatorReset = 0x07, + kAuthenticatorBioEnrollment = 0x09, kAuthenticatorBioEnrollmentPreview = 0x40, kAuthenticatorCredentialManagement = 0x0a, kAuthenticatorCredentialManagementPreview = 0x41, @@ -325,6 +326,7 @@ COMPONENT_EXPORT(DEVICE_FIDO) extern const char kCredentialManagementMapKey[]; COMPONENT_EXPORT(DEVICE_FIDO) extern const char kCredentialManagementPreviewMapKey[]; +COMPONENT_EXPORT(DEVICE_FIDO) extern const char kBioEnrollmentMapKey[]; COMPONENT_EXPORT(DEVICE_FIDO) extern const char kBioEnrollmentPreviewMapKey[]; // HID transport specific constants.
diff --git a/device/fido/fido_device_authenticator.cc b/device/fido/fido_device_authenticator.cc index a3e09286..25009de 100644 --- a/device/fido/fido_device_authenticator.cc +++ b/device/fido/fido_device_authenticator.cc
@@ -492,35 +492,36 @@ /*string_fixup_predicate=*/nullptr); } -void FidoDeviceAuthenticator::GetModality(BioEnrollmentCallback callback) { - DCHECK( - Options()->bio_enrollment_availability_preview != - AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported); +// Helper method for determining correct bio enrollment version. +static BioEnrollmentRequest::Version GetBioEnrollmentRequestVersion( + const AuthenticatorSupportedOptions& options) { + return options.bio_enrollment_availability != + AuthenticatorSupportedOptions::BioEnrollmentAvailability:: + kNotSupported + ? BioEnrollmentRequest::kDefault + : BioEnrollmentRequest::kPreview; +} +void FidoDeviceAuthenticator::GetModality(BioEnrollmentCallback callback) { RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>( - BioEnrollmentRequest::ForGetModality(), std::move(callback), - base::BindOnce(&BioEnrollmentResponse::Parse)); + BioEnrollmentRequest::ForGetModality( + GetBioEnrollmentRequestVersion(*Options())), + std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse)); } void FidoDeviceAuthenticator::GetSensorInfo(BioEnrollmentCallback callback) { - DCHECK( - Options()->bio_enrollment_availability_preview != - AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported); - RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>( - BioEnrollmentRequest::ForGetSensorInfo(), std::move(callback), - base::BindOnce(&BioEnrollmentResponse::Parse)); + BioEnrollmentRequest::ForGetSensorInfo( + GetBioEnrollmentRequestVersion(*Options())), + std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse)); } void FidoDeviceAuthenticator::BioEnrollFingerprint( const pin::TokenResponse& response, BioEnrollmentCallback callback) { - DCHECK( - Options()->bio_enrollment_availability_preview != - AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported); - RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>( - BioEnrollmentRequest::ForEnrollBegin(response), + BioEnrollmentRequest::ForEnrollBegin( + GetBioEnrollmentRequestVersion(*Options()), response), base::BindOnce(&FidoDeviceAuthenticator::OnBioEnroll, weak_factory_.GetWeakPtr(), std::move(response), std::move(callback), @@ -530,16 +531,13 @@ void FidoDeviceAuthenticator::BioEnrollRename( const pin::TokenResponse& response, - std::vector<uint8_t> template_id, + std::vector<uint8_t> id, std::string name, BioEnrollmentCallback callback) { - DCHECK( - Options()->bio_enrollment_availability_preview != - AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported); - RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>( - BioEnrollmentRequest::ForRename(response, std::move(template_id), - std::move(name)), + BioEnrollmentRequest::ForRename( + GetBioEnrollmentRequestVersion(*Options()), response, std::move(id), + std::move(name)), std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse)); } @@ -547,17 +545,15 @@ const pin::TokenResponse& response, std::vector<uint8_t> template_id, BioEnrollmentCallback callback) { - DCHECK( - Options()->bio_enrollment_availability_preview != - AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported); - RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>( - BioEnrollmentRequest::ForDelete(response, std::move(template_id)), + BioEnrollmentRequest::ForDelete( + GetBioEnrollmentRequestVersion(*Options()), response, + std::move(template_id)), std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse)); } void FidoDeviceAuthenticator::OnBioEnroll( - pin::TokenResponse token, + pin::TokenResponse response, BioEnrollmentCallback callback, base::Optional<std::vector<uint8_t>> current_template_id, CtapDeviceResponseCode code, @@ -577,36 +573,32 @@ current_template_id = *bio->template_id; } - auto request = - BioEnrollmentRequest::ForEnrollNextSample(token, *current_template_id); + auto request = BioEnrollmentRequest::ForEnrollNextSample( + GetBioEnrollmentRequestVersion(*Options()), response, + *current_template_id); + RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>( std::move(request), base::BindOnce(&FidoDeviceAuthenticator::OnBioEnroll, - weak_factory_.GetWeakPtr(), std::move(token), + weak_factory_.GetWeakPtr(), std::move(response), std::move(callback), std::move(current_template_id)), base::BindOnce(&BioEnrollmentResponse::Parse)); } void FidoDeviceAuthenticator::BioEnrollCancel(BioEnrollmentCallback callback) { - DCHECK( - Options()->bio_enrollment_availability_preview != - AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported); - RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>( - BioEnrollmentRequest::ForCancel(), std::move(callback), - base::BindOnce(&BioEnrollmentResponse::Parse)); + BioEnrollmentRequest::ForCancel( + GetBioEnrollmentRequestVersion(*Options())), + std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse)); } void FidoDeviceAuthenticator::BioEnrollEnumerate( - const pin::TokenResponse& token, + const pin::TokenResponse& response, BioEnrollmentCallback callback) { - DCHECK( - Options()->bio_enrollment_availability_preview != - AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported); - RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>( - BioEnrollmentRequest::ForEnumerate(std::move(token)), std::move(callback), - base::BindOnce(&BioEnrollmentResponse::Parse)); + BioEnrollmentRequest::ForEnumerate( + GetBioEnrollmentRequestVersion(*Options()), std::move(response)), + std::move(callback), base::BindOnce(&BioEnrollmentResponse::Parse)); } void FidoDeviceAuthenticator::Reset(ResetCallback callback) {
diff --git a/device/fido/virtual_ctap2_device.cc b/device/fido/virtual_ctap2_device.cc index 2745c301..f1580673 100644 --- a/device/fido/virtual_ctap2_device.cc +++ b/device/fido/virtual_ctap2_device.cc
@@ -502,6 +502,17 @@ if (config.bio_enrollment_support) { options_updated = true; if (mutable_state()->bio_enrollment_provisioned) { + options.bio_enrollment_availability = AuthenticatorSupportedOptions:: + BioEnrollmentAvailability::kSupportedAndProvisioned; + } else { + options.bio_enrollment_availability = AuthenticatorSupportedOptions:: + BioEnrollmentAvailability::kSupportedButUnprovisioned; + } + } + + if (config.bio_enrollment_preview_support) { + options_updated = true; + if (mutable_state()->bio_enrollment_provisioned) { options.bio_enrollment_availability_preview = AuthenticatorSupportedOptions::BioEnrollmentAvailability:: kSupportedAndProvisioned; @@ -590,6 +601,7 @@ case CtapRequestCommand::kAuthenticatorCredentialManagement: response_code = OnCredentialManagement(request_bytes, &response_data); break; + case CtapRequestCommand::kAuthenticatorBioEnrollment: case CtapRequestCommand::kAuthenticatorBioEnrollmentPreview: response_code = OnBioEnrollment(request_bytes, &response_data); break; @@ -1345,8 +1357,12 @@ base::span<const uint8_t> request_bytes, std::vector<uint8_t>* response) { // Check to ensure that device supports bio enrollment. - if (device_info_->options.bio_enrollment_availability_preview == - AuthenticatorSupportedOptions::BioEnrollmentAvailability::kNotSupported) { + if (device_info_->options.bio_enrollment_availability == + AuthenticatorSupportedOptions::BioEnrollmentAvailability:: + kNotSupported && + device_info_->options.bio_enrollment_availability_preview == + AuthenticatorSupportedOptions::BioEnrollmentAvailability:: + kNotSupported) { return CtapDeviceResponseCode::kCtap2ErrUnsupportedOption; } @@ -1434,7 +1450,7 @@ case static_cast<int>(SubCmd::kEnrollBegin): response_map.emplace( static_cast<int>(BioEnrollmentResponseKey::kTemplateId), - cbor::Value(std::vector<uint8_t>{0, 0, 0, 1})); + std::vector<uint8_t>{0, 0, 0, 1}); response_map.emplace( static_cast<int>(BioEnrollmentResponseKey::kLastEnrollSampleStatus), static_cast<int>(BioEnrollmentSampleStatus::kGood));
diff --git a/device/fido/virtual_ctap2_device.h b/device/fido/virtual_ctap2_device.h index 6a7a5cc..cb0c21b 100644 --- a/device/fido/virtual_ctap2_device.h +++ b/device/fido/virtual_ctap2_device.h
@@ -45,6 +45,7 @@ bool resident_key_support = false; bool credential_management_support = false; bool bio_enrollment_support = false; + bool bio_enrollment_preview_support = false; bool cred_protect_support = false; // resident_credential_storage is the number of resident credentials that // the device will store before returning KEY_STORE_FULL.
diff --git a/extensions/browser/api/app_window/app_window_apitest.cc b/extensions/browser/api/app_window/app_window_apitest.cc index 428393c..2b46a3b 100644 --- a/extensions/browser/api/app_window/app_window_apitest.cc +++ b/extensions/browser/api/app_window/app_window_apitest.cc
@@ -117,7 +117,9 @@ "platform_apps/windows_api_always_on_top/no_permissions")) << message_; } -IN_PROC_BROWSER_TEST_F(AppWindowApiTest, Get) { +// https://crbug.com/978272 - semi-consistently timing out on Linux CFI bots, +// and flaking in some Windows/ChromeOS try runs. +IN_PROC_BROWSER_TEST_F(AppWindowApiTest, DISABLED_Get) { EXPECT_TRUE(RunPlatformAppTest("platform_apps/windows_api_get")) << message_; }
diff --git a/extensions/browser/api/extensions_api_client.cc b/extensions/browser/api/extensions_api_client.cc index 6f43548..313465b 100644 --- a/extensions/browser/api/extensions_api_client.cc +++ b/extensions/browser/api/extensions_api_client.cc
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "extensions/browser/api/device_permissions_prompt.h" +#include "extensions/browser/api/system_display/display_info_provider.h" #include "extensions/browser/api/virtual_keyboard_private/virtual_keyboard_delegate.h" #include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h" #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h" @@ -109,6 +110,11 @@ return nullptr; } +std::unique_ptr<DisplayInfoProvider> +ExtensionsAPIClient::CreateDisplayInfoProvider() const { + return nullptr; +} + MetricsPrivateDelegate* ExtensionsAPIClient::GetMetricsPrivateDelegate() { return nullptr; }
diff --git a/extensions/browser/api/extensions_api_client.h b/extensions/browser/api/extensions_api_client.h index c88cd401..dd4f2bfa 100644 --- a/extensions/browser/api/extensions_api_client.h +++ b/extensions/browser/api/extensions_api_client.h
@@ -39,6 +39,7 @@ class AppViewGuestDelegate; class ContentRulesRegistry; class DevicePermissionsPrompt; +class DisplayInfoProvider; class ExtensionOptionsGuest; class ExtensionOptionsGuestDelegate; class FeedbackPrivateDelegate; @@ -151,6 +152,11 @@ // Creates a delegate for handling the management extension api. virtual ManagementAPIDelegate* CreateManagementAPIDelegate() const; + // Creates and returns the DisplayInfoProvider used by the + // chrome.system.display extension API. + virtual std::unique_ptr<DisplayInfoProvider> CreateDisplayInfoProvider() + const; + // If supported by the embedder, returns a delegate for embedder-dependent // MetricsPrivateAPI behavior. virtual MetricsPrivateDelegate* GetMetricsPrivateDelegate();
diff --git a/extensions/browser/api/serial/serial_connection.cc b/extensions/browser/api/serial/serial_connection.cc index 80ca129..33ac243 100644 --- a/extensions/browser/api/serial/serial_connection.cc +++ b/extensions/browser/api/serial/serial_connection.cc
@@ -32,10 +32,6 @@ return api::serial::SEND_ERROR_NONE; case device::mojom::SerialSendError::DISCONNECTED: return api::serial::SEND_ERROR_DISCONNECTED; - case device::mojom::SerialSendError::PENDING: - return api::serial::SEND_ERROR_PENDING; - case device::mojom::SerialSendError::TIMEOUT: - return api::serial::SEND_ERROR_TIMEOUT; case device::mojom::SerialSendError::SYSTEM_ERROR: return api::serial::SEND_ERROR_SYSTEM_ERROR; } @@ -49,8 +45,6 @@ return api::serial::RECEIVE_ERROR_NONE; case device::mojom::SerialReceiveError::DISCONNECTED: return api::serial::RECEIVE_ERROR_DISCONNECTED; - case device::mojom::SerialReceiveError::TIMEOUT: - return api::serial::RECEIVE_ERROR_TIMEOUT; case device::mojom::SerialReceiveError::DEVICE_LOST: return api::serial::RECEIVE_ERROR_DEVICE_LOST; case device::mojom::SerialReceiveError::BREAK:
diff --git a/extensions/browser/api/system_display/display_info_provider.cc b/extensions/browser/api/system_display/display_info_provider.cc index 7096e4b3..00abc24 100644 --- a/extensions/browser/api/system_display/display_info_provider.cc +++ b/extensions/browser/api/system_display/display_info_provider.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/strings/string_number_conversions.h" #include "base/threading/thread_task_runner_handle.h" +#include "extensions/browser/api/extensions_api_client.h" #include "extensions/browser/extensions_browser_client.h" #include "extensions/common/api/system_display.h" #include "ui/display/display.h" @@ -42,8 +43,11 @@ // static DisplayInfoProvider* DisplayInfoProvider::Get() { - if (!g_display_info_provider) - g_display_info_provider = DisplayInfoProvider::Create(); + if (!g_display_info_provider) { + // Let the DisplayInfoProvider leak. + g_display_info_provider = + ExtensionsAPIClient::Get()->CreateDisplayInfoProvider().release(); + } return g_display_info_provider; }
diff --git a/extensions/browser/api/system_display/display_info_provider.h b/extensions/browser/api/system_display/display_info_provider.h index da705f8c..df76556 100644 --- a/extensions/browser/api/system_display/display_info_provider.h +++ b/extensions/browser/api/system_display/display_info_provider.h
@@ -128,8 +128,6 @@ int64_t primary_display_id); private: - static DisplayInfoProvider* Create(); - // Update the content of the |unit| obtained for |display| using // platform specific method. virtual void UpdateDisplayUnitInfoForPlatform(
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn index c7a450a..9a8521d6 100644 --- a/extensions/renderer/BUILD.gn +++ b/extensions/renderer/BUILD.gn
@@ -102,6 +102,8 @@ "extension_frame_helper.h", "extension_injection_host.cc", "extension_injection_host.h", + "extension_interaction.cc", + "extension_interaction.h", "extension_js_runner.cc", "extension_js_runner.h", "extension_throttle_entry.cc",
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index c19c99b..fd19c1a 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -64,6 +64,7 @@ #include "extensions/renderer/display_source_custom_bindings.h" #include "extensions/renderer/dom_activity_logger.h" #include "extensions/renderer/extension_frame_helper.h" +#include "extensions/renderer/extension_interaction.h" #include "extensions/renderer/extensions_renderer_client.h" #include "extensions/renderer/file_system_natives.h" #include "extensions/renderer/guest_view/guest_view_internal_custom_bindings.h" @@ -101,11 +102,11 @@ #include "services/network/public/mojom/cors.mojom.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url_request.h" +#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h" #include "third_party/blink/public/web/web_custom_element.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_frame.h" #include "third_party/blink/public/web/web_local_frame.h" -#include "third_party/blink/public/web/web_scoped_user_gesture.h" #include "third_party/blink/public/web/web_script_controller.h" #include "third_party/blink/public/web/web_security_policy.h" #include "third_party/blink/public/web/web_settings.h" @@ -115,7 +116,6 @@ #include "v8/include/v8.h" using blink::WebDocument; -using blink::WebScopedUserGesture; using blink::WebSecurityPolicy; using blink::WebString; using blink::WebView; @@ -347,6 +347,7 @@ } void Dispatcher::DidInitializeServiceWorkerContextOnWorkerThread( + blink::WebServiceWorkerContextProxy* context_proxy, v8::Local<v8::Context> v8_context, int64_t service_worker_version_id, const GURL& service_worker_scope, @@ -401,7 +402,7 @@ IPCMessageSender::CreateWorkerThreadIPCMessageSender( worker_dispatcher, service_worker_version_id); worker_dispatcher->AddWorkerData( - service_worker_version_id, context, + service_worker_version_id, context_proxy, context, CreateBindingsSystem(std::move(ipc_sender))); // TODO(lazyboy): Make sure accessing |source_map_| in worker thread is @@ -968,7 +969,7 @@ content::RenderFrame* background_frame = ExtensionFrameHelper::GetBackgroundPageFrame(params.extension_id); - std::unique_ptr<WebScopedUserGesture> web_user_gesture; + std::unique_ptr<ExtensionInteraction> web_user_gesture; // Synthesize a user gesture if this was in response to user action; this is // necessary if the gesture was e.g. by clicking on the extension toolbar // icon, context menu entry, etc. @@ -983,8 +984,8 @@ ScriptContextSet::GetMainWorldContextForFrame(background_frame); if (background_context && bindings_system_->HasEventListenerInContext( params.event_name, background_context)) { - web_user_gesture.reset( - new WebScopedUserGesture(background_frame->GetWebFrame())); + web_user_gesture = ExtensionInteraction::CreateScopeForMainThread( + background_frame->GetWebFrame()); } }
diff --git a/extensions/renderer/dispatcher.h b/extensions/renderer/dispatcher.h index d369cc6c..c0b6b9a 100644 --- a/extensions/renderer/dispatcher.h +++ b/extensions/renderer/dispatcher.h
@@ -45,6 +45,7 @@ namespace blink { class WebLocalFrame; +class WebServiceWorkerContextProxy; } namespace base { @@ -107,6 +108,7 @@ // Runs on a different thread and should only use thread safe member // variables. void DidInitializeServiceWorkerContextOnWorkerThread( + blink::WebServiceWorkerContextProxy* context_proxy, v8::Local<v8::Context> v8_context, int64_t service_worker_version_id, const GURL& service_worker_scope,
diff --git a/extensions/renderer/extension_interaction.cc b/extensions/renderer/extension_interaction.cc new file mode 100644 index 0000000..c8a7a9b --- /dev/null +++ b/extensions/renderer/extension_interaction.cc
@@ -0,0 +1,64 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/renderer/extension_interaction.h" + +#include <utility> + +#include "base/memory/ptr_util.h" +#include "extensions/renderer/script_context.h" +#include "extensions/renderer/service_worker_data.h" +#include "extensions/renderer/worker_thread_dispatcher.h" +#include "extensions/renderer/worker_thread_util.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_scoped_user_gesture.h" +#include "third_party/blink/public/web/web_user_gesture_indicator.h" + +namespace extensions { + +// static +std::unique_ptr<ExtensionInteraction> +ExtensionInteraction::CreateScopeForWorker() { + // Note: ExtensionInteraction ctor is private. + return base::WrapUnique(new ExtensionInteraction(nullptr)); +} + +// static +std::unique_ptr<ExtensionInteraction> +ExtensionInteraction::CreateScopeForMainThread( + blink::WebLocalFrame* web_frame) { + // Note: ExtensionInteraction ctor is private. + return base::WrapUnique(new ExtensionInteraction(web_frame)); +} + +// static +bool ExtensionInteraction::HasActiveInteraction(ScriptContext* context) { + if (worker_thread_util::IsWorkerThread()) { + DCHECK(!context->web_frame()); + ServiceWorkerData* worker_data = + WorkerThreadDispatcher::GetServiceWorkerData(); + return worker_data->interaction_count() > 0 || + worker_data->is_service_worker_window_interaction_allowed(); + } + return blink::WebUserGestureIndicator::IsProcessingUserGesture( + context->web_frame()); +} + +ExtensionInteraction::ExtensionInteraction(blink::WebLocalFrame* context) + : is_worker_thread_(worker_thread_util::IsWorkerThread()) { + if (is_worker_thread_) { + DCHECK(!context); + WorkerThreadDispatcher::GetServiceWorkerData()->IncrementInteraction(); + } else { + main_thread_gesture_ = + std::make_unique<blink::WebScopedUserGesture>(context); + } +} + +ExtensionInteraction::~ExtensionInteraction() { + if (is_worker_thread_) + WorkerThreadDispatcher::GetServiceWorkerData()->DecrementInteraction(); +} + +} // namespace extensions
diff --git a/extensions/renderer/extension_interaction.h b/extensions/renderer/extension_interaction.h new file mode 100644 index 0000000..0d4f656 --- /dev/null +++ b/extensions/renderer/extension_interaction.h
@@ -0,0 +1,49 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_RENDERER_EXTENSION_INTERACTION_H_ +#define EXTENSIONS_RENDERER_EXTENSION_INTERACTION_H_ + +#include <memory> + +#include "base/macros.h" + +namespace blink { +class WebLocalFrame; +class WebScopedUserGesture; +} // namespace blink + +namespace extensions { + +class ScriptContext; + +// Provides user interaction related utilities for extensions, works for +// both RenderFrame based and Service Worker based extensions. +// Provides scoped interaction creation for a context and provides current +// interaction state retrieval method. +class ExtensionInteraction { + public: + ~ExtensionInteraction(); + + // Creates a scoped interaction for a RenderFrame based extension. + static std::unique_ptr<ExtensionInteraction> CreateScopeForMainThread( + blink::WebLocalFrame* web_frame); + // Creates a scoped interaction for a Service Worker based extension. + static std::unique_ptr<ExtensionInteraction> CreateScopeForWorker(); + + // Returns true if |context| has an active user interaction. + static bool HasActiveInteraction(ScriptContext* context); + + private: + explicit ExtensionInteraction(blink::WebLocalFrame* context); + + bool is_worker_thread_ = false; + std::unique_ptr<blink::WebScopedUserGesture> main_thread_gesture_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionInteraction); +}; + +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_EXTENSION_INTERACTION_H_
diff --git a/extensions/renderer/native_extension_bindings_system.cc b/extensions/renderer/native_extension_bindings_system.cc index 13dde54..94a57e1b 100644 --- a/extensions/renderer/native_extension_bindings_system.cc +++ b/extensions/renderer/native_extension_bindings_system.cc
@@ -28,6 +28,7 @@ #include "extensions/renderer/content_setting.h" #include "extensions/renderer/declarative_content_hooks_delegate.h" #include "extensions/renderer/extension_frame_helper.h" +#include "extensions/renderer/extension_interaction.h" #include "extensions/renderer/extension_js_runner.h" #include "extensions/renderer/get_script_context.h" #include "extensions/renderer/i18n_hooks_delegate.h" @@ -45,7 +46,6 @@ #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_local_frame.h" -#include "third_party/blink/public/web/web_user_gesture_indicator.h" namespace extensions { @@ -852,8 +852,7 @@ bool NativeExtensionBindingsSystem::GetUserActivationState( v8::Local<v8::Context> context) { ScriptContext* script_context = GetScriptContextFromV8ContextChecked(context); - return blink::WebUserGestureIndicator::IsProcessingUserGestureThreadSafe( - script_context->web_frame()); + return ExtensionInteraction::HasActiveInteraction(script_context); } void NativeExtensionBindingsSystem::OnEventListenerChanged(
diff --git a/extensions/renderer/service_worker_data.cc b/extensions/renderer/service_worker_data.cc index 3c96f09..0fc377b 100644 --- a/extensions/renderer/service_worker_data.cc +++ b/extensions/renderer/service_worker_data.cc
@@ -10,13 +10,24 @@ ServiceWorkerData::ServiceWorkerData( int64_t service_worker_version_id, + blink::WebServiceWorkerContextProxy* context_proxy, ScriptContext* context, std::unique_ptr<NativeExtensionBindingsSystem> bindings_system) : service_worker_version_id_(service_worker_version_id), + context_proxy_(context_proxy), context_(context), v8_schema_registry_(new V8SchemaRegistry), bindings_system_(std::move(bindings_system)) {} ServiceWorkerData::~ServiceWorkerData() {} +void ServiceWorkerData::IncrementInteraction() { + ++interaction_count_; +} + +void ServiceWorkerData::DecrementInteraction() { + DCHECK_GT(interaction_count_, 0); + --interaction_count_; +} + } // namespace extensions
diff --git a/extensions/renderer/service_worker_data.h b/extensions/renderer/service_worker_data.h index b99892a2..854865f 100644 --- a/extensions/renderer/service_worker_data.h +++ b/extensions/renderer/service_worker_data.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "extensions/renderer/v8_schema_registry.h" +#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h" namespace extensions { class NativeExtensionBindingsSystem; @@ -20,6 +21,7 @@ public: ServiceWorkerData( int64_t service_worker_version_id, + blink::WebServiceWorkerContextProxy* context_proxy, ScriptContext* context, std::unique_ptr<NativeExtensionBindingsSystem> bindings_system); ~ServiceWorkerData(); @@ -33,9 +35,27 @@ } ScriptContext* context() const { return context_; } + // Returns the number of active interactions for this worker. + int interaction_count() const { return interaction_count_; } + + // Returns true if this worker is within a user interaction. + // The interaction originates from Service Worker notificationclick. + bool is_service_worker_window_interaction_allowed() const { + return context_proxy_->IsWindowInteractionAllowed(); + } + + // Marks the beginning of an interaction within this worker. + void IncrementInteraction(); + // Marks the end of an interaction within this worker. + void DecrementInteraction(); + private: const int64_t service_worker_version_id_; - ScriptContext* const context_; + // Valid for the lifetime of |this|. + blink::WebServiceWorkerContextProxy* const context_proxy_ = nullptr; + ScriptContext* const context_ = nullptr; + + int interaction_count_ = 0; std::unique_ptr<V8SchemaRegistry> v8_schema_registry_; std::unique_ptr<NativeExtensionBindingsSystem> bindings_system_;
diff --git a/extensions/renderer/user_gestures_native_handler.cc b/extensions/renderer/user_gestures_native_handler.cc index bfc42efe..ba796067 100644 --- a/extensions/renderer/user_gestures_native_handler.cc +++ b/extensions/renderer/user_gestures_native_handler.cc
@@ -5,9 +5,9 @@ #include "extensions/renderer/user_gestures_native_handler.h" #include "base/bind.h" +#include "extensions/renderer/extension_interaction.h" #include "extensions/renderer/script_context.h" #include "third_party/blink/public/web/web_scoped_user_gesture.h" -#include "third_party/blink/public/web/web_user_gesture_indicator.h" namespace extensions { @@ -29,12 +29,13 @@ const v8::FunctionCallbackInfo<v8::Value>& args) { args.GetReturnValue().Set( v8::Boolean::New(args.GetIsolate(), - blink::WebUserGestureIndicator::IsProcessingUserGesture( - context()->web_frame()))); + ExtensionInteraction::HasActiveInteraction(context()))); } void UserGesturesNativeHandler::RunWithUserGesture( const v8::FunctionCallbackInfo<v8::Value>& args) { + // TODO(lazyboy): This won't work for Service Workers. Address this once we're + // certain that we need this for workers. blink::WebScopedUserGesture user_gesture(context()->web_frame()); CHECK_EQ(args.Length(), 1); CHECK(args[0]->IsFunction());
diff --git a/extensions/renderer/worker_thread_dispatcher.cc b/extensions/renderer/worker_thread_dispatcher.cc index 6b94e6ff..50b6afb 100644 --- a/extensions/renderer/worker_thread_dispatcher.cc +++ b/extensions/renderer/worker_thread_dispatcher.cc
@@ -18,11 +18,13 @@ #include "extensions/common/extension_features.h" #include "extensions/common/extension_messages.h" #include "extensions/renderer/dispatcher.h" +#include "extensions/renderer/extension_interaction.h" #include "extensions/renderer/extensions_renderer_client.h" #include "extensions/renderer/native_extension_bindings_system.h" #include "extensions/renderer/native_renderer_messaging_service.h" #include "extensions/renderer/service_worker_data.h" #include "extensions/renderer/worker_script_context_set.h" +#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h" namespace extensions { @@ -33,12 +35,6 @@ base::LazyInstance<base::ThreadLocalPointer<extensions::ServiceWorkerData>>:: DestructorAtExit g_data_tls = LAZY_INSTANCE_INITIALIZER; -ServiceWorkerData* GetServiceWorkerData() { - ServiceWorkerData* data = g_data_tls.Pointer()->Get(); - DCHECK(data); - return data; -} - } // namespace WorkerThreadDispatcher::WorkerThreadDispatcher() {} @@ -72,6 +68,13 @@ } // static +ServiceWorkerData* WorkerThreadDispatcher::GetServiceWorkerData() { + ServiceWorkerData* data = g_data_tls.Pointer()->Get(); + DCHECK(data); + return data; +} + +// static bool WorkerThreadDispatcher::HandlesMessageOnWorkerThread( const IPC::Message& message) { return message.type() == ExtensionMsg_ResponseWorker::ID || @@ -157,6 +160,9 @@ const base::ListValue& event_args) { ServiceWorkerData* data = g_data_tls.Pointer()->Get(); DCHECK(data); + std::unique_ptr<ExtensionInteraction> scoped_extension_interaction; + if (params.is_user_gesture) + scoped_extension_interaction = ExtensionInteraction::CreateScopeForWorker(); data->bindings_system()->DispatchEventInContext( params.event_name, &event_args, ¶ms.filtering_info, data->context()); Send(new ExtensionHostMsg_EventAckWorker(data->service_worker_version_id(), @@ -213,12 +219,14 @@ void WorkerThreadDispatcher::AddWorkerData( int64_t service_worker_version_id, - ScriptContext* context, + blink::WebServiceWorkerContextProxy* context_proxy, + ScriptContext* script_context, std::unique_ptr<NativeExtensionBindingsSystem> bindings_system) { ServiceWorkerData* data = g_data_tls.Pointer()->Get(); if (!data) { - ServiceWorkerData* new_data = new ServiceWorkerData( - service_worker_version_id, context, std::move(bindings_system)); + ServiceWorkerData* new_data = + new ServiceWorkerData(service_worker_version_id, context_proxy, + script_context, std::move(bindings_system)); g_data_tls.Pointer()->Set(new_data); }
diff --git a/extensions/renderer/worker_thread_dispatcher.h b/extensions/renderer/worker_thread_dispatcher.h index 7465339..419b2f6 100644 --- a/extensions/renderer/worker_thread_dispatcher.h +++ b/extensions/renderer/worker_thread_dispatcher.h
@@ -19,6 +19,10 @@ class ListValue; } +namespace blink { +class WebServiceWorkerContextProxy; +} + namespace content { class RenderThread; } @@ -31,6 +35,7 @@ namespace extensions { class NativeExtensionBindingsSystem; class ScriptContext; +class ServiceWorkerData; class V8SchemaRegistry; struct Message; struct PortId; @@ -52,6 +57,7 @@ static NativeExtensionBindingsSystem* GetBindingsSystem(); static V8SchemaRegistry* GetV8SchemaRegistry(); static ScriptContext* GetScriptContext(); + static ServiceWorkerData* GetServiceWorkerData(); void Init(content::RenderThread* render_thread); @@ -60,7 +66,8 @@ void AddWorkerData( int64_t service_worker_version_id, - ScriptContext* context, + blink::WebServiceWorkerContextProxy* context_proxy, + ScriptContext* script_context, std::unique_ptr<NativeExtensionBindingsSystem> bindings_system); void RemoveWorkerData(int64_t service_worker_version_id);
diff --git a/extensions/shell/browser/shell_display_info_provider.cc b/extensions/shell/browser/shell_display_info_provider.cc index 5bf8a7d..a823b87 100644 --- a/extensions/shell/browser/shell_display_info_provider.cc +++ b/extensions/shell/browser/shell_display_info_provider.cc
@@ -8,9 +8,4 @@ ShellDisplayInfoProvider::ShellDisplayInfoProvider() = default; -// static -DisplayInfoProvider* DisplayInfoProvider::Create() { - return new ShellDisplayInfoProvider(); -} - } // namespace extensions
diff --git a/extensions/shell/browser/shell_extensions_api_client.cc b/extensions/shell/browser/shell_extensions_api_client.cc index 226d0a8e..980b78a 100644 --- a/extensions/shell/browser/shell_extensions_api_client.cc +++ b/extensions/shell/browser/shell_extensions_api_client.cc
@@ -11,6 +11,7 @@ #include "extensions/shell/browser/api/feedback_private/shell_feedback_private_delegate.h" #include "extensions/shell/browser/delegates/shell_kiosk_delegate.h" #include "extensions/shell/browser/shell_app_view_guest_delegate.h" +#include "extensions/shell/browser/shell_display_info_provider.h" #include "extensions/shell/browser/shell_extension_web_contents_observer.h" #include "extensions/shell/browser/shell_virtual_keyboard_delegate.h" #include "extensions/shell/browser/shell_web_view_guest_delegate.h" @@ -46,6 +47,11 @@ return std::make_unique<ShellVirtualKeyboardDelegate>(); } +std::unique_ptr<DisplayInfoProvider> +ShellExtensionsAPIClient::CreateDisplayInfoProvider() const { + return std::make_unique<ShellDisplayInfoProvider>(); +} + #if defined(OS_LINUX) && !defined(OS_CHROMEOS) FileSystemDelegate* ShellExtensionsAPIClient::GetFileSystemDelegate() { if (!file_system_delegate_)
diff --git a/extensions/shell/browser/shell_extensions_api_client.h b/extensions/shell/browser/shell_extensions_api_client.h index ffc1a8e..38729ee 100644 --- a/extensions/shell/browser/shell_extensions_api_client.h +++ b/extensions/shell/browser/shell_extensions_api_client.h
@@ -30,6 +30,8 @@ WebViewGuest* web_view_guest) const override; std::unique_ptr<VirtualKeyboardDelegate> CreateVirtualKeyboardDelegate( content::BrowserContext* browser_context) const override; + std::unique_ptr<DisplayInfoProvider> CreateDisplayInfoProvider() + const override; #if defined(OS_LINUX) && !defined(OS_CHROMEOS) FileSystemDelegate* GetFileSystemDelegate() override; #endif
diff --git a/fuchsia/engine/BUILD.gn b/fuchsia/engine/BUILD.gn index b01218ce..e450b4f 100644 --- a/fuchsia/engine/BUILD.gn +++ b/fuchsia/engine/BUILD.gn
@@ -105,6 +105,8 @@ "browser/discarding_event_filter.h", "browser/frame_impl.cc", "browser/frame_impl.h", + "browser/navigation_controller_impl.cc", + "browser/navigation_controller_impl.h", "browser/web_engine_browser_context.cc", "browser/web_engine_browser_context.h", "browser/web_engine_browser_main.cc",
diff --git a/fuchsia/engine/browser/frame_impl.cc b/fuchsia/engine/browser/frame_impl.cc index f5d65dd..6a6d1e3 100644 --- a/fuchsia/engine/browser/frame_impl.cc +++ b/fuchsia/engine/browser/frame_impl.cc
@@ -46,7 +46,7 @@ LayoutManagerImpl() = default; ~LayoutManagerImpl() override = default; - // aura::LayoutManager. + // aura::LayoutManager implementation. void OnWindowResized() override { // Resize the child to match the size of the parent if (child_) { @@ -77,32 +77,6 @@ DISALLOW_COPY_AND_ASSIGN(LayoutManagerImpl); }; -void UpdateNavigationStateFromNavigationEntry( - content::NavigationEntry* entry, - content::WebContents* web_contents, - fuchsia::web::NavigationState* navigation_state) { - DCHECK(entry); - DCHECK(web_contents); - DCHECK(navigation_state); - - navigation_state->set_title(base::UTF16ToUTF8(entry->GetTitleForDisplay())); - navigation_state->set_url(entry->GetURL().spec()); - - switch (entry->GetPageType()) { - case content::PageType::PAGE_TYPE_NORMAL: - case content::PageType::PAGE_TYPE_INTERSTITIAL: - navigation_state->set_page_type(fuchsia::web::PageType::NORMAL); - break; - case content::PageType::PAGE_TYPE_ERROR: - navigation_state->set_page_type(fuchsia::web::PageType::ERROR); - break; - } - - navigation_state->set_can_go_back(web_contents->GetController().CanGoBack()); - navigation_state->set_can_go_forward( - web_contents->GetController().CanGoForward()); -} - class FrameFocusRules : public wm::BaseFocusRules { public: FrameFocusRules() = default; @@ -197,9 +171,9 @@ fidl::InterfaceRequest<fuchsia::web::Frame> frame_request) : web_contents_(std::move(web_contents)), context_(context), + navigation_controller_(web_contents_.get()), log_level_(kLogSeverityNone), - binding_(this, std::move(frame_request)), - weak_factory_(this) { + binding_(this, std::move(frame_request)) { web_contents_->SetDelegate(this); Observe(web_contents_.get()); binding_.set_error_handler([this](zx_status_t status) { @@ -220,6 +194,39 @@ return zx::unowned_channel(binding_.channel()); } +FrameImpl::OriginScopedScript::OriginScopedScript() = default; + +FrameImpl::OriginScopedScript::OriginScopedScript( + std::vector<std::string> origins, + base::ReadOnlySharedMemoryRegion script) + : origins_(std::move(origins)), script_(std::move(script)) {} + +FrameImpl::OriginScopedScript& FrameImpl::OriginScopedScript::operator=( + FrameImpl::OriginScopedScript&& other) { + origins_ = std::move(other.origins_); + script_ = std::move(other.script_); + return *this; +} + +FrameImpl::OriginScopedScript::~OriginScopedScript() = default; + +void FrameImpl::TearDownView() { + if (window_tree_host_) { + aura::client::SetFocusClient(root_window(), nullptr); + wm::SetActivationClient(root_window(), nullptr); + root_window()->RemovePreTargetHandler(focus_controller_.get()); + web_contents_->GetNativeView()->Hide(); + window_tree_host_->Hide(); + window_tree_host_->compositor()->SetVisible(false); + window_tree_host_ = nullptr; + + // Allows posted focus events to process before the FocusController is torn + // down. + content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE, + std::move(focus_controller_)); + } +} + void FrameImpl::CreateView(fuchsia::ui::views::ViewToken view_token) { // If a View to this Frame is already active then disconnect it. TearDownView(); @@ -254,7 +261,7 @@ void FrameImpl::GetNavigationController( fidl::InterfaceRequest<fuchsia::web::NavigationController> controller) { - controller_bindings_.AddBinding(this, std::move(controller)); + navigation_controller_.AddBinding(std::move(controller)); } void FrameImpl::ExecuteJavaScriptNoResult( @@ -412,18 +419,7 @@ void FrameImpl::SetNavigationEventListener( fidl::InterfaceHandle<fuchsia::web::NavigationEventListener> listener) { - // Reset the event buffer state. - waiting_for_navigation_event_ack_ = false; - previous_navigation_state_ = {}; - pending_navigation_event_ = {}; - - if (listener) { - navigation_listener_.Bind(std::move(listener)); - navigation_listener_.set_error_handler( - [this](zx_status_t status) { SetNavigationEventListener(nullptr); }); - } else { - navigation_listener_.Unbind(); - } + navigation_controller_.SetEventListener(std::move(listener)); } void FrameImpl::SetJavaScriptLogLevel(fuchsia::web::ConsoleLogLevel level) { @@ -434,164 +430,6 @@ discarding_event_filter_.set_discard_events(!enable_input); } -FrameImpl::OriginScopedScript::OriginScopedScript() = default; - -FrameImpl::OriginScopedScript::OriginScopedScript( - std::vector<std::string> origins, - base::ReadOnlySharedMemoryRegion script) - : origins_(std::move(origins)), script_(std::move(script)) {} - -FrameImpl::OriginScopedScript& FrameImpl::OriginScopedScript::operator=( - FrameImpl::OriginScopedScript&& other) { - origins_ = std::move(other.origins_); - script_ = std::move(other.script_); - return *this; -} - -FrameImpl::OriginScopedScript::~OriginScopedScript() = default; - -void FrameImpl::TearDownView() { - if (window_tree_host_) { - aura::client::SetFocusClient(root_window(), nullptr); - wm::SetActivationClient(root_window(), nullptr); - root_window()->RemovePreTargetHandler(focus_controller_.get()); - web_contents_->GetNativeView()->Hide(); - window_tree_host_->Hide(); - window_tree_host_->compositor()->SetVisible(false); - window_tree_host_ = nullptr; - - // Allows posted focus events to process before the FocusController is torn - // down. - content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE, - std::move(focus_controller_)); - } -} - -void FrameImpl::OnNavigationEntryChanged() { - fuchsia::web::NavigationState new_state; - new_state.set_is_main_document_loaded(is_main_document_loaded_); - UpdateNavigationStateFromNavigationEntry( - web_contents_->GetController().GetVisibleEntry(), web_contents_.get(), - &new_state); - - DiffNavigationEntries(previous_navigation_state_, new_state, - &pending_navigation_event_); - previous_navigation_state_ = std::move(new_state); - - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&FrameImpl::MaybeSendNavigationEvent, - weak_factory_.GetWeakPtr())); -} - -void FrameImpl::MaybeSendNavigationEvent() { - if (!navigation_listener_) - return; - - if (pending_navigation_event_.IsEmpty() || - waiting_for_navigation_event_ack_) { - return; - } - - waiting_for_navigation_event_ack_ = true; - - // Send the event to the observer and, upon acknowledgement, revisit this - // function to send another update. - navigation_listener_->OnNavigationStateChanged( - std::move(pending_navigation_event_), [this]() { - waiting_for_navigation_event_ack_ = false; - MaybeSendNavigationEvent(); - }); - - pending_navigation_event_ = {}; -} - -void FrameImpl::LoadUrl(std::string url, - fuchsia::web::LoadUrlParams params, - LoadUrlCallback callback) { - fuchsia::web::NavigationController_LoadUrl_Result result; - GURL validated_url(url); - if (!validated_url.is_valid()) { - result.set_err(fuchsia::web::NavigationControllerError::INVALID_URL); - callback(std::move(result)); - return; - } - - content::NavigationController::LoadURLParams params_converted(validated_url); - if (params.has_headers()) { - std::vector<std::string> extra_headers; - extra_headers.reserve(params.headers().size()); - for (const auto& header : params.headers()) { - // TODO(crbug.com/964732): Check there is no colon in |header_name|. - base::StringPiece header_name( - reinterpret_cast<const char*>(header.name.data()), - header.name.size()); - base::StringPiece header_value( - reinterpret_cast<const char*>(header.value.data()), - header.value.size()); - extra_headers.emplace_back( - base::StrCat({header_name, ": ", header_value})); - } - params_converted.extra_headers = base::JoinString(extra_headers, "\n"); - } - - if (validated_url.scheme() == url::kDataScheme) - params_converted.load_type = content::NavigationController::LOAD_TYPE_DATA; - - params_converted.transition_type = ui::PageTransitionFromInt( - ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); - if (params.has_was_user_activated() && params.was_user_activated()) { - params_converted.was_activated = content::WasActivatedOption::kYes; - } else { - params_converted.was_activated = content::WasActivatedOption::kNo; - } - - web_contents_->GetController().LoadURLWithParams(params_converted); - result.set_response(fuchsia::web::NavigationController_LoadUrl_Response()); - callback(std::move(result)); -} - -void FrameImpl::GoBack() { - if (web_contents_->GetController().CanGoBack()) - web_contents_->GetController().GoBack(); -} - -void FrameImpl::GoForward() { - if (web_contents_->GetController().CanGoForward()) - web_contents_->GetController().GoForward(); -} - -void FrameImpl::Stop() { - web_contents_->Stop(); -} - -void FrameImpl::Reload(fuchsia::web::ReloadType type) { - content::ReloadType internal_reload_type; - switch (type) { - case fuchsia::web::ReloadType::PARTIAL_CACHE: - internal_reload_type = content::ReloadType::NORMAL; - break; - case fuchsia::web::ReloadType::NO_CACHE: - internal_reload_type = content::ReloadType::BYPASSING_CACHE; - break; - } - web_contents_->GetController().Reload(internal_reload_type, false); -} - -void FrameImpl::GetVisibleEntry( - fuchsia::web::NavigationController::GetVisibleEntryCallback callback) { - content::NavigationEntry* entry = - web_contents_->GetController().GetVisibleEntry(); - if (!entry) { - callback({}); - return; - } - - fuchsia::web::NavigationState state; - state.set_is_main_document_loaded(is_main_document_loaded_); - UpdateNavigationStateFromNavigationEntry(entry, web_contents_.get(), &state); - callback(std::move(state)); -} - void FrameImpl::CloseContents(content::WebContents* source) { DCHECK_EQ(source, web_contents_.get()); context_->DestroyFrame(this); @@ -685,74 +523,7 @@ } } -void FrameImpl::TitleWasSet(content::NavigationEntry* entry) { - // The title was changed after the document was loaded. - OnNavigationEntryChanged(); -} - -void FrameImpl::DocumentAvailableInMainFrame() { - // The main document is loaded, but not necessarily all the subresources. Some - // fields like "title" will change here. - - OnNavigationEntryChanged(); -} - void FrameImpl::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) { context_->OnDevToolsPortReady(); - - // The document and its statically-declared subresources are loaded. - is_main_document_loaded_ = true; - OnNavigationEntryChanged(); -} - -void FrameImpl::DidStartNavigation( - content::NavigationHandle* navigation_handle) { - if (navigation_handle->IsSameDocument()) - return; - - is_main_document_loaded_ = false; - OnNavigationEntryChanged(); -} - -void DiffNavigationEntries(const fuchsia::web::NavigationState& old_entry, - const fuchsia::web::NavigationState& new_entry, - fuchsia::web::NavigationState* difference) { - DCHECK(difference); - - DCHECK(new_entry.has_title()); - if (!old_entry.has_title() || (new_entry.title() != old_entry.title())) { - difference->set_title(new_entry.title()); - } - - DCHECK(new_entry.has_url()); - if (!old_entry.has_url() || (new_entry.url() != old_entry.url())) { - difference->set_url(new_entry.url()); - } - - DCHECK(new_entry.has_page_type()); - if (!old_entry.has_page_type() || - (new_entry.page_type() != old_entry.page_type())) { - difference->set_page_type(new_entry.page_type()); - } - - DCHECK(new_entry.has_can_go_back()); - if (!old_entry.has_can_go_back() || - old_entry.can_go_back() != new_entry.can_go_back()) { - difference->set_can_go_back(new_entry.can_go_back()); - } - - DCHECK(new_entry.has_can_go_forward()); - if (!old_entry.has_can_go_forward() || - old_entry.can_go_forward() != new_entry.can_go_forward()) { - difference->set_can_go_forward(new_entry.can_go_forward()); - } - - DCHECK(new_entry.has_is_main_document_loaded()); - if (!old_entry.has_is_main_document_loaded() || - old_entry.is_main_document_loaded() != - new_entry.is_main_document_loaded()) { - difference->set_is_main_document_loaded( - new_entry.is_main_document_loaded()); - } }
diff --git a/fuchsia/engine/browser/frame_impl.h b/fuchsia/engine/browser/frame_impl.h index 672f44b..77e68787 100644 --- a/fuchsia/engine/browser/frame_impl.h +++ b/fuchsia/engine/browser/frame_impl.h
@@ -17,12 +17,11 @@ #include "base/macros.h" #include "base/memory/platform_shared_memory_region.h" -#include "base/memory/weak_ptr.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" #include "fuchsia/engine/browser/discarding_event_filter.h" +#include "fuchsia/engine/browser/navigation_controller_impl.h" #include "fuchsia/engine/on_load_script_injector.mojom.h" -#include "fuchsia/engine/web_engine_export.h" #include "ui/aura/window_tree_host.h" #include "ui/wm/core/focus_controller.h" #include "url/gurl.h" @@ -39,7 +38,6 @@ // Implementation of fuchsia.web.Frame based on content::WebContents. class FrameImpl : public fuchsia::web::Frame, - public fuchsia::web::NavigationController, public content::WebContentsObserver, public content::WebContentsDelegate { public: @@ -63,30 +61,6 @@ FRIEND_TEST_ALL_PREFIXES(FrameImplTest, ReloadFrame); FRIEND_TEST_ALL_PREFIXES(FrameImplTest, Stop); - // fuchsia::web::Frame implementation. - void CreateView(fuchsia::ui::views::ViewToken view_token) override; - void GetNavigationController( - fidl::InterfaceRequest<fuchsia::web::NavigationController> controller) - override; - void ExecuteJavaScriptNoResult( - std::vector<std::string> origins, - fuchsia::mem::Buffer script, - ExecuteJavaScriptNoResultCallback callback) override; - void AddBeforeLoadJavaScript( - uint64_t id, - std::vector<std::string> origins, - fuchsia::mem::Buffer script, - AddBeforeLoadJavaScriptCallback callback) override; - void RemoveBeforeLoadJavaScript(uint64_t id) override; - void PostMessage(std::string origin, - fuchsia::web::WebMessage message, - fuchsia::web::Frame::PostMessageCallback callback) override; - void SetNavigationEventListener( - fidl::InterfaceHandle<fuchsia::web::NavigationEventListener> listener) - override; - void SetJavaScriptLogLevel(fuchsia::web::ConsoleLogLevel level) override; - void SetEnableInput(bool enable_input) override; - class OriginScopedScript { public: OriginScopedScript(); @@ -112,23 +86,29 @@ // Release the resources associated with the View, if one is active. void TearDownView(); - // Processes the most recent changes to the browser's navigation state and - // triggers the publishing of change events. - void OnNavigationEntryChanged(); - - // Sends |pending_navigation_event_| to the observer if there are any changes - // to be reported. - void MaybeSendNavigationEvent(); - - // fuchsia::web::NavigationController implementation. - void LoadUrl(std::string url, - fuchsia::web::LoadUrlParams params, - LoadUrlCallback callback) override; - void GoBack() override; - void GoForward() override; - void Stop() override; - void Reload(fuchsia::web::ReloadType type) override; - void GetVisibleEntry(GetVisibleEntryCallback callback) override; + // fuchsia::web::Frame implementation. + void CreateView(fuchsia::ui::views::ViewToken view_token) override; + void GetNavigationController( + fidl::InterfaceRequest<fuchsia::web::NavigationController> controller) + override; + void ExecuteJavaScriptNoResult( + std::vector<std::string> origins, + fuchsia::mem::Buffer script, + ExecuteJavaScriptNoResultCallback callback) override; + void AddBeforeLoadJavaScript( + uint64_t id, + std::vector<std::string> origins, + fuchsia::mem::Buffer script, + AddBeforeLoadJavaScriptCallback callback) override; + void RemoveBeforeLoadJavaScript(uint64_t id) override; + void PostMessage(std::string origin, + fuchsia::web::WebMessage message, + fuchsia::web::Frame::PostMessageCallback callback) override; + void SetNavigationEventListener( + fidl::InterfaceHandle<fuchsia::web::NavigationEventListener> listener) + override; + void SetJavaScriptLogLevel(fuchsia::web::ConsoleLogLevel level) override; + void SetEnableInput(bool enable_input) override; // content::WebContentsDelegate implementation. void CloseContents(content::WebContents* source) override; @@ -154,12 +134,8 @@ // content::WebContentsObserver implementation. void ReadyToCommitNavigation( content::NavigationHandle* navigation_handle) override; - void TitleWasSet(content::NavigationEntry*) override; - void DocumentAvailableInMainFrame() override; void DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) override; - void DidStartNavigation( - content::NavigationHandle* navigation_handle) override; std::unique_ptr<aura::WindowTreeHost> window_tree_host_; const std::unique_ptr<content::WebContents> web_contents_; @@ -167,29 +143,16 @@ ContextImpl* const context_; DiscardingEventFilter discarding_event_filter_; - fuchsia::web::NavigationEventListenerPtr navigation_listener_; - fuchsia::web::NavigationState previous_navigation_state_; - fuchsia::web::NavigationState pending_navigation_event_; - bool waiting_for_navigation_event_ack_; + NavigationControllerImpl navigation_controller_; logging::LogSeverity log_level_; std::map<uint64_t, OriginScopedScript> before_load_scripts_; std::vector<uint64_t> before_load_scripts_order_; base::RepeatingCallback<void(base::StringPiece)> console_log_message_hook_; - bool is_main_document_loaded_ = false; fidl::Binding<fuchsia::web::Frame> binding_; - fidl::BindingSet<fuchsia::web::NavigationController> controller_bindings_; - - base::WeakPtrFactory<FrameImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(FrameImpl); }; -// Computes the differences from old_entry to new_entry and stores the result in -// |difference|. -WEB_ENGINE_EXPORT void DiffNavigationEntries( - const fuchsia::web::NavigationState& old_entry, - const fuchsia::web::NavigationState& new_entry, - fuchsia::web::NavigationState* difference); #endif // FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_H_
diff --git a/fuchsia/engine/browser/navigation_controller_impl.cc b/fuchsia/engine/browser/navigation_controller_impl.cc new file mode 100644 index 0000000..cf0eb7e --- /dev/null +++ b/fuchsia/engine/browser/navigation_controller_impl.cc
@@ -0,0 +1,269 @@ +// 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 "fuchsia/engine/browser/navigation_controller_impl.h" + +#include "base/strings/strcat.h" +#include "base/strings/utf_string_conversions.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/was_activated_option.h" +#include "ui/base/page_transition_types.h" + +namespace { + +void UpdateNavigationStateFromNavigationEntry( + content::NavigationEntry* entry, + content::WebContents* web_contents, + fuchsia::web::NavigationState* navigation_state) { + DCHECK(entry); + DCHECK(web_contents); + DCHECK(navigation_state); + + navigation_state->set_title(base::UTF16ToUTF8(entry->GetTitleForDisplay())); + navigation_state->set_url(entry->GetURL().spec()); + + switch (entry->GetPageType()) { + case content::PageType::PAGE_TYPE_NORMAL: + case content::PageType::PAGE_TYPE_INTERSTITIAL: + navigation_state->set_page_type(fuchsia::web::PageType::NORMAL); + break; + case content::PageType::PAGE_TYPE_ERROR: + navigation_state->set_page_type(fuchsia::web::PageType::ERROR); + break; + } + + navigation_state->set_can_go_back(web_contents->GetController().CanGoBack()); + navigation_state->set_can_go_forward( + web_contents->GetController().CanGoForward()); +} + +} // namespace + +NavigationControllerImpl::NavigationControllerImpl( + content::WebContents* web_contents) + : web_contents_(web_contents), weak_factory_(this) { + Observe(web_contents_); +} + +NavigationControllerImpl::~NavigationControllerImpl() = default; + +void NavigationControllerImpl::AddBinding( + fidl::InterfaceRequest<fuchsia::web::NavigationController> controller) { + controller_bindings_.AddBinding(this, std::move(controller)); +} + +void NavigationControllerImpl::SetEventListener( + fidl::InterfaceHandle<fuchsia::web::NavigationEventListener> listener) { + // Reset the event buffer state. + waiting_for_navigation_event_ack_ = false; + previous_navigation_state_ = {}; + pending_navigation_event_ = {}; + + if (listener) { + navigation_listener_.Bind(std::move(listener)); + navigation_listener_.set_error_handler( + [this](zx_status_t status) { SetEventListener(nullptr); }); + } else { + navigation_listener_.Unbind(); + } +} + +void NavigationControllerImpl::OnNavigationEntryChanged() { + fuchsia::web::NavigationState new_state; + new_state.set_is_main_document_loaded(is_main_document_loaded_); + UpdateNavigationStateFromNavigationEntry( + web_contents_->GetController().GetVisibleEntry(), web_contents_, + &new_state); + + DiffNavigationEntries(previous_navigation_state_, new_state, + &pending_navigation_event_); + previous_navigation_state_ = std::move(new_state); + + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&NavigationControllerImpl::MaybeSendNavigationEvent, + weak_factory_.GetWeakPtr())); +} + +void NavigationControllerImpl::MaybeSendNavigationEvent() { + if (!navigation_listener_) + return; + + if (pending_navigation_event_.IsEmpty() || + waiting_for_navigation_event_ack_) { + return; + } + + waiting_for_navigation_event_ack_ = true; + + // Send the event to the observer and, upon acknowledgement, revisit this + // function to send another update. + navigation_listener_->OnNavigationStateChanged( + std::move(pending_navigation_event_), [this]() { + waiting_for_navigation_event_ack_ = false; + MaybeSendNavigationEvent(); + }); + + pending_navigation_event_ = {}; +} + +void NavigationControllerImpl::LoadUrl(std::string url, + fuchsia::web::LoadUrlParams params, + LoadUrlCallback callback) { + fuchsia::web::NavigationController_LoadUrl_Result result; + GURL validated_url(url); + if (!validated_url.is_valid()) { + result.set_err(fuchsia::web::NavigationControllerError::INVALID_URL); + callback(std::move(result)); + return; + } + + content::NavigationController::LoadURLParams params_converted(validated_url); + if (params.has_headers()) { + std::vector<std::string> extra_headers; + extra_headers.reserve(params.headers().size()); + for (const auto& header : params.headers()) { + // TODO(crbug.com/964732): Check there is no colon in |header_name|. + base::StringPiece header_name( + reinterpret_cast<const char*>(header.name.data()), + header.name.size()); + base::StringPiece header_value( + reinterpret_cast<const char*>(header.value.data()), + header.value.size()); + extra_headers.emplace_back( + base::StrCat({header_name, ": ", header_value})); + } + params_converted.extra_headers = base::JoinString(extra_headers, "\n"); + } + + if (validated_url.scheme() == url::kDataScheme) + params_converted.load_type = content::NavigationController::LOAD_TYPE_DATA; + + params_converted.transition_type = ui::PageTransitionFromInt( + ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); + if (params.has_was_user_activated() && params.was_user_activated()) { + params_converted.was_activated = content::WasActivatedOption::kYes; + } else { + params_converted.was_activated = content::WasActivatedOption::kNo; + } + + web_contents_->GetController().LoadURLWithParams(params_converted); + result.set_response(fuchsia::web::NavigationController_LoadUrl_Response()); + callback(std::move(result)); +} + +void NavigationControllerImpl::GoBack() { + if (web_contents_->GetController().CanGoBack()) + web_contents_->GetController().GoBack(); +} + +void NavigationControllerImpl::GoForward() { + if (web_contents_->GetController().CanGoForward()) + web_contents_->GetController().GoForward(); +} + +void NavigationControllerImpl::Stop() { + web_contents_->Stop(); +} + +void NavigationControllerImpl::Reload(fuchsia::web::ReloadType type) { + content::ReloadType internal_reload_type; + switch (type) { + case fuchsia::web::ReloadType::PARTIAL_CACHE: + internal_reload_type = content::ReloadType::NORMAL; + break; + case fuchsia::web::ReloadType::NO_CACHE: + internal_reload_type = content::ReloadType::BYPASSING_CACHE; + break; + } + web_contents_->GetController().Reload(internal_reload_type, false); +} + +void NavigationControllerImpl::GetVisibleEntry( + fuchsia::web::NavigationController::GetVisibleEntryCallback callback) { + content::NavigationEntry* entry = + web_contents_->GetController().GetVisibleEntry(); + if (!entry) { + callback({}); + return; + } + + fuchsia::web::NavigationState state; + state.set_is_main_document_loaded(is_main_document_loaded_); + UpdateNavigationStateFromNavigationEntry(entry, web_contents_, &state); + callback(std::move(state)); +} + +void NavigationControllerImpl::TitleWasSet(content::NavigationEntry* entry) { + // The title was changed after the document was loaded. + OnNavigationEntryChanged(); +} + +void NavigationControllerImpl::DocumentAvailableInMainFrame() { + // The main document is loaded, but not necessarily all the subresources. Some + // fields like "title" will change here. + + OnNavigationEntryChanged(); +} + +void NavigationControllerImpl::DidFinishLoad( + content::RenderFrameHost* render_frame_host, + const GURL& validated_url) { + // The document and its statically-declared subresources are loaded. + is_main_document_loaded_ = true; + OnNavigationEntryChanged(); +} + +void NavigationControllerImpl::DidStartNavigation( + content::NavigationHandle* navigation_handle) { + if (navigation_handle->IsSameDocument()) + return; + + is_main_document_loaded_ = false; + OnNavigationEntryChanged(); +} + +void DiffNavigationEntries(const fuchsia::web::NavigationState& old_entry, + const fuchsia::web::NavigationState& new_entry, + fuchsia::web::NavigationState* difference) { + DCHECK(difference); + + DCHECK(new_entry.has_title()); + if (!old_entry.has_title() || (new_entry.title() != old_entry.title())) { + difference->set_title(new_entry.title()); + } + + DCHECK(new_entry.has_url()); + if (!old_entry.has_url() || (new_entry.url() != old_entry.url())) { + difference->set_url(new_entry.url()); + } + + DCHECK(new_entry.has_page_type()); + if (!old_entry.has_page_type() || + (new_entry.page_type() != old_entry.page_type())) { + difference->set_page_type(new_entry.page_type()); + } + + DCHECK(new_entry.has_can_go_back()); + if (!old_entry.has_can_go_back() || + old_entry.can_go_back() != new_entry.can_go_back()) { + difference->set_can_go_back(new_entry.can_go_back()); + } + + DCHECK(new_entry.has_can_go_forward()); + if (!old_entry.has_can_go_forward() || + old_entry.can_go_forward() != new_entry.can_go_forward()) { + difference->set_can_go_forward(new_entry.can_go_forward()); + } + + DCHECK(new_entry.has_is_main_document_loaded()); + if (!old_entry.has_is_main_document_loaded() || + old_entry.is_main_document_loaded() != + new_entry.is_main_document_loaded()) { + difference->set_is_main_document_loaded( + new_entry.is_main_document_loaded()); + } +}
diff --git a/fuchsia/engine/browser/navigation_controller_impl.h b/fuchsia/engine/browser/navigation_controller_impl.h new file mode 100644 index 0000000..6d7b1159 --- /dev/null +++ b/fuchsia/engine/browser/navigation_controller_impl.h
@@ -0,0 +1,88 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FUCHSIA_ENGINE_BROWSER_NAVIGATION_CONTROLLER_IMPL_H_ +#define FUCHSIA_ENGINE_BROWSER_NAVIGATION_CONTROLLER_IMPL_H_ + +#include <fuchsia/web/cpp/fidl.h> +#include <lib/fidl/cpp/binding_set.h> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "content/public/browser/web_contents_observer.h" +#include "fuchsia/engine/web_engine_export.h" + +namespace content { +class NavigationEntry; +class NavigationHandle; +class WebContents; +} // namespace content + +// Implementation of fuchsia.web.NavigationController for content::WebContents. +class NavigationControllerImpl : public fuchsia::web::NavigationController, + public content::WebContentsObserver { + public: + explicit NavigationControllerImpl(content::WebContents* web_contents); + ~NavigationControllerImpl() final; + + void AddBinding( + fidl::InterfaceRequest<fuchsia::web::NavigationController> controller); + + void SetEventListener( + fidl::InterfaceHandle<fuchsia::web::NavigationEventListener> listener); + + private: + // Processes the most recent changes to the browser's navigation state and + // triggers the publishing of change events. + void OnNavigationEntryChanged(); + + // Sends |pending_navigation_event_| to the observer if there are any changes + // to be reported. + void MaybeSendNavigationEvent(); + + // fuchsia::web::NavigationController implementation. + void LoadUrl(std::string url, + fuchsia::web::LoadUrlParams params, + LoadUrlCallback callback) final; + void GoBack() final; + void GoForward() final; + void Stop() final; + void Reload(fuchsia::web::ReloadType type) final; + void GetVisibleEntry(GetVisibleEntryCallback callback) final; + + // content::WebContentsObserver implementation. + void TitleWasSet(content::NavigationEntry*) override; + void DocumentAvailableInMainFrame() override; + void DidFinishLoad(content::RenderFrameHost* render_frame_host, + const GURL& validated_url) override; + void DidStartNavigation( + content::NavigationHandle* navigation_handle) override; + + content::WebContents* const web_contents_; + + // NavigationController client bindings. + fidl::BindingSet<fuchsia::web::NavigationController> controller_bindings_; + + // Fields used to dispatch events to the NavigationEventListener. + fuchsia::web::NavigationEventListenerPtr navigation_listener_; + fuchsia::web::NavigationState previous_navigation_state_; + fuchsia::web::NavigationState pending_navigation_event_; + bool waiting_for_navigation_event_ack_ = false; + + // True once the main document finishes loading. + bool is_main_document_loaded_ = false; + + base::WeakPtrFactory<NavigationControllerImpl> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(NavigationControllerImpl); +}; + +// Computes the differences from old_entry to new_entry and stores the result in +// |difference|. +WEB_ENGINE_EXPORT void DiffNavigationEntries( + const fuchsia::web::NavigationState& old_entry, + const fuchsia::web::NavigationState& new_entry, + fuchsia::web::NavigationState* difference); + +#endif // FUCHSIA_ENGINE_BROWSER_NAVIGATION_CONTROLLER_IMPL_H_
diff --git a/google_apis/gaia/oauth2_access_token_manager.cc b/google_apis/gaia/oauth2_access_token_manager.cc index 1f425dd..4322d54 100644 --- a/google_apis/gaia/oauth2_access_token_manager.cc +++ b/google_apis/gaia/oauth2_access_token_manager.cc
@@ -16,6 +16,32 @@ int OAuth2AccessTokenManager::max_fetch_retry_num_ = 5; +OAuth2AccessTokenManager::RequestParameters::RequestParameters( + const std::string& client_id, + const CoreAccountId& account_id, + const OAuth2TokenService::ScopeSet& scopes) + : client_id(client_id), account_id(account_id), scopes(scopes) {} + +OAuth2AccessTokenManager::RequestParameters::RequestParameters( + const RequestParameters& other) = default; + +OAuth2AccessTokenManager::RequestParameters::~RequestParameters() {} + +bool OAuth2AccessTokenManager::RequestParameters::operator<( + const RequestParameters& p) const { + if (client_id < p.client_id) + return true; + else if (p.client_id < client_id) + return false; + + if (account_id < p.account_id) + return true; + else if (p.account_id < account_id) + return false; + + return scopes < p.scopes; +} + // Class that fetches an OAuth2 access token for a given account id and set of // scopes. // @@ -386,8 +412,8 @@ // If there is already a pending fetcher for |scopes| and |account_id|, // simply register this |request| for those results rather than starting // a new fetcher. - OAuth2TokenService::RequestParameters request_parameters = - OAuth2TokenService::RequestParameters(client_id, account_id, scopes); + RequestParameters request_parameters = + RequestParameters(client_id, account_id, scopes); auto iter = pending_fetchers_.find(request_parameters); if (iter != pending_fetchers_.end()) { iter->second->AddWaitingRequest(request->AsWeakPtr()); @@ -406,16 +432,15 @@ const OAuth2AccessTokenConsumer::TokenResponse& token_response) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - token_cache_[OAuth2TokenService::RequestParameters(client_id, account_id, - scopes)] = token_response; + token_cache_[RequestParameters(client_id, account_id, scopes)] = + token_response; } const OAuth2AccessTokenConsumer::TokenResponse* OAuth2AccessTokenManager::GetCachedTokenResponse( - const OAuth2TokenService::RequestParameters& request_parameters) { + const RequestParameters& request_parameters) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - OAuth2TokenService::TokenCache::iterator token_iterator = - token_cache_.find(request_parameters); + TokenCache::iterator token_iterator = token_cache_.find(request_parameters); if (token_iterator == token_cache_.end()) return nullptr; if (token_iterator->second.expiration_time <= base::Time::Now()) { @@ -438,7 +463,7 @@ void OAuth2AccessTokenManager::ClearCacheForAccount( const CoreAccountId& account_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - for (OAuth2TokenService::TokenCache::iterator iter = token_cache_.begin(); + for (TokenCache::iterator iter = token_cache_.begin(); iter != token_cache_.end(); /* iter incremented in body */) { if (iter->first.account_id == account_id) { @@ -468,6 +493,30 @@ CancelFetchers(fetchers_to_cancel); } +void OAuth2AccessTokenManager::InvalidateAccessToken( + const CoreAccountId& account_id, + const OAuth2TokenService::ScopeSet& scopes, + const std::string& access_token) { + // TODO(https://crbug.com/967598): Use directly + // OAuth2AccessTokenManager::InvalidateAccessTokenImpl once this fully manages + // access tokens independently of OAuth2TokenService. For now, some tests need + // to call overridden of OAuth2TokenService::InvalidateAccessTokenImpl. + token_service_->InvalidateAccessTokenImpl( + account_id, GaiaUrls::GetInstance()->oauth2_chrome_client_id(), scopes, + access_token); +} + +void OAuth2AccessTokenManager::InvalidateAccessTokenImpl( + const CoreAccountId& account_id, + const std::string& client_id, + const OAuth2TokenService::ScopeSet& scopes, + const std::string& access_token) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + RemoveCachedTokenResponse(RequestParameters(client_id, account_id, scopes), + access_token); + delegate_->InvalidateAccessToken(account_id, client_id, scopes, access_token); +} + void OAuth2AccessTokenManager:: set_max_authorization_token_fetch_retries_for_testing(int max_retries) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -478,8 +527,8 @@ const std::string& client_id, const CoreAccountId& account_id, const OAuth2TokenService::ScopeSet& scopes) const { - auto iter = pending_fetchers_.find( - OAuth2TokenService::RequestParameters(client_id, account_id, scopes)); + auto iter = + pending_fetchers_.find(RequestParameters(client_id, account_id, scopes)); return iter == pending_fetchers_.end() ? 0 : iter->second->GetWaitingRequestCount(); @@ -525,8 +574,7 @@ return std::move(request); } - OAuth2TokenService::RequestParameters request_parameters(client_id, - account_id, scopes); + RequestParameters request_parameters(client_id, account_id, scopes); const OAuth2AccessTokenConsumer::TokenResponse* token_response = GetCachedTokenResponse(request_parameters); if (token_response && token_response->access_token.length()) { @@ -547,7 +595,7 @@ void OAuth2AccessTokenManager::InformConsumerWithCachedTokenResponse( const OAuth2AccessTokenConsumer::TokenResponse* cache_token_response, OAuth2TokenService::RequestImpl* request, - const OAuth2TokenService::RequestParameters& request_parameters) { + const RequestParameters& request_parameters) { DCHECK(cache_token_response && cache_token_response->access_token.length()); for (auto& observer : diagnostics_observer_list_) { observer.OnFetchAccessTokenComplete( @@ -564,11 +612,10 @@ } bool OAuth2AccessTokenManager::RemoveCachedTokenResponse( - const OAuth2TokenService::RequestParameters& request_parameters, + const RequestParameters& request_parameters, const std::string& token_to_remove) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - OAuth2TokenService::TokenCache::iterator token_iterator = - token_cache_.find(request_parameters); + TokenCache::iterator token_iterator = token_cache_.find(request_parameters); if (token_iterator != token_cache_.end() && token_iterator->second.access_token == token_to_remove) { for (auto& observer : diagnostics_observer_list_) { @@ -617,7 +664,7 @@ // Then by (2), |fetcher| is recorded in |pending_fetchers_|. // Then by (3), |fetcher_| is mapped from its combination of client ID, // account ID, and scope set. - OAuth2TokenService::RequestParameters request_param( + RequestParameters request_param( fetcher->GetClientId(), fetcher->GetAccountId(), fetcher->GetScopeSet()); const OAuth2AccessTokenConsumer::TokenResponse* entry =
diff --git a/google_apis/gaia/oauth2_access_token_manager.h b/google_apis/gaia/oauth2_access_token_manager.h index 4271065..3277a094 100644 --- a/google_apis/gaia/oauth2_access_token_manager.h +++ b/google_apis/gaia/oauth2_access_token_manager.h
@@ -18,6 +18,25 @@ // Class that manages requests for OAuth2 access tokens. class OAuth2AccessTokenManager { public: + // The parameters used to fetch an OAuth2 access token. + struct RequestParameters { + RequestParameters(const std::string& client_id, + const CoreAccountId& account_id, + const OAuth2TokenService::ScopeSet& scopes); + RequestParameters(const RequestParameters& other); + ~RequestParameters(); + bool operator<(const RequestParameters& params) const; + + // OAuth2 client id. + std::string client_id; + // Account id for which the request is made. + CoreAccountId account_id; + // URL scopes for the requested access token. + OAuth2TokenService::ScopeSet scopes; + }; + typedef std::map<RequestParameters, OAuth2AccessTokenConsumer::TokenResponse> + TokenCache; + // TODO(https://crbug.com/967598): Remove |token_service| parameter once // OAuth2AccessTokenManager fully manages access tokens independently of // OAuth2TokenService and replace |delegate| with @@ -85,7 +104,7 @@ // ensure no entry with the same |client_scopes| is added before the usage of // the returned entry is done. const OAuth2AccessTokenConsumer::TokenResponse* GetCachedTokenResponse( - const OAuth2TokenService::RequestParameters& client_scopes); + const RequestParameters& client_scopes); // Clears the internal token cache. void ClearCache(); @@ -101,6 +120,22 @@ // Cancels all requests related to a given |account_id|. void CancelRequestsForAccount(const CoreAccountId& account_id); + // Mark an OAuth2 |access_token| issued for |account_id| and |scopes| as + // invalid. This should be done if the token was received from this class, + // but was not accepted by the server (e.g., the server returned + // 401 Unauthorized). The token will be removed from the cache for the given + // scopes. + void InvalidateAccessToken(const CoreAccountId& account_id, + const OAuth2TokenService::ScopeSet& scopes, + const std::string& access_token); + + // Invalidates the |access_token| issued for |account_id|, |client_id| and + // |scopes|. + void InvalidateAccessTokenImpl(const CoreAccountId& account_id, + const std::string& client_id, + const OAuth2TokenService::ScopeSet& scopes, + const std::string& access_token); + void set_max_authorization_token_fetch_retries_for_testing(int max_retries); // Returns the current number of pending fetchers matching given params. @@ -117,7 +152,7 @@ class Fetcher; friend class Fetcher; - OAuth2TokenService::TokenCache& token_cache() { return token_cache_; } + TokenCache& token_cache() { return token_cache_; } // Create an access token fetcher for the given account id. std::unique_ptr<OAuth2AccessTokenFetcher> CreateAccessTokenFetcher( @@ -140,13 +175,12 @@ void InformConsumerWithCachedTokenResponse( const OAuth2AccessTokenConsumer::TokenResponse* token_response, OAuth2TokenService::RequestImpl* request, - const OAuth2TokenService::RequestParameters& client_scopes); + const RequestParameters& client_scopes); // Removes an access token for the given set of scopes from the cache. // Returns true if the entry was removed, otherwise false. - bool RemoveCachedTokenResponse( - const OAuth2TokenService::RequestParameters& client_scopes, - const std::string& token_to_remove); + bool RemoveCachedTokenResponse(const RequestParameters& client_scopes, + const std::string& token_to_remove); // Called when |fetcher| finishes fetching. void OnFetchComplete(Fetcher* fetcher); @@ -155,7 +189,7 @@ void CancelFetchers(std::vector<Fetcher*> fetchers_to_cancel); // The cache of currently valid tokens. - OAuth2TokenService::TokenCache token_cache_; + TokenCache token_cache_; // List of observers to notify when access token status changes. base::ObserverList<AccessTokenDiagnosticsObserver, true>::Unchecked diagnostics_observer_list_; @@ -167,8 +201,7 @@ OAuth2TokenServiceDelegate* delegate_; // A map from fetch parameters to a fetcher that is fetching an OAuth2 access // token using these parameters. - std::map<OAuth2TokenService::RequestParameters, std::unique_ptr<Fetcher>> - pending_fetchers_; + std::map<RequestParameters, std::unique_ptr<Fetcher>> pending_fetchers_; // Maximum number of retries in fetching an OAuth2 access token. static int max_fetch_retry_num_;
diff --git a/google_apis/gaia/oauth2_token_service.cc b/google_apis/gaia/oauth2_token_service.cc index 749c9f0..e4faa5c 100644 --- a/google_apis/gaia/oauth2_token_service.cc +++ b/google_apis/gaia/oauth2_token_service.cc
@@ -23,33 +23,6 @@ #include "google_apis/gaia/oauth2_token_service_delegate.h" #include "services/network/public/cpp/shared_url_loader_factory.h" -OAuth2TokenService::RequestParameters::RequestParameters( - const std::string& client_id, - const CoreAccountId& account_id, - const ScopeSet& scopes) - : client_id(client_id), account_id(account_id), scopes(scopes) {} - -OAuth2TokenService::RequestParameters::RequestParameters( - const RequestParameters& other) = default; - -OAuth2TokenService::RequestParameters::~RequestParameters() { -} - -bool OAuth2TokenService::RequestParameters::operator<( - const RequestParameters& p) const { - if (client_id < p.client_id) - return true; - else if (p.client_id < client_id) - return false; - - if (account_id < p.account_id) - return true; - else if (p.account_id < account_id) - return false; - - return scopes < p.scopes; -} - OAuth2TokenService::RequestImpl::RequestImpl( const CoreAccountId& account_id, OAuth2TokenService::Consumer* consumer) @@ -116,8 +89,8 @@ return token_manager_->diagnostics_observer_list_; } -OAuth2TokenService::TokenCache& OAuth2TokenService::token_cache() { - return token_manager_->token_cache(); +int OAuth2TokenService::GetTokenCacheCount() { + return token_manager_->token_cache().size(); } void OAuth2TokenService::AddObserver(OAuth2TokenServiceObserver* observer) { @@ -183,11 +156,6 @@ client_secret, scopes, consumer); } -scoped_refptr<network::SharedURLLoaderFactory> -OAuth2TokenService::GetURLLoaderFactory() const { - return delegate_->GetURLLoaderFactory(); -} - std::unique_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequestWithContext( const CoreAccountId& account_id, @@ -241,9 +209,7 @@ const CoreAccountId& account_id, const ScopeSet& scopes, const std::string& access_token) { - InvalidateAccessTokenImpl(account_id, - GaiaUrls::GetInstance()->oauth2_chrome_client_id(), - scopes, access_token); + token_manager_->InvalidateAccessToken(account_id, scopes, access_token); } void OAuth2TokenService::InvalidateTokenForMultilogin( @@ -259,23 +225,14 @@ delegate_->InvalidateTokenForMultilogin(failed_account); } -void OAuth2TokenService::InvalidateAccessTokenForClient( - const CoreAccountId& account_id, - const std::string& client_id, - const ScopeSet& scopes, - const std::string& access_token) { - InvalidateAccessTokenImpl(account_id, client_id, scopes, access_token); -} - void OAuth2TokenService::InvalidateAccessTokenImpl( const CoreAccountId& account_id, const std::string& client_id, const ScopeSet& scopes, const std::string& access_token) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - token_manager_->RemoveCachedTokenResponse( - RequestParameters(client_id, account_id, scopes), access_token); - delegate_->InvalidateAccessToken(account_id, client_id, scopes, access_token); + token_manager_->InvalidateAccessTokenImpl(account_id, client_id, scopes, + access_token); } void OAuth2TokenService::OnRefreshTokensLoaded() {
diff --git a/google_apis/gaia/oauth2_token_service.h b/google_apis/gaia/oauth2_token_service.h index b32b785d0..1178ade 100644 --- a/google_apis/gaia/oauth2_token_service.h +++ b/google_apis/gaia/oauth2_token_service.h
@@ -91,25 +91,6 @@ std::string id_; }; - // The parameters used to fetch an OAuth2 access token. - struct RequestParameters { - RequestParameters(const std::string& client_id, - const CoreAccountId& account_id, - const ScopeSet& scopes); - RequestParameters(const RequestParameters& other); - ~RequestParameters(); - bool operator<(const RequestParameters& params) const; - - // OAuth2 client id. - std::string client_id; - // Account id for which the request is made. - CoreAccountId account_id; - // URL scopes for the requested access token. - ScopeSet scopes; - }; - typedef std::map<RequestParameters, OAuth2AccessTokenConsumer::TokenResponse> - TokenCache; - explicit OAuth2TokenService( std::unique_ptr<OAuth2TokenServiceDelegate> delegate); ~OAuth2TokenService() override; @@ -158,7 +139,7 @@ // This method does the same as |StartRequest| except it uses the // URLLoaderfactory given by |url_loader_factory| instead of using the one - // returned by |GetURLLoaderFactory| implemented by derived classes. + // returned by Delegate::GetURLLoaderFactory(). // Deprecated. It's moved to OAuth2AccessTokenManager. std::unique_ptr<Request> StartRequestWithContext( const CoreAccountId& account_id, @@ -199,17 +180,11 @@ // but was not accepted by the server (e.g., the server returned // 401 Unauthorized). The token will be removed from the cache for the given // scopes. + // Deprecated. It's moved to OAuth2AccessTokenManager. void InvalidateAccessToken(const CoreAccountId& account_id, const ScopeSet& scopes, const std::string& access_token); - // Like |InvalidateToken| except is uses |client_id| to identity OAuth2 client - // app that issued the request instead of Chrome's default values. - void InvalidateAccessTokenForClient(const CoreAccountId& account_id, - const std::string& client_id, - const ScopeSet& scopes, - const std::string& access_token); - // Removes token from cache (if it is cached) and calls // InvalidateTokenForMultilogin method of the delegate. This should be done if // the token was received from this class, but was not accepted by the server @@ -230,7 +205,7 @@ // TODO(https://crbug.com/967598): Remove this. It's opened only for // OAuth2TokenServiceTest. - OAuth2TokenService::TokenCache& token_cache(); + int GetTokenCacheCount(); const base::ObserverList<AccessTokenDiagnosticsObserver, true>::Unchecked& GetAccessTokenDiagnosticsObservers(); @@ -313,8 +288,9 @@ const ScopeSet& scopes); // Invalidates the |access_token| issued for |account_id|, |client_id| and - // |scopes|. Virtual so it can be overriden for tests and for platform- - // specifc behavior. + // |scopes|. Virtual so it can be overridden for tests and for platform- + // specific behavior. + // Deprecated. It's moved to OAuth2AccessTokenManager. virtual void InvalidateAccessTokenImpl(const CoreAccountId& account_id, const std::string& client_id, const ScopeSet& scopes, @@ -323,10 +299,6 @@ private: friend class OAuth2TokenServiceDelegate; - // Provide a URLLoaderFactory used for fetching access tokens with the - // |StartRequest| method. - scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() const; - std::unique_ptr<OAuth2TokenServiceDelegate> delegate_; // The depth of batch changes.
diff --git a/google_apis/gaia/oauth2_token_service_unittest.cc b/google_apis/gaia/oauth2_token_service_unittest.cc index a7d7e25d..72d9361 100644 --- a/google_apis/gaia/oauth2_token_service_unittest.cc +++ b/google_apis/gaia/oauth2_token_service_unittest.cc
@@ -16,6 +16,7 @@ #include "google_apis/gaia/oauth2_access_token_consumer.h" #include "google_apis/gaia/oauth2_access_token_fetcher_immediate_error.h" #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h" +#include "google_apis/gaia/oauth2_access_token_manager.h" #include "google_apis/gaia/oauth2_token_service.h" #include "google_apis/gaia/oauth2_token_service_test_util.h" #include "net/http/http_status_code.h" @@ -770,15 +771,15 @@ const CoreAccountId account_id0("0"); const CoreAccountId account_id1("1"); - OAuth2TokenService::RequestParameters params[] = { - OAuth2TokenService::RequestParameters("0", account_id0, set_0), - OAuth2TokenService::RequestParameters("0", account_id0, set_1), - OAuth2TokenService::RequestParameters("0", account_id1, set_0), - OAuth2TokenService::RequestParameters("0", account_id1, set_1), - OAuth2TokenService::RequestParameters("1", account_id0, set_0), - OAuth2TokenService::RequestParameters("1", account_id0, set_1), - OAuth2TokenService::RequestParameters("1", account_id1, set_0), - OAuth2TokenService::RequestParameters("1", account_id1, set_1), + OAuth2AccessTokenManager::RequestParameters params[] = { + OAuth2AccessTokenManager::RequestParameters("0", "0", set_0), + OAuth2AccessTokenManager::RequestParameters("0", "0", set_1), + OAuth2AccessTokenManager::RequestParameters("0", "1", set_0), + OAuth2AccessTokenManager::RequestParameters("0", "1", set_1), + OAuth2AccessTokenManager::RequestParameters("1", "0", set_0), + OAuth2AccessTokenManager::RequestParameters("1", "0", set_1), + OAuth2AccessTokenManager::RequestParameters("1", "1", set_0), + OAuth2AccessTokenManager::RequestParameters("1", "1", set_1), }; for (size_t i = 0; i < base::size(params); i++) { @@ -811,11 +812,11 @@ EXPECT_EQ(1, consumer_.number_of_successful_tokens_); EXPECT_EQ(0, consumer_.number_of_errors_); EXPECT_EQ("token", consumer_.last_token_); - EXPECT_EQ(1, (int)oauth2_service_->token_cache().size()); + EXPECT_EQ(1, oauth2_service_->GetTokenCacheCount()); oauth2_service_->ClearCache(); - EXPECT_EQ(0, (int)oauth2_service_->token_cache().size()); + EXPECT_EQ(0, oauth2_service_->GetTokenCacheCount()); oauth2_service_->GetFakeOAuth2TokenServiceDelegate()->UpdateCredentials( account_id, "refreshToken"); SimulateOAuthTokenResponse(GetValidTokenResponse("another token", 3600)); @@ -824,7 +825,7 @@ EXPECT_EQ(2, consumer_.number_of_successful_tokens_); EXPECT_EQ(0, consumer_.number_of_errors_); EXPECT_EQ("another token", consumer_.last_token_); - EXPECT_EQ(1, (int)oauth2_service_->token_cache().size()); + EXPECT_EQ(1, oauth2_service_->GetTokenCacheCount()); } TEST_F(OAuth2TokenServiceTest, FixRequestErrorIfPossible) {
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index 26a144c..fe1e9b4 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -392,6 +392,7 @@ "//ui/platform_window", "//ui/platform_window:platform_impls", ] + sources += [ "command_buffer/service/swap_chain_factory_dxgi_unittest.cc" ] } if (use_dawn) {
diff --git a/gpu/command_buffer/service/swap_chain_factory_dxgi.cc b/gpu/command_buffer/service/swap_chain_factory_dxgi.cc index f67a7d2..3f3fd71e 100644 --- a/gpu/command_buffer/service/swap_chain_factory_dxgi.cc +++ b/gpu/command_buffer/service/swap_chain_factory_dxgi.cc
@@ -13,6 +13,7 @@ #include "gpu/command_buffer/service/shared_image_backing.h" #include "gpu/command_buffer/service/shared_image_representation.h" #include "gpu/command_buffer/service/texture_manager.h" +#include "ui/gl/direct_composition_surface_win.h" #include "ui/gl/gl_angle_util_win.h" #include "ui/gl/gl_image_dxgi_swap_chain.h" #include "ui/gl/trace_util.h" @@ -229,15 +230,15 @@ gl::GLImage* image; unsigned target = GL_TEXTURE_2D; - gles2::Texture::ImageState image_state; if (texture_) { + gles2::Texture::ImageState image_state; image = texture_->GetLevelImage(target, 0, &image_state); + DCHECK_EQ(image_state, gles2::Texture::BOUND); } else { DCHECK(texture_passthrough_); image = texture_passthrough_->GetLevelImage(target, 0); } DCHECK(image); - DCHECK_EQ(image_state, gles2::Texture::BOUND); if (!image->BindTexImage(target)) { DLOG(ERROR) << "Failed to rebind texture to new surface."; @@ -291,6 +292,11 @@ SwapChainFactoryDXGI::SwapChainBackings::operator=( SwapChainFactoryDXGI::SwapChainBackings&&) = default; +// static +bool SwapChainFactoryDXGI::IsSupported() { + return gl::DirectCompositionSurfaceWin::IsDirectCompositionSupported(); +} + std::unique_ptr<SharedImageBacking> SwapChainFactoryDXGI::MakeBacking( const Mailbox& mailbox, viz::ResourceFormat format, @@ -314,6 +320,10 @@ auto image = base::MakeRefCounted<gl::GLImageDXGISwapChain>( size, viz::BufferFormat(format), d3d11_texture, swap_chain); + if (!image->Initialize()) { + DLOG(ERROR) << "Failed to create EGL image"; + return nullptr; + } if (!image->BindTexImage(target)) { DLOG(ERROR) << "Failed to bind image to swap chain D3D11 texture."; return nullptr; @@ -393,7 +403,7 @@ desc.Stereo = FALSE; desc.SampleDesc.Count = 1; desc.BufferCount = 2; - desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT; desc.Scaling = DXGI_SCALING_STRETCH; desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; desc.Flags = 0;
diff --git a/gpu/command_buffer/service/swap_chain_factory_dxgi.h b/gpu/command_buffer/service/swap_chain_factory_dxgi.h index ba21b19..07a1d98 100644 --- a/gpu/command_buffer/service/swap_chain_factory_dxgi.h +++ b/gpu/command_buffer/service/swap_chain_factory_dxgi.h
@@ -28,7 +28,10 @@ explicit SwapChainFactoryDXGI(bool use_passthrough); ~SwapChainFactoryDXGI(); - struct SwapChainBackings { + // Returns true if DXGI swap chain shared images for overlays are supported. + static bool IsSupported(); + + struct GPU_GLES2_EXPORT SwapChainBackings { SwapChainBackings(std::unique_ptr<SharedImageBacking> front_buffer, std::unique_ptr<SharedImageBacking> back_buffer); ~SwapChainBackings(); @@ -71,4 +74,4 @@ } // namespace gpu -#endif // GPU_COMMAND_BUFFER_SERVICE_SWAP_CHAIN_FACTORY_DXGI_H_ \ No newline at end of file +#endif // GPU_COMMAND_BUFFER_SERVICE_SWAP_CHAIN_FACTORY_DXGI_H_
diff --git a/gpu/command_buffer/service/swap_chain_factory_dxgi_unittest.cc b/gpu/command_buffer/service/swap_chain_factory_dxgi_unittest.cc new file mode 100644 index 0000000..c27dcde --- /dev/null +++ b/gpu/command_buffer/service/swap_chain_factory_dxgi_unittest.cc
@@ -0,0 +1,277 @@ +// 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 "gpu/command_buffer/service/swap_chain_factory_dxgi.h" + +#include <memory> +#include <utility> + +#include "base/bind_helpers.h" +#include "gpu/command_buffer/common/shared_image_usage.h" +#include "gpu/command_buffer/service/service_utils.h" +#include "gpu/command_buffer/service/shared_context_state.h" +#include "gpu/command_buffer/service/shared_image_factory.h" +#include "gpu/command_buffer/service/shared_image_manager.h" +#include "gpu/command_buffer/service/shared_image_representation.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gl/gl_context.h" +#include "ui/gl/gl_image_dxgi_swap_chain.h" +#include "ui/gl/gl_surface.h" +#include "ui/gl/init/gl_factory.h" + +namespace gpu { +namespace { + +class SwapChainFactoryDXGITest : public testing::Test { + public: + void SetUp() override { + surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size()); + ASSERT_TRUE(surface_); + context_ = gl::init::CreateGLContext(nullptr, surface_.get(), + gl::GLContextAttribs()); + ASSERT_TRUE(context_); + bool result = context_->MakeCurrent(surface_.get()); + ASSERT_TRUE(result); + + memory_type_tracker_ = std::make_unique<MemoryTypeTracker>(nullptr); + shared_image_representation_factory_ = + std::make_unique<SharedImageRepresentationFactory>( + &shared_image_manager_, nullptr); + } + + protected: + bool UsesPassthrough() const { + return gles2::PassthroughCommandDecoderSupported(); + } + void CreateAndPresentSwapChain(bool uses_passthrough_texture); + + scoped_refptr<gl::GLSurface> surface_; + scoped_refptr<gl::GLContext> context_; + SharedImageManager shared_image_manager_; + std::unique_ptr<MemoryTypeTracker> memory_type_tracker_; + std::unique_ptr<SharedImageRepresentationFactory> + shared_image_representation_factory_; +}; + +void SwapChainFactoryDXGITest::CreateAndPresentSwapChain( + bool uses_passthrough_texture) { + DCHECK(SwapChainFactoryDXGI::IsSupported()); + std::unique_ptr<SwapChainFactoryDXGI> swap_chain_factory_ = + std::make_unique<SwapChainFactoryDXGI>(uses_passthrough_texture); + auto front_buffer_mailbox = Mailbox::GenerateForSharedImage(); + auto back_buffer_mailbox = Mailbox::GenerateForSharedImage(); + auto format = viz::RGBA_8888; + gfx::Size size(1, 1); + auto color_space = gfx::ColorSpace::CreateSRGB(); + uint32_t usage = gpu::SHARED_IMAGE_USAGE_GLES2 | + gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT | + gpu::SHARED_IMAGE_USAGE_DISPLAY | + gpu::SHARED_IMAGE_USAGE_SCANOUT; + + auto backings = swap_chain_factory_->CreateSwapChain( + front_buffer_mailbox, back_buffer_mailbox, format, size, color_space, + usage); + ASSERT_TRUE(backings.front_buffer); + ASSERT_TRUE(backings.back_buffer); + + GLenum expected_target = GL_TEXTURE_2D; + Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture; + scoped_refptr<gles2::TexturePassthrough> back_passthrough_texture; + gles2::Texture* back_texture; + gl::GLImageDXGISwapChain* back_image; + gl::GLImageDXGISwapChain* front_image; + + std::unique_ptr<SharedImageRepresentationFactoryRef> back_factory_ref = + shared_image_manager_.Register(std::move(backings.back_buffer), + memory_type_tracker_.get()); + std::unique_ptr<SharedImageRepresentationFactoryRef> front_factory_ref = + shared_image_manager_.Register(std::move(backings.front_buffer), + memory_type_tracker_.get()); + + if (uses_passthrough_texture) { + auto back_gl_representation = + shared_image_representation_factory_->ProduceGLTexturePassthrough( + back_buffer_mailbox); + ASSERT_TRUE(back_gl_representation); + back_passthrough_texture = back_gl_representation->GetTexturePassthrough(); + EXPECT_TRUE(back_passthrough_texture); + EXPECT_EQ(TextureBase::Type::kPassthrough, + back_passthrough_texture->GetType()); + EXPECT_EQ(expected_target, back_passthrough_texture->target()); + back_gl_representation.reset(); + + back_image = gl::GLImageDXGISwapChain::FromGLImage( + back_passthrough_texture->GetLevelImage( + back_passthrough_texture->target(), 0)); + ASSERT_TRUE(back_image); + + auto front_gl_representation = + shared_image_representation_factory_->ProduceGLTexturePassthrough( + front_buffer_mailbox); + ASSERT_TRUE(front_gl_representation); + auto front_passthrough_texture = + front_gl_representation->GetTexturePassthrough(); + EXPECT_TRUE(front_passthrough_texture); + EXPECT_EQ(TextureBase::Type::kPassthrough, + front_passthrough_texture->GetType()); + EXPECT_EQ(expected_target, front_passthrough_texture->target()); + front_gl_representation.reset(); + + front_image = gl::GLImageDXGISwapChain::FromGLImage( + front_passthrough_texture->GetLevelImage( + front_passthrough_texture->target(), 0)); + ASSERT_TRUE(front_image); + front_passthrough_texture.reset(); + } else { + auto back_gl_representation = + shared_image_representation_factory_->ProduceGLTexture( + back_buffer_mailbox); + ASSERT_TRUE(back_gl_representation); + back_texture = back_gl_representation->GetTexture(); + EXPECT_TRUE(back_texture); + EXPECT_EQ(TextureBase::Type::kValidated, back_texture->GetType()); + EXPECT_EQ(expected_target, back_texture->target()); + // Ensures that back buffer is explicitly cleared. + EXPECT_TRUE(back_texture->IsLevelCleared(back_texture->target(), 0)); + back_gl_representation.reset(); + + gles2::Texture::ImageState image_state; + back_image = gl::GLImageDXGISwapChain::FromGLImage( + back_texture->GetLevelImage(back_texture->target(), 0, &image_state)); + ASSERT_TRUE(back_image); + EXPECT_EQ(gles2::Texture::BOUND, image_state); + + auto front_gl_representation = + shared_image_representation_factory_->ProduceGLTexture( + front_buffer_mailbox); + ASSERT_TRUE(front_gl_representation); + gles2::Texture* front_texture = front_gl_representation->GetTexture(); + EXPECT_TRUE(front_texture); + EXPECT_EQ(TextureBase::Type::kValidated, front_texture->GetType()); + EXPECT_EQ(expected_target, front_texture->target()); + // Ensures that front buffer is explicitly cleared. + EXPECT_TRUE(front_texture->IsLevelCleared(front_texture->target(), 0)); + front_gl_representation.reset(); + + front_image = gl::GLImageDXGISwapChain::FromGLImage( + front_texture->GetLevelImage(front_texture->target(), 0, &image_state)); + ASSERT_TRUE(front_image); + EXPECT_EQ(gles2::Texture::BOUND, image_state); + } + + EXPECT_EQ(S_OK, back_image->swap_chain()->GetBuffer( + 0 /* buffer_index */, IID_PPV_ARGS(&d3d11_texture))); + EXPECT_TRUE(d3d11_texture); + EXPECT_EQ(d3d11_texture, back_image->texture()); + d3d11_texture.Reset(); + + EXPECT_EQ(S_OK, front_image->swap_chain()->GetBuffer( + 1 /* buffer_index */, IID_PPV_ARGS(&d3d11_texture))); + EXPECT_TRUE(d3d11_texture); + EXPECT_EQ(d3d11_texture, front_image->texture()); + d3d11_texture.Reset(); + + GLenum target; + GLuint service_id; + if (uses_passthrough_texture) { + target = back_passthrough_texture->target(); + service_id = back_passthrough_texture->service_id(); + back_passthrough_texture.reset(); + } else { + target = back_texture->target(); + service_id = back_texture->service_id(); + } + + // Create an FBO. + GLuint fbo = 0; + gl::GLApi* api = gl::g_current_gl_context; + api->glGenFramebuffersEXTFn(1, &fbo); + api->glBindFramebufferEXTFn(GL_FRAMEBUFFER, fbo); + api->glBindTextureFn(target, service_id); + ASSERT_EQ(api->glGetErrorFn(), static_cast<GLenum>(GL_NO_ERROR)); + + // Attach the texture to FBO. + api->glFramebufferTexture2DEXTFn(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, + service_id, 0); + EXPECT_EQ(api->glCheckFramebufferStatusEXTFn(GL_FRAMEBUFFER), + static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE)); + ASSERT_EQ(api->glGetErrorFn(), static_cast<GLenum>(GL_NO_ERROR)); + + api->glViewportFn(0, 0, size.width(), size.height()); + // Set the clear color to green. + api->glClearColorFn(0.0f, 1.0f, 0.0f, 1.0f); + api->glClearFn(GL_COLOR_BUFFER_BIT); + ASSERT_EQ(api->glGetErrorFn(), static_cast<GLenum>(GL_NO_ERROR)); + + { + GLubyte pixel_color[4]; + const uint8_t expected_color[4] = {0, 255, 0, 255}; + // Checks if rendering to back buffer was successful. + api->glReadPixelsFn(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel_color); + EXPECT_EQ(expected_color[0], pixel_color[0]); + EXPECT_EQ(expected_color[1], pixel_color[1]); + EXPECT_EQ(expected_color[2], pixel_color[2]); + EXPECT_EQ(expected_color[3], pixel_color[3]); + } + + back_factory_ref->PresentSwapChain(); + + // TODO(ashithasantosh): Check contents of front buffer. + { + GLubyte pixel_color[4]; + const uint8_t expected_color[4] = {0, 0, 0, 255}; + // After present, back buffer should now have a clear texture. + api->glReadPixelsFn(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel_color); + EXPECT_EQ(expected_color[0], pixel_color[0]); + EXPECT_EQ(expected_color[1], pixel_color[1]); + EXPECT_EQ(expected_color[2], pixel_color[2]); + EXPECT_EQ(expected_color[3], pixel_color[3]); + } + api->glDeleteFramebuffersEXTFn(1, &fbo); +} + +TEST_F(SwapChainFactoryDXGITest, InvalidFormat) { + if (!SwapChainFactoryDXGI::IsSupported()) + return; + std::unique_ptr<SwapChainFactoryDXGI> swap_chain_factory_ = + std::make_unique<SwapChainFactoryDXGI>(false /* use_passthrough */); + auto front_buffer_mailbox = Mailbox::GenerateForSharedImage(); + auto back_buffer_mailbox = Mailbox::GenerateForSharedImage(); + gfx::Size size(1, 1); + auto color_space = gfx::ColorSpace::CreateSRGB(); + uint32_t usage = gpu::SHARED_IMAGE_USAGE_SCANOUT; + { + auto valid_format = viz::RGBA_8888; + auto backings = swap_chain_factory_->CreateSwapChain( + front_buffer_mailbox, back_buffer_mailbox, valid_format, size, + color_space, usage); + EXPECT_TRUE(backings.front_buffer); + EXPECT_TRUE(backings.back_buffer); + backings.front_buffer->Destroy(); + backings.back_buffer->Destroy(); + } + { + auto invalid_format = viz::BGRA_8888; + auto backings = swap_chain_factory_->CreateSwapChain( + front_buffer_mailbox, back_buffer_mailbox, invalid_format, size, + color_space, usage); + EXPECT_FALSE(backings.front_buffer); + EXPECT_FALSE(backings.back_buffer); + } +} + +TEST_F(SwapChainFactoryDXGITest, CreateAndPresentSwapChain) { + if (!SwapChainFactoryDXGI::IsSupported() || UsesPassthrough()) + return; + CreateAndPresentSwapChain(false /* uses_passthrough_texture */); +} + +TEST_F(SwapChainFactoryDXGITest, CreateAndPresentSwapChain_PassthroughTexture) { + if (!SwapChainFactoryDXGI::IsSupported() || !UsesPassthrough()) + return; + CreateAndPresentSwapChain(true /* uses_passthrough_texture */); +} + +} // anonymous namespace +} // namespace gpu
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc index e9039ab..1677aaec 100644 --- a/headless/lib/browser/headless_content_browser_client.cc +++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -289,12 +289,13 @@ } } -void HeadlessContentBrowserClient::SelectClientCertificate( +base::OnceClosure HeadlessContentBrowserClient::SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs, std::unique_ptr<content::ClientCertificateDelegate> delegate) { delegate->ContinueWithCertificate(nullptr, nullptr); + return base::OnceClosure(); } void HeadlessContentBrowserClient::ResourceDispatcherHostCreated() {
diff --git a/headless/lib/browser/headless_content_browser_client.h b/headless/lib/browser/headless_content_browser_client.h index 4e0c3c2..f87a1798 100644 --- a/headless/lib/browser/headless_content_browser_client.h +++ b/headless/lib/browser/headless_content_browser_client.h
@@ -55,7 +55,7 @@ bool expired_previous_decision, const base::Callback<void(content::CertificateRequestResultType)>& callback) override; - void SelectClientCertificate( + base::OnceClosure SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs,
diff --git a/ios/chrome/app/spotlight/bookmarks_spotlight_manager.mm b/ios/chrome/app/spotlight/bookmarks_spotlight_manager.mm index aac97fe6..476d36f1 100644 --- a/ios/chrome/app/spotlight/bookmarks_spotlight_manager.mm +++ b/ios/chrome/app/spotlight/bookmarks_spotlight_manager.mm
@@ -214,10 +214,8 @@ spotlight::DeleteItemsWithIdentifiers(@[ spotlightID ], completion); return; } - int childCount = node->child_count(); - for (int child = 0; child < childCount; child++) { - [self removeNodeFromIndex:node->GetChild(child)]; - } + for (const auto& child : node->children()) + [self removeNodeFromIndex:child.get()]; } - (BOOL)shouldReindex { @@ -274,10 +272,8 @@ } return; } - int childCount = node->child_count(); - for (int child = 0; child < childCount; child++) { - [self refreshNodeInIndex:node->GetChild(child) initial:initial]; - } + for (const auto& child : node->children()) + [self refreshNodeInIndex:child.get() initial:initial]; } - (void)shutdown {
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn index 4a5844b..4460e586 100644 --- a/ios/chrome/browser/autofill/BUILD.gn +++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -331,6 +331,8 @@ "//components/test/data/autofill/heuristics/input/153_fmm-en_inm.gob.mx.html", "//components/test/data/autofill/heuristics/input/154_fmm-es_inm.gob.mx.html", "//components/test/data/autofill/heuristics/input/155_fmm-ja_inm.gob.mx.html", + "//components/test/data/autofill/heuristics/input/156_buyAlbum_bandcamp.com_price.html", + "//components/test/data/autofill/heuristics/input/157_bug_971402_opentable_checkout.html", "//components/test/data/autofill/heuristics/output/000_i18n_de.out", "//components/test/data/autofill/heuristics/output/001_i18n_de2.out", "//components/test/data/autofill/heuristics/output/002_i18n_en.out", @@ -486,6 +488,8 @@ "//components/test/data/autofill/heuristics/output/153_fmm-en_inm.gob.mx.out", "//components/test/data/autofill/heuristics/output/154_fmm-es_inm.gob.mx.out", "//components/test/data/autofill/heuristics/output/155_fmm-ja_inm.gob.mx.out", + "//components/test/data/autofill/heuristics/output/156_buyAlbum_bandcamp.com_price.out", + "//components/test/data/autofill/heuristics/output/157_bug_971402_opentable_checkout.out", ] outputs = [ "{{bundle_resources_dir}}/" +
diff --git a/ios/chrome/browser/bookmarks/bookmarks_utils.cc b/ios/chrome/browser/bookmarks/bookmarks_utils.cc index 62d97f9..1d50ff19 100644 --- a/ios/chrome/browser/bookmarks/bookmarks_utils.cc +++ b/ios/chrome/browser/bookmarks/bookmarks_utils.cc
@@ -31,11 +31,10 @@ bookmark_model->RemoveAllUserBookmarks(); - for (int i = 0; i < bookmark_model->root_node()->child_count(); ++i) { - if (!bookmark_model->client()->CanBeEditedByUser( - bookmark_model->root_node()->GetChild(i))) + for (const auto& child : bookmark_model->root_node()->children()) { + if (!bookmark_model->client()->CanBeEditedByUser(child.get())) continue; - if (!bookmark_model->root_node()->GetChild(i)->children().empty()) + if (!child->children().empty()) return false; } @@ -60,11 +59,9 @@ std::vector<const BookmarkNode*> primary_permanent_nodes = PrimaryPermanentNodes(model); for (const BookmarkNode* parent : primary_permanent_nodes) { - int child_count = parent->child_count(); - for (int i = 0; i < child_count; ++i) { - const BookmarkNode* node = parent->GetChild(i); - if (node->is_folder() && node->IsVisible()) - root_level_folders.push_back(node); + for (const auto& child : parent->children()) { + if (child->is_folder() && child->IsVisible()) + root_level_folders.push_back(child.get()); } } return root_level_folders;
diff --git a/ios/chrome/browser/ui/activity_services/activity_service_controller_unittest.mm b/ios/chrome/browser/ui/activity_services/activity_service_controller_unittest.mm index 82f50ec..12c6be0 100644 --- a/ios/chrome/browser/ui/activity_services/activity_service_controller_unittest.mm +++ b/ios/chrome/browser/ui/activity_services/activity_service_controller_unittest.mm
@@ -648,7 +648,7 @@ // Verify bookmarked URL. GURL bookmarkedURL = GURL("https://chromium.org/page"); const bookmarks::BookmarkNode* defaultFolder = bookmark_model_->mobile_node(); - bookmark_model_->AddURL(defaultFolder, defaultFolder->child_count(), + bookmark_model_->AddURL(defaultFolder, defaultFolder->children().size(), base::SysNSStringToUTF16(@"Test bookmark"), bookmarkedURL); data = [[ShareToData alloc]
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm index d8ebe725..5c351159 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
@@ -269,7 +269,7 @@ } else { DCHECK(!self.folder); self.folder = self.bookmarkModel->AddFolder( - self.parentFolder, self.parentFolder->child_count(), folderTitle); + self.parentFolder, self.parentFolder->children().size(), folderTitle); } [self.delegate bookmarkFolderEditor:self didFinishEditingFolder:self.folder]; }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_mediator.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_mediator.mm index 1033b38..3088b7f 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_mediator.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_mediator.mm
@@ -133,13 +133,11 @@ return; } // Add all bookmarks and folders of the current root node to the table. - int childCount = self.sharedState.tableViewDisplayedRootNode->child_count(); - for (int i = 0; i < childCount; ++i) { - const BookmarkNode* node = - self.sharedState.tableViewDisplayedRootNode->GetChild(i); + for (const auto& child : + self.sharedState.tableViewDisplayedRootNode->children()) { BookmarkHomeNodeItem* nodeItem = [[BookmarkHomeNodeItem alloc] initWithType:BookmarkHomeItemTypeBookmark - bookmarkNode:node]; + bookmarkNode:child.get()]; [self.sharedState.tableViewModel addItem:nodeItem toSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks];
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm index ac8d6e7..4dc7c41 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -1069,7 +1069,7 @@ self.sharedState.editingFolderNode = self.sharedState.bookmarkModel->AddFolder( self.sharedState.tableViewDisplayedRootNode, - self.sharedState.tableViewDisplayedRootNode->child_count(), + self.sharedState.tableViewDisplayedRootNode->children().size(), folderTitle); BookmarkHomeNodeItem* nodeItem = [[BookmarkHomeNodeItem alloc] @@ -1248,13 +1248,11 @@ std::copy(editNodes.begin(), editNodes.end(), std::back_inserter(nodes)); } else { // Create a vector of edit nodes in the same order as the nodes in folder. - int childCount = self.sharedState.tableViewDisplayedRootNode->child_count(); - for (int i = 0; i < childCount; ++i) { - const BookmarkNode* node = - self.sharedState.tableViewDisplayedRootNode->GetChild(i); - if (self.sharedState.editNodes.find(node) != + for (const auto& child : + self.sharedState.tableViewDisplayedRootNode->children()) { + if (self.sharedState.editNodes.find(child.get()) != self.sharedState.editNodes.end()) { - nodes.push_back(node); + nodes.push_back(child.get()); } } }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.mm b/ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.mm index e370a2bd..541b604 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.mm
@@ -35,13 +35,14 @@ NSString* title) { base::string16 c_title = base::SysNSStringToUTF16(title); GURL url(base::SysNSStringToUTF16(@"http://example.com/bookmark") + c_title); - return _bookmarkModel->AddURL(parent, parent->child_count(), c_title, url); + return _bookmarkModel->AddURL(parent, parent->children().size(), c_title, + url); } const BookmarkNode* BookmarkIOSUnitTest::AddFolder(const BookmarkNode* parent, NSString* title) { base::string16 c_title = base::SysNSStringToUTF16(title); - return _bookmarkModel->AddFolder(parent, parent->child_count(), c_title); + return _bookmarkModel->AddFolder(parent, parent->children().size(), c_title); } void BookmarkIOSUnitTest::ChangeTitle(NSString* title,
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_mediator.mm b/ios/chrome/browser/ui/bookmarks/bookmark_mediator.mm index 903f4e1..17c5307 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_mediator.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_mediator.mm
@@ -92,7 +92,7 @@ [[self class] folderForNewBookmarksInBrowserState:self.browserState]; BookmarkModel* bookmarkModel = ios::BookmarkModelFactory::GetForBrowserState(self.browserState); - bookmarkModel->AddURL(defaultFolder, defaultFolder->child_count(), + bookmarkModel->AddURL(defaultFolder, defaultFolder->children().size(), base::SysNSStringToUTF16(title), URL); MDCSnackbarMessageAction* action = [[MDCSnackbarMessageAction alloc] init];
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm index 7b239ac..1f09198 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
@@ -224,8 +224,8 @@ if (!node) { // Create a new bookmark. bookmark_model->client()->RecordAction( base::UserMetricsAction("BookmarkAdded")); - node = - bookmark_model->AddURL(folder, folder->child_count(), titleString, url); + node = bookmark_model->AddURL(folder, folder->children().size(), + titleString, url); } else { // Update the information. bookmark_model->SetTitle(node, titleString); bookmark_model->SetURL(node, url); @@ -233,7 +233,7 @@ DCHECK(folder); DCHECK(!folder->HasAncestor(node)); if (node->parent() != folder) { - bookmark_model->Move(node, folder, folder->child_count()); + bookmark_model->Move(node, folder, folder->children().size()); } DCHECK(node->parent() == folder); } @@ -312,9 +312,8 @@ bookmarks::BookmarkModel* model, const BookmarkNode* node) { // Delete children in reverse order, so that the index remains valid. - for (int i = node->child_count() - 1; i >= 0; --i) { - DeleteBookmarks(bookmarks, model, node->GetChild(i)); - } + for (size_t i = node->children().size(); i > 0; --i) + DeleteBookmarks(bookmarks, model, node->children()[i - 1].get()); if (bookmarks.find(node) != bookmarks.end()) model->Remove(node); @@ -364,7 +363,7 @@ if (folder->HasAncestor(node)) continue; if (node->parent() != folder) { - model->Move(node, folder, folder->child_count()); + model->Move(node, folder, folder->children().size()); didPerformMove = true; } } @@ -541,12 +540,9 @@ NodeVector* results, const NodeSet& obstructions) { std::vector<const BookmarkNode*> directDescendants; - for (int i = 0; i < folder->child_count(); ++i) { - const BookmarkNode* subfolder = folder->GetChild(i); - if (IsObstructed(subfolder, obstructions)) - continue; - - directDescendants.push_back(subfolder); + for (const auto& subfolder : folder->children()) { + if (!IsObstructed(subfolder.get(), obstructions)) + directDescendants.push_back(subfolder.get()); } bookmark_utils_ios::SortFolders(&directDescendants);
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm index f9082f13..38f1aedce 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm
@@ -104,13 +104,13 @@ bookmark_utils_ios::DeleteBookmarks(toDelete, _bookmarkModel); - EXPECT_EQ(mobileNode->child_count(), 2); + EXPECT_EQ(2u, mobileNode->children().size()); const BookmarkNode* child0 = mobileNode->GetChild(0); EXPECT_EQ(child0, f1); - EXPECT_EQ(child0->child_count(), 3); + EXPECT_EQ(3u, child0->children().size()); const BookmarkNode* child1 = mobileNode->GetChild(1); EXPECT_EQ(child1, b); - EXPECT_EQ(child1->child_count(), 0); + EXPECT_EQ(0u, child1->children().size()); } TEST_F(BookmarkIOSUtilsUnitTest, MoveNodes) { @@ -133,13 +133,13 @@ bookmark_utils_ios::MoveBookmarks(toMove, _bookmarkModel, f1); - EXPECT_EQ(mobileNode->child_count(), 2); + EXPECT_EQ(2u, mobileNode->children().size()); const BookmarkNode* child0 = mobileNode->GetChild(0); EXPECT_EQ(child0, f1); - EXPECT_EQ(child0->child_count(), 6); + EXPECT_EQ(6u, child0->children().size()); const BookmarkNode* child1 = mobileNode->GetChild(1); EXPECT_EQ(child1, b); - EXPECT_EQ(child1->child_count(), 0); + EXPECT_EQ(0u, child1->children().size()); } TEST_F(BookmarkIOSUtilsUnitTest, TestDefaultMoveFolder) {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm index 6dc36ba0..e55abfd 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm
@@ -7,6 +7,7 @@ #import <XCTest/XCTest.h> #include <vector> +#include "base/format_macros.h" #include "base/ios/ios_util.h" #include "base/strings/sys_string_conversions.h" #import "base/test/ios/wait_util.h" @@ -1300,7 +1301,7 @@ } // Verifies that there is |count| children on the bookmark folder with |name|. -+ (void)assertChildCount:(int)count ofFolderWithName:(NSString*)name { ++ (void)assertChildCount:(size_t)count ofFolderWithName:(NSString*)name { base::string16 name16(base::SysNSStringToUTF16(name)); bookmarks::BookmarkModel* bookmarkModel = ios::BookmarkModelFactory::GetForBrowserState( @@ -1318,10 +1319,10 @@ } } GREYAssert(folder, @"No folder named %@", name); - GREYAssertEqual( - folder->child_count(), count, - @"Unexpected number of children in folder '%@': %d instead of %d", name, - folder->child_count(), count); + GREYAssertEqual(folder->children().size(), count, + @"Unexpected number of children in folder '%@': %" PRIuS + " instead of %" PRIuS, + name, folder->children().size(), count); } + (void)verifyContextMenuForSingleURL {
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_helper_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_helper_unittest.mm index 9b30233..f8198e1 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller_helper_unittest.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_helper_unittest.mm
@@ -88,7 +88,7 @@ const bookmarks::BookmarkNode* bookmarks = bookmark_model->bookmark_bar_node(); const bookmarks::BookmarkNode* node = - bookmark_model->AddURL(bookmarks, bookmarks->child_count(), + bookmark_model->AddURL(bookmarks, bookmarks->children().size(), base::UTF8ToUTF16(kWebUrl), GURL(kWebUrl)); EXPECT_TRUE([helper_ isWebStateBookmarked:web_state_.get()]);
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm b/ios/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm index aab848e..9b02fa5 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm +++ b/ios/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm
@@ -144,7 +144,7 @@ chrome_browser_state_.get()); GURL URL = GURL(kTestUrl); const BookmarkNode* defaultFolder = bookmark_model_->mobile_node(); - bookmark_model_->AddURL(defaultFolder, defaultFolder->child_count(), + bookmark_model_->AddURL(defaultFolder, defaultFolder->children().size(), base::SysNSStringToUTF16(@"Test bookmark 1"), URL); } @@ -198,7 +198,7 @@ chrome_browser_state_.get()); GURL URL = GURL(kTestUrl2); const BookmarkNode* defaultFolder = bookmark_model_->mobile_node(); - bookmark_model_->AddURL(defaultFolder, defaultFolder->child_count(), + bookmark_model_->AddURL(defaultFolder, defaultFolder->children().size(), base::SysNSStringToUTF16(@"Test bookmark 1"), URL); EXPECT_OCMOCK_VERIFY(consumer_); @@ -207,7 +207,7 @@ bookmark_model_ = ios::BookmarkModelFactory::GetForBrowserState( chrome_browser_state_.get()); URL = GURL(kTestUrl); - bookmark_model_->AddURL(defaultFolder, defaultFolder->child_count(), + bookmark_model_->AddURL(defaultFolder, defaultFolder->children().size(), base::SysNSStringToUTF16(@"Test bookmark 2"), URL); EXPECT_OCMOCK_VERIFY(consumer_); @@ -222,7 +222,7 @@ chrome_browser_state_.get()); GURL URL = GURL(kTestUrl2); const BookmarkNode* defaultFolder = bookmark_model_->mobile_node(); - bookmark_model_->AddURL(defaultFolder, defaultFolder->child_count(), + bookmark_model_->AddURL(defaultFolder, defaultFolder->children().size(), base::SysNSStringToUTF16(@"Test bookmark 1"), URL); web_state_->SetCurrentURL(GURL(kTestUrl)); mediator_.webStateList = web_state_list_.get();
diff --git a/media/formats/mp4/track_run_iterator.cc b/media/formats/mp4/track_run_iterator.cc index d24d0e3..3663cbe5 100644 --- a/media/formats/mp4/track_run_iterator.cc +++ b/media/formats/mp4/track_run_iterator.cc
@@ -119,7 +119,11 @@ } TrackRunIterator::TrackRunIterator(const Movie* moov, MediaLog* media_log) - : moov_(moov), media_log_(media_log), sample_offset_(0) { + : moov_(moov), + media_log_(media_log), + sample_dts_(0), + sample_cts_(0), + sample_offset_(0) { CHECK(moov); }
diff --git a/media/gpu/v4l2/v4l2_slice_video_decoder.cc b/media/gpu/v4l2/v4l2_slice_video_decoder.cc index be9b71d..9732fe57 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decoder.cc +++ b/media/gpu/v4l2/v4l2_slice_video_decoder.cc
@@ -134,6 +134,8 @@ device_poll_thread_("V4L2SliceVideoDecoderDevicePollThread"), state_(State::kUninitialized), weak_this_factory_(this) { + DETACH_FROM_SEQUENCE(client_sequence_checker_); + DETACH_FROM_SEQUENCE(decoder_sequence_checker_); VLOGF(2); weak_this_ = weak_this_factory_.GetWeakPtr(); @@ -142,31 +144,44 @@ } V4L2SliceVideoDecoder::~V4L2SliceVideoDecoder() { + // We might be called from either the client or the decoder sequence. + DETACH_FROM_SEQUENCE(client_sequence_checker_); + DETACH_FROM_SEQUENCE(decoder_sequence_checker_); VLOGF(2); } std::string V4L2SliceVideoDecoder::GetDisplayName() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); + return "V4L2SliceVideoDecoder"; } bool V4L2SliceVideoDecoder::IsPlatformDecoder() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); + return true; } int V4L2SliceVideoDecoder::GetMaxDecodeRequests() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); + return 4; } bool V4L2SliceVideoDecoder::NeedsBitstreamConversion() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); + return needs_bitstream_conversion_; } bool V4L2SliceVideoDecoder::CanReadWithoutStalling() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); + return frame_pool_ && !frame_pool_->IsExhausted(); } void V4L2SliceVideoDecoder::Destroy() { - DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); VLOGF(2); decoder_task_runner_->PostTask( @@ -175,7 +190,7 @@ } void V4L2SliceVideoDecoder::DestroyTask() { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(2); if (avd_) { @@ -203,7 +218,7 @@ InitCB init_cb, const OutputCB& output_cb, const WaitingCB& /* waiting_cb */) { - DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); VLOGF(2) << "config: " << config.AsHumanReadableString(); if (!config.IsValidConfig()) { @@ -226,7 +241,7 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config, InitCB init_cb, const OutputCB& output_cb) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK(state_ == State::kUninitialized || state_ == State::kDecoding); DVLOGF(3); @@ -365,7 +380,7 @@ } bool V4L2SliceVideoDecoder::SetupInputFormat(uint32_t input_format_fourcc) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_EQ(state_, State::kUninitialized); // Check if the format is supported. @@ -402,7 +417,7 @@ } uint32_t V4L2SliceVideoDecoder::NegotiateOutputFormat() { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); const std::vector<uint32_t> formats = device_->EnumerateSupportedPixelformats( V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); @@ -420,7 +435,7 @@ } bool V4L2SliceVideoDecoder::SetupOutputFormat(uint32_t output_format_fourcc) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3) << "output_format_fourcc = " << output_format_fourcc; // Only set fourcc for output; resolution, etc., will come from the @@ -440,7 +455,7 @@ } void V4L2SliceVideoDecoder::Reset(base::OnceClosure closure) { - DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); DVLOGF(3); decoder_task_runner_->PostTask( @@ -449,7 +464,7 @@ } void V4L2SliceVideoDecoder::ResetTask(base::OnceClosure closure) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3); if (avd_) @@ -474,7 +489,7 @@ } void V4L2SliceVideoDecoder::ClearPendingRequests(DecodeStatus status) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3); // Clear output_request_queue_. @@ -499,7 +514,7 @@ void V4L2SliceVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) { - DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); decoder_task_runner_->PostTask( FROM_HERE, @@ -509,7 +524,7 @@ } void V4L2SliceVideoDecoder::EnqueueDecodeTask(DecodeRequest request) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK(state_ == State::kDecoding || state_ == State::kPause); decode_request_queue_.push(std::move(request)); @@ -517,7 +532,7 @@ } void V4L2SliceVideoDecoder::PumpDecodeTask() { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK(state_ == State::kDecoding || state_ == State::kPause); DVLOGF(3) << "state_:" << static_cast<int>(state_) << " Number of Decode requests: " << decode_request_queue_.size(); @@ -598,7 +613,7 @@ } void V4L2SliceVideoDecoder::PumpOutputSurfaces() { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3) << "state_: " << static_cast<int>(state_) << " Number of display surfaces: " << output_request_queue_.size(); @@ -646,7 +661,7 @@ } bool V4L2SliceVideoDecoder::ChangeResolution() { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_EQ(state_, State::kPause); // We change resolution after outputting all pending surfaces, there should // be no V4L2DecodeSurface left. @@ -711,7 +726,7 @@ } scoped_refptr<V4L2DecodeSurface> V4L2SliceVideoDecoder::CreateSurface() { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(4); // Request VideoFrame. @@ -744,7 +759,7 @@ } void V4L2SliceVideoDecoder::ReuseOutputBuffer(V4L2ReadableBufferRef buffer) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3) << "Reuse output surface #" << buffer->BufferId(); // Resume decoding in case of ran out of surface. @@ -759,7 +774,7 @@ const scoped_refptr<V4L2DecodeSurface>& dec_surface, const uint8_t* data, size_t size) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3); size_t plane_size = dec_surface->input_buffer().GetPlaneSize(0); @@ -780,7 +795,7 @@ void V4L2SliceVideoDecoder::DecodeSurface( const scoped_refptr<V4L2DecodeSurface>& dec_surface) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3); // Enqueue input_buf and output_buf @@ -817,7 +832,7 @@ int32_t bitstream_id, const gfx::Rect& visible_rect, const VideoColorSpace& /* color_space */) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3); // TODO(akahuang): Update visible_rect at the output frame. @@ -828,7 +843,7 @@ } bool V4L2SliceVideoDecoder::StartStreamV4L2Queue() { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3); if (!device_poll_thread_.IsRunning()) { @@ -850,7 +865,7 @@ } bool V4L2SliceVideoDecoder::StopStreamV4L2Queue() { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_NE(state_, State::kUninitialized); DVLOGF(3); @@ -887,7 +902,7 @@ // Poke when we want to dequeue buffer from V4L2 device void V4L2SliceVideoDecoder::SchedulePollTaskIfNeeded() { DVLOGF(3); - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK(input_queue_->IsStreaming() && output_queue_->IsStreaming()); if (!device_poll_thread_.IsRunning()) { @@ -924,7 +939,7 @@ } void V4L2SliceVideoDecoder::ServiceDeviceTask() { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3) << "Number of queued input buffers: " << input_queue_->QueuedBuffersCount() << ", Number of queued output buffers: " @@ -979,21 +994,21 @@ } int32_t V4L2SliceVideoDecoder::GetNextBitstreamId() { - DCHECK(client_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x7FFFFFFF; return next_bitstream_buffer_id_; } void V4L2SliceVideoDecoder::RunDecodeCB(DecodeCB cb, DecodeStatus status) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); client_task_runner_->PostTask(FROM_HERE, base::BindOnce(std::move(cb), status)); } void V4L2SliceVideoDecoder::RunOutputCB(scoped_refptr<VideoFrame> frame) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); frame->metadata()->SetBoolean(VideoFrameMetadata::POWER_EFFICIENT, true); scoped_refptr<VideoFrame> converted_frame = @@ -1012,7 +1027,7 @@ } void V4L2SliceVideoDecoder::SetState(State new_state) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); + DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3) << "Change state from " << static_cast<int>(state_) << " to " << static_cast<int>(new_state);
diff --git a/media/gpu/v4l2/v4l2_slice_video_decoder.h b/media/gpu/v4l2/v4l2_slice_video_decoder.h index 5b2f5e9..b7d91b31 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decoder.h +++ b/media/gpu/v4l2/v4l2_slice_video_decoder.h
@@ -15,6 +15,7 @@ #include "base/containers/queue.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" #include "base/sequenced_task_runner.h" #include "base/threading/thread.h" #include "media/base/video_decoder.h" @@ -234,6 +235,9 @@ // |decoder_task_runner_|. base::WeakPtr<V4L2SliceVideoDecoder> weak_this_; base::WeakPtrFactory<V4L2SliceVideoDecoder> weak_this_factory_; + + SEQUENCE_CHECKER(client_sequence_checker_); + SEQUENCE_CHECKER(decoder_sequence_checker_); }; } // namespace media
diff --git a/media/video/gpu_video_accelerator_factories.h b/media/video/gpu_video_accelerator_factories.h index 2f3da2c..ead732da 100644 --- a/media/video/gpu_video_accelerator_factories.h +++ b/media/video/gpu_video_accelerator_factories.h
@@ -35,7 +35,6 @@ } namespace gpu { -class ContextSupport; class GpuMemoryBufferManager; class SharedImageInterface; struct SyncToken; @@ -99,17 +98,6 @@ virtual std::unique_ptr<VideoEncodeAccelerator> CreateVideoEncodeAccelerator() = 0; - // Allocate & delete native textures. - virtual bool CreateTextures(int32_t count, - const gfx::Size& size, - std::vector<uint32_t>* texture_ids, - std::vector<gpu::Mailbox>* texture_mailboxes, - uint32_t texture_target) = 0; - virtual void DeleteTexture(uint32_t texture_id) = 0; - virtual gpu::SyncToken CreateSyncToken() = 0; - virtual void ShallowFlushCHROMIUM() = 0; - - virtual void WaitSyncToken(const gpu::SyncToken& sync_token) = 0; virtual void SignalSyncToken(const gpu::SyncToken& sync_token, base::OnceClosure callback) = 0; @@ -130,12 +118,6 @@ virtual OutputFormat VideoFrameOutputFormat( VideoPixelFormat pixel_format) = 0; - // Returns a GL Context that can be used on the task runner associated with - // the same instance of GpuVideoAcceleratorFactories. - // nullptr will be returned in cases where a context couldn't be created or - // the context was lost. - virtual gpu::gles2::GLES2Interface* ContextGL() = 0; - // Returns a SharedImageInterface that can be used (on any thread) to allocate // and update shared images. // nullptr will be returned in cases where a context couldn't be created or @@ -160,7 +142,6 @@ virtual scoped_refptr<viz::ContextProviderCommandBuffer> GetMediaContextProvider() = 0; - virtual gpu::ContextSupport* GetMediaContextProviderContextSupport() = 0; // Sets the current pipeline rendering color space. virtual void SetRenderingColorSpace(const gfx::ColorSpace& color_space) = 0;
diff --git a/media/video/mock_gpu_video_accelerator_factories.h b/media/video/mock_gpu_video_accelerator_factories.h index bd44869b..85176ed 100644 --- a/media/video/mock_gpu_video_accelerator_factories.h +++ b/media/video/mock_gpu_video_accelerator_factories.h
@@ -47,25 +47,14 @@ // framework does not want. Trampoline it. MOCK_METHOD0(DoCreateVideoEncodeAccelerator, VideoEncodeAccelerator*()); - MOCK_METHOD5(CreateTextures, - bool(int32_t count, - const gfx::Size& size, - std::vector<uint32_t>* texture_ids, - std::vector<gpu::Mailbox>* texture_mailboxes, - uint32_t texture_target)); - MOCK_METHOD1(DeleteTexture, void(uint32_t texture_id)); - MOCK_METHOD0(CreateSyncToken, gpu::SyncToken()); - MOCK_METHOD1(WaitSyncToken, void(const gpu::SyncToken& sync_token)); MOCK_METHOD2(SignalSyncToken, void(const gpu::SyncToken& sync_token, base::OnceClosure callback)); - MOCK_METHOD0(ShallowFlushCHROMIUM, void()); MOCK_METHOD0(GetTaskRunner, scoped_refptr<base::SingleThreadTaskRunner>()); MOCK_METHOD0(GetVideoEncodeAcceleratorSupportedProfiles, VideoEncodeAccelerator::SupportedProfiles()); MOCK_METHOD0(GetMediaContextProvider, scoped_refptr<viz::ContextProviderCommandBuffer>()); - MOCK_METHOD0(GetMediaContextProviderContextSupport, gpu::ContextSupport*()); MOCK_METHOD1(SetRenderingColorSpace, void(const gfx::ColorSpace&)); std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer( @@ -80,7 +69,6 @@ return video_frame_output_format_; } - gpu::gles2::GLES2Interface* ContextGL() override { return nullptr; } gpu::SharedImageInterface* SharedImageInterface() override { return sii_; } gpu::GpuMemoryBufferManager* GpuMemoryBufferManager() override { return nullptr;
diff --git a/mojo/public/cpp/bindings/struct_ptr.h b/mojo/public/cpp/bindings/struct_ptr.h index 4dcddd15..50533e9 100644 --- a/mojo/public/cpp/bindings/struct_ptr.h +++ b/mojo/public/cpp/bindings/struct_ptr.h
@@ -99,10 +99,6 @@ explicit operator bool() const { return !is_null(); } - bool operator<(const StructPtr& other) const { - return Hash(internal::kHashSeed) < other.Hash(internal::kHashSeed); - } - private: friend class internal::StructPtrWTFHelper<Struct>; void Take(StructPtr* other) { @@ -115,32 +111,23 @@ DISALLOW_COPY_AND_ASSIGN(StructPtr); }; -template <typename T> -bool operator==(const StructPtr<T>& lhs, const StructPtr<T>& rhs) { - return lhs.Equals(rhs); -} -template <typename T> -bool operator!=(const StructPtr<T>& lhs, const StructPtr<T>& rhs) { - return !(lhs == rhs); -} - // Designed to be used when Struct is small and copyable. template <typename S> class InlinedStructPtr { public: using Struct = S; - InlinedStructPtr() : state_(NIL) {} - InlinedStructPtr(std::nullptr_t) : state_(NIL) {} + InlinedStructPtr() = default; + InlinedStructPtr(std::nullptr_t) {} - ~InlinedStructPtr() {} + ~InlinedStructPtr() = default; InlinedStructPtr& operator=(std::nullptr_t) { reset(); return *this; } - InlinedStructPtr(InlinedStructPtr&& other) : state_(NIL) { Take(&other); } + InlinedStructPtr(InlinedStructPtr&& other) { Take(&other); } InlinedStructPtr& operator=(InlinedStructPtr&& other) { Take(&other); return *this; @@ -198,10 +185,6 @@ explicit operator bool() const { return !is_null(); } - bool operator<(const InlinedStructPtr& other) const { - return Hash(internal::kHashSeed) < other.Hash(internal::kHashSeed); - } - private: friend class internal::InlinedStructPtrWTFHelper<Struct>; void Take(InlinedStructPtr* other) { @@ -210,28 +193,17 @@ } enum State { - VALID, NIL, + VALID, DELETED, // For use in WTF::HashMap only }; mutable Struct value_; - State state_; + State state_ = NIL; DISALLOW_COPY_AND_ASSIGN(InlinedStructPtr); }; -template <typename T> -bool operator==(const InlinedStructPtr<T>& lhs, - const InlinedStructPtr<T>& rhs) { - return lhs.Equals(rhs); -} -template <typename T> -bool operator!=(const InlinedStructPtr<T>& lhs, - const InlinedStructPtr<T>& rhs) { - return !(lhs == rhs); -} - namespace internal { template <typename Struct> @@ -269,7 +241,56 @@ } }; +// Convenience type trait so that we can get away with defining the comparison +// operators only once. +template <typename T> +struct IsStructPtrImpl : std::false_type {}; + +template <typename S> +struct IsStructPtrImpl<StructPtr<S>> : std::true_type {}; + +template <typename S> +struct IsStructPtrImpl<InlinedStructPtr<S>> : std::true_type {}; + } // namespace internal + +template <typename T> +constexpr bool IsStructPtrV = internal::IsStructPtrImpl<std::decay_t<T>>::value; + +template <typename Ptr, std::enable_if_t<IsStructPtrV<Ptr>>* = nullptr> +bool operator==(const Ptr& lhs, const Ptr& rhs) { + return lhs.Equals(rhs); +} + +template <typename Ptr, std::enable_if_t<IsStructPtrV<Ptr>>* = nullptr> +bool operator!=(const Ptr& lhs, const Ptr& rhs) { + return !(lhs == rhs); +} + +// Perform a deep comparison if possible. Otherwise treat null pointers less +// than valid pointers. +template <typename Ptr, std::enable_if_t<IsStructPtrV<Ptr>>* = nullptr> +bool operator<(const Ptr& lhs, const Ptr& rhs) { + if (!lhs || !rhs) + return bool{lhs} < bool{rhs}; + return *lhs < *rhs; +} + +template <typename Ptr, std::enable_if_t<IsStructPtrV<Ptr>>* = nullptr> +bool operator<=(const Ptr& lhs, const Ptr& rhs) { + return !(rhs < lhs); +} + +template <typename Ptr, std::enable_if_t<IsStructPtrV<Ptr>>* = nullptr> +bool operator>(const Ptr& lhs, const Ptr& rhs) { + return rhs < lhs; +} + +template <typename Ptr, std::enable_if_t<IsStructPtrV<Ptr>>* = nullptr> +bool operator>=(const Ptr& lhs, const Ptr& rhs) { + return !(lhs < rhs); +} + } // namespace mojo namespace std {
diff --git a/mojo/public/cpp/bindings/tests/rect_chromium.h b/mojo/public/cpp/bindings/tests/rect_chromium.h index 4092668..e83d5626 100644 --- a/mojo/public/cpp/bindings/tests/rect_chromium.h +++ b/mojo/public/cpp/bindings/tests/rect_chromium.h
@@ -57,12 +57,17 @@ int GetArea() const { return width_ * height_; } + auto TieForCmp() const { return std::tie(x_, y_, width_, height_); } + bool operator==(const RectChromium& other) const { - return (x() == other.x() && y() == other.y() && width() == other.width() && - height() == other.height()); + return TieForCmp() == other.TieForCmp(); } bool operator!=(const RectChromium& other) const { return !(*this == other); } + bool operator<(const RectChromium& other) const { + return TieForCmp() < other.TieForCmp(); + } + private: int x_ = 0; int y_ = 0;
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl index 801c015..0679323 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
@@ -3,6 +3,8 @@ {{ kythe_annotation(struct_prefix) }} class {{export_attribute}} {{struct.name}} { public: + template <typename T> + using EnableIfSame = std::enable_if_t<std::is_same<{{struct.name}}, T>::value>; using DataView = {{struct.name}}DataView; using Data_ = internal::{{struct.name}}_Data; @@ -54,9 +56,7 @@ // Equals() is a template so it is only instantiated if it is used. Thus, the // bindings generator does not need to know whether Equals() or == operator // are available for members. - template <typename T, - typename std::enable_if<std::is_same< - T, {{struct.name}}>::value>::type* = nullptr> + template <typename T, {{struct.name}}::EnableIfSame<T>* = nullptr> bool Equals(const T& other) const; {%- if struct|is_hashable %} @@ -136,3 +136,24 @@ DISALLOW_COPY_AND_ASSIGN({{struct.name}}); {%- endif %} }; + +// The comparison operators are templates, so they are only instantiated if they +// are used. Thus, the bindings generator does not need to know whether +// comparison operators are available for members. +template <typename T, {{struct.name}}::EnableIfSame<T>* = nullptr> +bool operator<(const T& lhs, const T& rhs); + +template <typename T, {{struct.name}}::EnableIfSame<T>* = nullptr> +bool operator<=(const T& lhs, const T& rhs) { + return !(rhs < lhs); +} + +template <typename T, {{struct.name}}::EnableIfSame<T>* = nullptr> +bool operator>(const T& lhs, const T& rhs) { + return rhs < lhs; +} + +template <typename T, {{struct.name}}::EnableIfSame<T>* = nullptr> +bool operator>=(const T& lhs, const T& rhs) { + return !(lhs < rhs); +}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_template_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_template_definition.tmpl index fab27cd8..32bf674 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_template_definition.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_template_definition.tmpl
@@ -8,9 +8,7 @@ ); } -template <typename T, - typename std::enable_if<std::is_same< - T, {{struct.name}}>::value>::type*> +template <typename T, {{struct.name}}::EnableIfSame<T>*> bool {{struct.name}}::Equals(const T& other_struct) const { {%- for field in struct.fields %} if (!mojo::Equals(this->{{field.name}}, other_struct.{{field.name}})) @@ -18,3 +16,14 @@ {%- endfor %} return true; } + +template <typename T, {{struct.name}}::EnableIfSame<T>*> +bool operator<(const T& lhs, const T& rhs) { +{%- for field in struct.fields %} + if (lhs.{{field.name}} < rhs.{{field.name}}) + return true; + if (rhs.{{field.name}} < lhs.{{field.name}}) + return false; +{%- endfor %} + return false; +}
diff --git a/net/log/net_log_capture_mode.cc b/net/log/net_log_capture_mode.cc index a2ff3c1..9b00247e 100644 --- a/net/log/net_log_capture_mode.cc +++ b/net/log/net_log_capture_mode.cc
@@ -4,11 +4,6 @@ #include "net/log/net_log_capture_mode.h" -#include <algorithm> - -#include "base/command_line.h" -#include "base/strings/string_piece.h" - namespace net { namespace { @@ -67,23 +62,4 @@ NetLogCaptureMode::NetLogCaptureMode(uint32_t value) : value_(value) { } -NetLogCaptureMode GetNetCaptureModeFromCommandLine( - const base::CommandLine& command_line, - base::StringPiece switch_name) { - if (command_line.HasSwitch(switch_name)) { - std::string value = command_line.GetSwitchValueASCII(switch_name); - - if (value == "Default") - return NetLogCaptureMode::Default(); - if (value == "IncludeCookiesAndCredentials") - return NetLogCaptureMode::IncludeCookiesAndCredentials(); - if (value == "IncludeSocketBytes") - return NetLogCaptureMode::IncludeSocketBytes(); - - LOG(ERROR) << "Unrecognized value for --" << switch_name; - } - - return net::NetLogCaptureMode::Default(); -} - } // namespace net
diff --git a/net/log/net_log_capture_mode.h b/net/log/net_log_capture_mode.h index 470a00c..b688c57e 100644 --- a/net/log/net_log_capture_mode.h +++ b/net/log/net_log_capture_mode.h
@@ -7,15 +7,8 @@ #include <stdint.h> -#include <string> - -#include "base/strings/string_piece_forward.h" #include "net/base/net_export.h" -namespace base { -class CommandLine; -} - namespace net { // NetLogCaptureMode specifies the granularity of events that should be emitted @@ -64,11 +57,6 @@ int32_t value_; }; -// Parses a NetLogCaptureMode given an optional command-line switch. -NET_EXPORT NetLogCaptureMode -GetNetCaptureModeFromCommandLine(const base::CommandLine& command_line, - base::StringPiece switch_name); - } // namespace net #endif // NET_LOG_NET_LOG_CAPTURE_MODE_H_
diff --git a/services/device/public/mojom/serial.mojom b/services/device/public/mojom/serial.mojom index 5cbfba9..cf1444a 100644 --- a/services/device/public/mojom/serial.mojom +++ b/services/device/public/mojom/serial.mojom
@@ -20,15 +20,12 @@ enum SerialSendError { NONE, DISCONNECTED, - PENDING, - TIMEOUT, SYSTEM_ERROR, }; enum SerialReceiveError { NONE, DISCONNECTED, - TIMEOUT, DEVICE_LOST, BREAK, FRAME_ERROR,
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 86f9a2a9..f0a4f13 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -41,6 +41,7 @@ #include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/base/network_delegate.h" +#include "net/base/network_isolation_key.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/cert/cert_verifier.h" #include "net/cert/ct_verify_result.h" @@ -1559,10 +1560,12 @@ request, net::NetLogWithSource()); } -void NetworkContext::PreconnectSockets(uint32_t num_streams, - const GURL& original_url, - int32_t load_flags, - bool privacy_mode_enabled) { +void NetworkContext::PreconnectSockets( + uint32_t num_streams, + const GURL& original_url, + int32_t load_flags, + bool privacy_mode_enabled, + const base::Optional<net::NetworkIsolationKey>& network_isolation_key) { GURL url = GetHSTSRedirect(original_url); // |PreconnectSockets| may receive arguments from the renderer, which is not @@ -1581,9 +1584,11 @@ request_info.extra_headers.SetHeader(net::HttpRequestHeaders::kUserAgent, user_agent); + request_info.load_flags = load_flags; request_info.privacy_mode = privacy_mode_enabled ? net::PRIVACY_MODE_ENABLED : net::PRIVACY_MODE_DISABLED; - request_info.load_flags = load_flags; + if (network_isolation_key) + request_info.network_isolation_key = *network_isolation_key; net::HttpTransactionFactory* factory = url_request_context_->http_transaction_factory();
diff --git a/services/network/network_context.h b/services/network/network_context.h index 1b0d3a1..225c3e5e 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -321,7 +321,9 @@ void PreconnectSockets(uint32_t num_streams, const GURL& url, int32_t load_flags, - bool privacy_mode_enabled) override; + bool privacy_mode_enabled, + const base::Optional<net::NetworkIsolationKey>& + network_isolation_key) override; void CreateP2PSocketManager( mojom::P2PTrustedSocketManagerClientPtr client, mojom::P2PTrustedSocketManagerRequest trusted_socket_manager,
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index 82a84cc..efc26e5 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -53,6 +53,7 @@ #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" #include "net/base/network_change_notifier.h" +#include "net/base/network_isolation_key.h" #include "net/base/proxy_server.h" #include "net/base/test_completion_callback.h" #include "net/cert/cert_verify_result.h" @@ -79,6 +80,7 @@ #include "net/proxy_resolution/proxy_config.h" #include "net/proxy_resolution/proxy_info.h" #include "net/proxy_resolution/proxy_resolution_service.h" +#include "net/socket/client_socket_pool.h" #include "net/socket/transport_client_socket_pool.h" #include "net/test/cert_test_util.h" #include "net/test/embedded_test_server/controllable_http_response.h" @@ -3484,8 +3486,9 @@ test_server.SetConnectionListener(&connection_listener); ASSERT_TRUE(test_server.Start()); - network_context->PreconnectSockets(1, test_server.base_url(), - net::LOAD_NORMAL, true); + network_context->PreconnectSockets( + 1, test_server.base_url(), net::LOAD_NORMAL, + true /* privacy_mode_enabled */, net::NetworkIsolationKey()); connection_listener.WaitForAcceptedConnections(1u); } @@ -3500,7 +3503,8 @@ const GURL server_http_url = GetHttpUrlFromHttps(test_server.base_url()); network_context->PreconnectSockets(1, server_http_url, net::LOAD_NORMAL, - true); + true /* privacy_mode_enabled */, + net::NetworkIsolationKey()); connection_listener.WaitForAcceptedConnections(1u); int num_sockets = GetSocketCountForGroup( @@ -3513,7 +3517,8 @@ network_context->url_request_context()->transport_security_state()->AddHSTS( server_http_url.host(), expiry, false); network_context->PreconnectSockets(1, server_http_url, net::LOAD_NORMAL, - true); + true /* privacy_mode_enabled */, + net::NetworkIsolationKey()); connection_listener.WaitForAcceptedConnections(1u); // If HSTS weren't respected, the initial connection would have been reused. @@ -3532,8 +3537,9 @@ test_server.SetConnectionListener(&connection_listener); ASSERT_TRUE(test_server.Start()); - network_context->PreconnectSockets(0, test_server.base_url(), - net::LOAD_NORMAL, true); + network_context->PreconnectSockets( + 0, test_server.base_url(), net::LOAD_NORMAL, + true /* privacy_mode_enabled */, net::NetworkIsolationKey()); base::RunLoop().RunUntilIdle(); int num_sockets = @@ -3553,8 +3559,9 @@ test_server.SetConnectionListener(&connection_listener); ASSERT_TRUE(test_server.Start()); - network_context->PreconnectSockets(2, test_server.base_url(), - net::LOAD_NORMAL, true); + network_context->PreconnectSockets( + 2, test_server.base_url(), net::LOAD_NORMAL, + true /* privacy_mode_enabled */, net::NetworkIsolationKey()); connection_listener.WaitForAcceptedConnections(2u); int num_sockets = @@ -3571,8 +3578,9 @@ test_server.SetConnectionListener(&connection_listener); ASSERT_TRUE(test_server.Start()); - network_context->PreconnectSockets(4, test_server.base_url(), - net::LOAD_NORMAL, true); + network_context->PreconnectSockets( + 4, test_server.base_url(), net::LOAD_NORMAL, + true /* privacy_mode_enabled */, net::NetworkIsolationKey()); connection_listener.WaitForAcceptedConnections(4u); @@ -3594,8 +3602,9 @@ GetSocketPoolInfo(network_context.get(), "max_sockets_per_group"); EXPECT_GT(76, max_num_sockets); - network_context->PreconnectSockets(76, test_server.base_url(), - net::LOAD_NORMAL, true); + network_context->PreconnectSockets( + 76, test_server.base_url(), net::LOAD_NORMAL, + true /* privacy_mode_enabled */, net::NetworkIsolationKey()); // Wait until |max_num_sockets| have been connected. connection_listener.WaitForAcceptedConnections(max_num_sockets); @@ -3610,6 +3619,45 @@ ASSERT_EQ(num_sockets, max_num_sockets); } +// Make sure preconnects for the same URL but with different network isolation +// keys are not merged. +TEST_F(NetworkContextTest, PreconnectNetworkIsolationKey) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + net::features::kPartitionConnectionsByNetworkIsolationKey); + + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateContextParams()); + + ConnectionListener connection_listener; + net::EmbeddedTestServer test_server; + test_server.SetConnectionListener(&connection_listener); + ASSERT_TRUE(test_server.Start()); + + const net::NetworkIsolationKey kKey1( + url::Origin::Create(GURL("http://foo.test"))); + const net::NetworkIsolationKey kKey2( + url::Origin::Create(GURL("http://bar.test"))); + network_context->PreconnectSockets(1, test_server.base_url(), + net::LOAD_NORMAL, + true /* privacy_mode_enabled */, kKey1); + network_context->PreconnectSockets(2, test_server.base_url(), + net::LOAD_NORMAL, + true /* privacy_mode_enabled */, kKey2); + connection_listener.WaitForAcceptedConnections(3u); + + net::ClientSocketPool::GroupId group_id1( + test_server.host_port_pair(), net::ClientSocketPool::SocketType::kHttp, + net::PrivacyMode::PRIVACY_MODE_ENABLED, kKey1); + EXPECT_EQ( + 1, GetSocketCountForGroup(network_context.get(), group_id1.ToString())); + net::ClientSocketPool::GroupId group_id2( + test_server.host_port_pair(), net::ClientSocketPool::SocketType::kHttp, + net::PrivacyMode::PRIVACY_MODE_ENABLED, kKey2); + EXPECT_EQ( + 2, GetSocketCountForGroup(network_context.get(), group_id2.ToString())); +} + // This tests both ClostAllConnetions and CloseIdleConnections. TEST_F(NetworkContextTest, CloseConnections) { // Have to close all connections first, as CloseIdleConnections leaves around
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 91481f5..b09c5d2e 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -856,10 +856,14 @@ // |privacy_mode_enabled| is also passed into the HttpRequestInfo class: if // it is true, then the request must be sent over a connection that cannot be // tracked by the server. + // |network_isolation_key| specifies the NetworkIsolationKey to associate + // with the preconnected sockets. The sockets will only be used for requests + // associated with the same key. PreconnectSockets(uint32 num_streams, url.mojom.Url url, int32 load_flags, - bool privacy_mode_enabled); + bool privacy_mode_enabled, + NetworkIsolationKey? network_isolation_key); // Creates a P2PSocketManager instance, used for WebRTC. CreateP2PSocketManager(P2PTrustedSocketManagerClient client,
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h index 4aa4146..30aa49d 100644 --- a/services/network/test/test_network_context.h +++ b/services/network/test/test_network_context.h
@@ -27,6 +27,10 @@ #include "services/network/public/mojom/websocket.mojom.h" #include "url/origin.h" +namespace net { +class NetworkIsolationKey; +} + namespace network { // Noop implementation of mojom::NetworkContext. Useful to override to create @@ -186,7 +190,9 @@ void PreconnectSockets(uint32_t num_streams, const GURL& url, int32_t load_flags, - bool privacy_mode_enabled) override {} + bool privacy_mode_enabled, + const base::Optional<net::NetworkIsolationKey>& + network_isolation_key) override {} void CreateP2PSocketManager( mojom::P2PTrustedSocketManagerClientPtr client, mojom::P2PTrustedSocketManagerRequest trusted_socket_manager,
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 94e5ef2..285fea3 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -14828,7 +14828,8 @@ { "args": [ "--gs-results-bucket=chromium-result-details", - "--recover-devices" + "--recover-devices", + "--test-launcher-filter-file=../../testing/buildbot/filters/android.asan.content_browsertests.filter" ], "merge": { "args": [ @@ -15896,50 +15897,6 @@ "--bucket", "chromium-result-details", "--test-name", - "perfetto_unittests" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "device_os": "MMB29Q", - "device_os_type": "userdebug", - "device_type": "bullhead", - "os": "Android" - } - ], - "output_links": [ - { - "link": [ - "https://luci-logdog.appspot.com/v/?s", - "=android%2Fswarming%2Flogcats%2F", - "${TASK_ID}%2F%2B%2Funified_logcats" - ], - "name": "shard #${SHARD_INDEX} logcats" - } - ] - }, - "test": "perfetto_unittests" - }, - { - "args": [ - "--gs-results-bucket=chromium-result-details", - "--recover-devices" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", "services_unittests" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" @@ -16285,7 +16242,8 @@ { "args": [ "--gs-results-bucket=chromium-result-details", - "--recover-devices" + "--recover-devices", + "--test-launcher-filter-file=../../testing/buildbot/filters/android.asan.unit_tests.filter" ], "merge": { "args": [
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index e850e09..9efe198 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -55,6 +55,7 @@ testonly = true data = [ + "//testing/buildbot/filters/android.asan.content_browsertests.filter", "//testing/buildbot/filters/cast-linux.content_browsertests.filter", "//testing/buildbot/filters/site_isolation_android.content_browsertests.filter", "//testing/buildbot/filters/skia_renderer.content_browsertests.filter", @@ -89,6 +90,14 @@ ] } +source_set("unit_tests_filters") { + testonly = true + + data = [ + "//testing/buildbot/filters/android.asan.unit_tests.filter", + ] +} + source_set("webview_cts_tests_filters") { testonly = true
diff --git a/testing/buildbot/filters/android.asan.content_browsertests.filter b/testing/buildbot/filters/android.asan.content_browsertests.filter new file mode 100644 index 0000000..94e6c1f0 --- /dev/null +++ b/testing/buildbot/filters/android.asan.content_browsertests.filter
@@ -0,0 +1,6 @@ +-IndexedDBBrowserTest.NegativeDBDataVersion +-IndexedDBBrowserTest.NegativeDBSchemaVersion +-SitePerProcessBrowserTest.UnloadHandlerSubframes +-SitePerProcessBrowserTest.UnloadNestedPendingDeletion +-TouchpadPinchBrowserTest.WheelListenerPreventingDoubleTap/1 +-TouchpadPinchBrowserTest.WheelListenerPreventingPinch/1
diff --git a/testing/buildbot/filters/android.asan.unit_tests.filter b/testing/buildbot/filters/android.asan.unit_tests.filter new file mode 100644 index 0000000..faa11bc --- /dev/null +++ b/testing/buildbot/filters/android.asan.unit_tests.filter
@@ -0,0 +1,2 @@ +-DetachedResourceRequestTest.ResponseTooLarge +-DetachedResourceRequestTest.TooManyRedirects
diff --git a/testing/buildbot/filters/gpu.skiarenderer_vulkan_content_browsertests.filter b/testing/buildbot/filters/gpu.skiarenderer_vulkan_content_browsertests.filter index 685d28c8..b04beb0 100644 --- a/testing/buildbot/filters/gpu.skiarenderer_vulkan_content_browsertests.filter +++ b/testing/buildbot/filters/gpu.skiarenderer_vulkan_content_browsertests.filter
@@ -44,6 +44,7 @@ -SitePerProcessHitTestBrowserTest.CrossProcessMouseCapture/1 -SitePerProcessHitTestBrowserTest.CrossProcessMouseEnterAndLeaveTest/0 -SitePerProcessHitTestBrowserTest.CrossProcessMousePointerCapture/0 +-SitePerProcessHitTestBrowserTest.CrossProcessMousePointerCapture/1 -SitePerProcessHitTestBrowserTest.CrossProcessTooltipTestAndroid/0 -SitePerProcessHitTestBrowserTest.HitTestStaleDataDeletedView/0 -SitePerProcessHitTestBrowserTest.MouseCaptureOnDragSelection/0
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 71b247d0..42cdf980 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -398,11 +398,6 @@ ], 'modifications': { # chromium.android - 'android-asan': { - 'swarming': { - 'shards': 18, - }, - }, 'Lollipop Phone Tester': { 'swarming': { 'shards': 13, @@ -419,6 +414,15 @@ '--test-launcher-filter-file=../../testing/buildbot/filters/cast-linux.content_browsertests.filter', ], }, + # chromium.memory + 'android-asan': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/android.asan.content_browsertests.filter', + ], + 'swarming': { + 'shards': 18, + }, + }, # chromium.win 'Win10 Tests x64 (dbg)': { 'experiment_percentage': 100, @@ -1179,6 +1183,7 @@ }, 'perfetto_unittests': { 'remove_from': [ + 'android-asan', 'android-code-coverage', 'android-kitkat-arm-rel', 'android-marshmallow-arm64-rel', @@ -1440,6 +1445,11 @@ }, }, # chromium.memory + 'android-asan': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/android.asan.unit_tests.filter', + ], + }, 'Linux ASan LSan Tests (1)': { # These are slow on the ASAN trybot for some reason. # crbug.com/794372
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index 58b87a0..63d781f 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -53,6 +53,7 @@ "features.h", "fetch/fetch_api_request_headers_map.h", "fetch/fetch_api_request_headers_mojom_traits.h", + "frame/blocked_navigation_types.h", "frame/frame_owner_element_type.h", "frame/frame_policy.h", "frame/from_ad_state.h",
diff --git a/third_party/blink/public/common/frame/blocked_navigation_types.h b/third_party/blink/public/common/frame/blocked_navigation_types.h new file mode 100644 index 0000000..9dcace05 --- /dev/null +++ b/third_party/blink/public/common/frame/blocked_navigation_types.h
@@ -0,0 +1,21 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_BLOCKED_NAVIGATION_TYPES_H_ +#define THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_BLOCKED_NAVIGATION_TYPES_H_ + +namespace blink { + +// The reason the navigation was blocked. +enum class NavigationBlockedReason { + // Frame attempted to navigate the top window without user activation. + kRedirectWithNoUserGesture, + // Frame attempted to navigate the top window without user activation and is + // sandboxed. + kRedirectWithNoUserGestureSandbox, + kMaxValue = kRedirectWithNoUserGestureSandbox, +}; + +} // namespace blink +#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_BLOCKED_NAVIGATION_TYPES_H_
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index e793faf8..4cd7b3d 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2318,6 +2318,11 @@ kPageLifecycleTransitionsOptOut = 2929, kPeriodicBackgroundSync = 2930, kPeriodicBackgroundSyncRegister = 2931, + kLazyLoadFrameLoadingAttributeEager = 2932, + kLazyLoadFrameLoadingAttributeLazy = 2933, + kLazyLoadImageLoadingAttributeEager = 2934, + kLazyLoadImageLoadingAttributeLazy = 2935, + kLazyLoadImageMissingDimensionsForLazy = 2936, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h index 74e2ee0..3326706d 100644 --- a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h +++ b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h
@@ -153,10 +153,14 @@ // DidInitializeWorkerContext(), but it's not clear when the context would // already be initialized.) // + // |context_proxy| is valid until WillDestroyWorkerContext() is called. + // // This function is used to support service workers in Chrome extensions. // // TODO(nhiroki): Can you clarify this code and comment? - virtual void DidInitializeWorkerContext(v8::Local<v8::Context> context) {} + virtual void DidInitializeWorkerContext( + WebServiceWorkerContextProxy* context_proxy, + v8::Local<v8::Context> v8_context) {} // WorkerGlobalScope is about to be destroyed. The client should clear // the WebServiceWorkerGlobalScopeProxy when this is called.
diff --git a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h index e473c82..2000984 100644 --- a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h +++ b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h
@@ -67,6 +67,8 @@ int64_t encoded_data_length, int64_t encoded_body_length, int64_t decoded_body_length) = 0; + + virtual bool IsWindowInteractionAllowed() = 0; }; } // namespace blink
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index c60758e..8f2a815 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -35,6 +35,7 @@ #include "base/unguessable_token.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" #include "third_party/blink/public/common/frame/user_activation_update_type.h" @@ -497,9 +498,11 @@ return WebURLRequest::kPreviewsUnspecified; } - // This frame tried to navigate its top level frame to the given url without - // ever having received a user gesture. - virtual void DidBlockFramebust(const WebURL&) {} + // This frame tried to perform a navigation from |initiator_url| to + // |blocked_url| but was blocked because of |reason|. + virtual void DidBlockNavigation(const WebURL& blocked_url, + const WebURL& initiator_url, + blink::NavigationBlockedReason reason) {} // Tells the embedder to navigate back or forward in session history by // the given offset (relative to the current position in session
diff --git a/third_party/blink/renderer/core/css/resolver/element_style_resources.cc b/third_party/blink/renderer/core/css/resolver/element_style_resources.cc index 148480f..173a46c 100644 --- a/third_party/blink/renderer/core/css/resolver/element_style_resources.cc +++ b/third_party/blink/renderer/core/css/resolver/element_style_resources.cc
@@ -223,8 +223,7 @@ image_request_optimization); if (new_image && new_image->IsLazyloadPossiblyDeferred()) { LazyLoadImageObserver::StartMonitoring( - pseudo_element_ ? pseudo_element_ : element_.Get(), - false /* is_for_intervention */); + pseudo_element_ ? pseudo_element_ : element_.Get()); } background_layer->SetImage(new_image); }
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_budget.cc b/third_party/blink/renderer/core/display_lock/display_lock_budget.cc index e0843ec2..35a62be 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_budget.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_budget.cc
@@ -12,12 +12,12 @@ DisplayLockBudget::DisplayLockBudget(DisplayLockContext* context) : clock_(base::DefaultTickClock::GetInstance()), context_(context) {} -bool DisplayLockBudget::MarkAncestorsDirtyForPhaseIfNeeded(Phase phase) { +bool DisplayLockBudget::MarkDirtyForPhaseIfNeeded(Phase phase) { switch (phase) { case Phase::kStyle: return context_->MarkForStyleRecalcIfNeeded(); case Phase::kLayout: - return context_->MarkAncestorsForLayoutIfNeeded(); + return context_->MarkForLayoutIfNeeded(); case Phase::kPrePaint: return context_->MarkAncestorsForPrePaintIfNeeded(); } @@ -42,7 +42,7 @@ // Mark the next phase we're scheduled to run. for (auto phase = static_cast<unsigned>(marking_phase); phase <= static_cast<unsigned>(Phase::kLast); ++phase) { - if (MarkAncestorsDirtyForPhaseIfNeeded(static_cast<Phase>(phase))) + if (MarkDirtyForPhaseIfNeeded(static_cast<Phase>(phase))) break; } }
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_budget.h b/third_party/blink/renderer/core/display_lock/display_lock_budget.h index f39072b0..aeea5fa3 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_budget.h +++ b/third_party/blink/renderer/core/display_lock/display_lock_budget.h
@@ -55,9 +55,10 @@ void MarkPhaseAsDirty(Phase marking_phase); - // Marks the ancestor chain dirty for the given phase if it's needed. Returns - // true if the ancestors were marked dirty and false otherwise. - bool MarkAncestorsDirtyForPhaseIfNeeded(Phase); + // Marks the element and ancestor chain dirty for the given phase if it's + // needed. Returns true if the ancestors were marked dirty and false + // otherwise. + bool MarkDirtyForPhaseIfNeeded(Phase); const base::TickClock* clock_;
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_budget_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_budget_test.cc index 8749fb6b..435c210 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_budget_test.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_budget_test.cc
@@ -542,19 +542,15 @@ EXPECT_FALSE(parent->NeedsStyleRecalc() || parent->ChildNeedsStyleRecalc()); EXPECT_FALSE(element->NeedsStyleRecalc() || element->ChildNeedsStyleRecalc()); - EXPECT_FALSE(parent->GetLayoutObject()->NeedsLayout()); + EXPECT_TRUE(parent->GetLayoutObject()->NeedsLayout()); EXPECT_TRUE(element->GetLayoutObject()->NeedsLayout()); ResetDeadlineForTesting(*budget, GetDocument().View()->CurrentLifecycleData()); - budget->DidPerformPhase(DisplayLockBudget::Phase::kStyle); EXPECT_TRUE( budget->ShouldPerformPhase(DisplayLockBudget::Phase::kLayout, GetDocument().View()->CurrentLifecycleData())); - EXPECT_TRUE(parent->GetLayoutObject()->NeedsLayout()); - EXPECT_TRUE(element->GetLayoutObject()->NeedsLayout()); - GetDocument().View()->SetInLifecycleUpdateForTest(false); }
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc index 2773b44..f255c8b 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -443,6 +443,8 @@ if (target == kSelf) return; + // Since we did layout on children already, we'll clear this. + child_layout_was_blocked_ = false; if (state_ == kUpdating) update_budget_->DidPerformPhase(DisplayLockBudget::Phase::kLayout); } @@ -516,7 +518,7 @@ // this, since |update_forced_| doesn't force paint to happen. See // ShouldPaint(). MarkForStyleRecalcIfNeeded(); - MarkAncestorsForLayoutIfNeeded(); + MarkForLayoutIfNeeded(); MarkAncestorsForPrePaintIfNeeded(); return ScopedForcedUpdate(this); } @@ -561,7 +563,7 @@ // Now that we know we have a layout object, we should ensure that we can // reach the rest of the phases as well. - MarkAncestorsForLayoutIfNeeded(); + MarkForLayoutIfNeeded(); MarkAncestorsForPrePaintIfNeeded(); MarkPaintLayerNeedsRepaint(); @@ -645,9 +647,26 @@ return false; } -bool DisplayLockContext::MarkAncestorsForLayoutIfNeeded() { +bool DisplayLockContext::MarkForLayoutIfNeeded() { if (IsElementDirtyForLayout()) { - element_->GetLayoutObject()->MarkContainerChainForLayout(); + // Forces the marking of ancestors to happen, even if + // |DisplayLockContext::ShouldLayout()| returns false. + base::AutoReset<bool> scoped_force(&update_forced_, true); + if (child_layout_was_blocked_) { + // We've previously blocked a child traversal when doing self-layout for + // the locked element, so we're marking it with child-needs-layout so that + // it will traverse to the locked element and do the child traversal + // again. We don't need to mark it for self-layout (by calling + // |LayoutObject::SetNeedsLayout()|) because the locked element itself + // doesn't need to relayout. + element_->GetLayoutObject()->SetChildNeedsLayout(); + child_layout_was_blocked_ = false; + } else { + // Since the dirty layout propagation stops at the locked element, we need + // to mark its ancestors as dirty here so that it will be traversed to on + // the next layout. + element_->GetLayoutObject()->MarkContainerChainForLayout(); + } return true; } return false; @@ -703,7 +722,7 @@ bool DisplayLockContext::IsElementDirtyForLayout() const { if (auto* layout_object = element_->GetLayoutObject()) - return layout_object->NeedsLayout(); + return layout_object->NeedsLayout() || child_layout_was_blocked_; return false; }
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.h b/third_party/blink/renderer/core/display_lock/display_lock_context.h index 1303221..2617a07 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.h +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.h
@@ -168,6 +168,8 @@ reattach_layout_tree_was_blocked_ = true; } + void NotifyChildLayoutWasBlocked() { child_layout_was_blocked_ = true; } + // Inform the display lock that it needs a graphics layer collection when it // needs to paint. void NotifyNeedsGraphicsLayerCollection() { @@ -229,7 +231,7 @@ // as well if needed. They return true if the element or its subtree were // dirty, and false otherwise. bool MarkForStyleRecalcIfNeeded(); - bool MarkAncestorsForLayoutIfNeeded(); + bool MarkForLayoutIfNeeded(); bool MarkAncestorsForPrePaintIfNeeded(); bool MarkPaintLayerNeedsRepaint(); @@ -329,6 +331,11 @@ bool needs_prepaint_subtree_walk_ = false; bool is_horizontal_writing_mode_ = true; bool needs_graphics_layer_collection_ = false; + // Will be true if child traversal was blocked on a previous layout run on the + // locked element. We need to keep track of this to ensure that on the next + // layout run where the descendants of the locked element are allowed to be + // traversed into, we will traverse to the children of the locked element. + bool child_layout_was_blocked_ = false; TaskHandle timeout_task_handle_; };
diff --git a/third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.cc b/third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.cc index 6e585907..8ed458b 100644 --- a/third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.cc +++ b/third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.cc
@@ -25,7 +25,7 @@ // Mark all the phases dirty since we have no intention of yielding. for (auto phase = static_cast<unsigned>(Phase::kFirst); phase <= static_cast<unsigned>(Phase::kLast); ++phase) { - MarkAncestorsDirtyForPhaseIfNeeded(static_cast<Phase>(phase)); + MarkDirtyForPhaseIfNeeded(static_cast<Phase>(phase)); } }
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index 8eba8e1..5a5973ed 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -1146,8 +1146,11 @@ web_frame_->Client()->DraggableRegionsChanged(); } -void LocalFrameClientImpl::DidBlockFramebust(const KURL& url) { - web_frame_->Client()->DidBlockFramebust(url); +void LocalFrameClientImpl::DidBlockNavigation( + const KURL& blocked_url, + const KURL& initiator_url, + blink::NavigationBlockedReason reason) { + web_frame_->Client()->DidBlockNavigation(blocked_url, initiator_url, reason); } base::UnguessableToken LocalFrameClientImpl::GetDevToolsFrameToken() const {
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h index 754f3ee..94d091e 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -278,7 +278,9 @@ void AnnotatedRegionsChanged() override; - void DidBlockFramebust(const KURL&) override; + void DidBlockNavigation(const KURL& blocked_url, + const KURL& initiator_url, + blink::NavigationBlockedReason reason) override; base::UnguessableToken GetDevToolsFrameToken() const override;
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 410bb652..cd974db 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -37,6 +37,7 @@ #include "services/network/public/cpp/features.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/frame/blocked_navigation_types.h" #include "third_party/blink/public/platform/interface_provider.h" #include "third_party/blink/public/platform/interface_registry.h" #include "third_party/blink/public/platform/scheduler/web_resource_loading_task_runner_handle.h" @@ -1017,6 +1018,9 @@ !LocalFrame::HasTransientUserActivation(this)) { // With only 'allow-top-navigation-by-user-activation' (but not // 'allow-top-navigation'), top navigation requires a user gesture. + Client()->DidBlockNavigation( + destination_url, GetDocument()->Url(), + blink::NavigationBlockedReason::kRedirectWithNoUserGestureSandbox); PrintNavigationErrorMessage( target_frame, "The frame attempting navigation of the top-level window is " @@ -1089,7 +1093,9 @@ "but is neither same-origin with its target nor has it received a " "user gesture. See " "https://www.chromestatus.com/features/5851021045661696."); - Client()->DidBlockFramebust(destination_url); + Client()->DidBlockNavigation( + destination_url, GetDocument()->Url(), + blink::NavigationBlockedReason::kRedirectWithNoUserGesture); } else { PrintNavigationErrorMessage(target_frame, "The frame attempting navigation is neither "
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h index a240c7b..b87c9fd 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -454,7 +454,9 @@ virtual void AnnotatedRegionsChanged() = 0; - virtual void DidBlockFramebust(const KURL&) {} + virtual void DidBlockNavigation(const KURL& blocked_url, + const KURL& initiator_urk, + blink::NavigationBlockedReason reason) {} // Called when the corresponding frame should be scrolled in a remote parent // frame.
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/third_party/blink/renderer/core/html/html_frame_owner_element.cc index 4b8a9861..b30d1a1 100644 --- a/third_party/blink/renderer/core/html/html_frame_owner_element.cc +++ b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -48,6 +48,7 @@ #include "third_party/blink/renderer/core/timing/window_performance.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/heap_allocator.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/network/network_state_notifier.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" @@ -517,11 +518,16 @@ // "auto" instead). if (EqualIgnoringASCIICase(params.new_value, "eager") && !GetDocument().IsLazyLoadPolicyEnforced()) { + UseCounter::Count(GetDocument(), + WebFeature::kLazyLoadFrameLoadingAttributeEager); should_lazy_load_children_ = false; if (lazy_load_frame_observer_ && lazy_load_frame_observer_->IsLazyLoadPending()) { lazy_load_frame_observer_->LoadImmediately(); } + } else if (EqualIgnoringASCIICase(params.new_value, "lazy")) { + UseCounter::Count(GetDocument(), + WebFeature::kLazyLoadFrameLoadingAttributeLazy); } } else { HTMLElement::ParseAttribute(params);
diff --git a/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc b/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc index c3eeb13..b97f565 100644 --- a/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc +++ b/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc
@@ -771,6 +771,10 @@ EXPECT_TRUE(ConsoleMessages().Contains("main body onload")); EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload")); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeLazy)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeEager)); ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0); histogram_tester()->ExpectTotalCount( @@ -817,6 +821,10 @@ EXPECT_EQ(RuntimeEnabledFeatures::LazyFrameLoadingEnabled(), ConsoleMessages().Contains("main body onload")); EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload")); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeEager)); ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0); @@ -937,6 +945,10 @@ EXPECT_TRUE(ConsoleMessages().Contains("main body onload")); EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload")); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeLazy)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeEager)); ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0); @@ -1014,6 +1026,10 @@ Compositor().BeginFrame(); test::RunPendingTasks(); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeLazy)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeEager)); // There's another nested cross origin iframe inside the first child frame, // even further down such that it's not near the viewport. If LazyLoad is @@ -1090,6 +1106,10 @@ EXPECT_TRUE(ConsoleMessages().Contains("main body onload")); EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload")); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeLazy)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeEager)); } INSTANTIATE_TEST_SUITE_P( @@ -1215,6 +1235,10 @@ false); TestCrossOriginFrameIsImmediatelyLoaded("loading='lazy'"); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeEager)); } TEST_F(LazyLoadFramesTest, LazyLoadWhenAttrLazy) { @@ -1226,6 +1250,10 @@ false); TestCrossOriginFrameIsLazilyLoaded("loading='lazy'"); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeEager)); } TEST_F(LazyLoadFramesTest, LazyLoadWhenAttrEager) { @@ -1237,6 +1265,10 @@ false); TestCrossOriginFrameIsImmediatelyLoaded("loading='eager'"); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeLazy)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeEager)); } TEST_F(LazyLoadFramesTest, LazyLoadWhenAutomaticAndAttrLazy) { @@ -1248,6 +1280,10 @@ false); TestCrossOriginFrameIsLazilyLoaded("loading='lazy'"); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeEager)); } TEST_F(LazyLoadFramesTest, LazyLoadWhenAutomaticAndAttrEager) { @@ -1259,6 +1295,10 @@ false); TestCrossOriginFrameIsImmediatelyLoaded("loading='eager'"); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeLazy)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeEager)); } TEST_F(LazyLoadFramesTest, LazyLoadWhenAutomaticRestrictedAndAttrLazy) { @@ -1270,6 +1310,10 @@ true); TestCrossOriginFrameIsLazilyLoaded("loading='lazy'"); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeEager)); } TEST_F(LazyLoadFramesTest, LazyLoadWhenAutomaticRestrictedAndAttrEager) { @@ -1282,6 +1326,10 @@ GetNetworkStateNotifier().SetSaveDataEnabled(true); TestCrossOriginFrameIsImmediatelyLoaded("loading='eager'"); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeLazy)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadFrameLoadingAttributeEager)); } TEST_F(LazyLoadFramesTest, LazyLoadWhenAutomaticDisabled) {
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer.cc b/third_party/blink/renderer/core/html/lazy_load_image_observer.cc index 484571b..934ea14 100644 --- a/third_party/blink/renderer/core/html/lazy_load_image_observer.cc +++ b/third_party/blink/renderer/core/html/lazy_load_image_observer.cc
@@ -21,6 +21,7 @@ #include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h" #include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h" #include "third_party/blink/renderer/core/style/computed_style.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" namespace blink { @@ -59,10 +60,10 @@ } // namespace void LazyLoadImageObserver::StartMonitoring(Element* element, - bool is_for_intervention) { + DeferralMessage deferral_message) { if (Document* document = GetRootDocumentOrNull(element)) { document->EnsureLazyLoadImageObserver().StartMonitoringNearViewport( - document, element, is_for_intervention); + document, element, deferral_message); } } @@ -97,7 +98,7 @@ void LazyLoadImageObserver::StartMonitoringNearViewport( Document* root_document, Element* element, - bool is_for_intervention) { + DeferralMessage deferral_message) { DCHECK(RuntimeEnabledFeatures::LazyImageLoadingEnabled()); if (!lazy_load_intersection_observer_) { @@ -110,13 +111,26 @@ } lazy_load_intersection_observer_->observe(element); - if (is_for_intervention && !is_load_event_deferred_intervention_shown_) { + if (deferral_message == DeferralMessage::kLoadEventsDeferred && + !is_load_event_deferred_intervention_shown_) { is_load_event_deferred_intervention_shown_ = true; root_document->AddConsoleMessage(ConsoleMessage::Create( mojom::ConsoleMessageSource::kIntervention, mojom::ConsoleMessageLevel::kInfo, "Images loaded lazily and replaced with placeholders. Load events are " - "deferred. See https://crbug.com/846170")); + "deferred. See https://crbug.com/954323")); + } + if (deferral_message == DeferralMessage::kMissingDimensionForLazy && + !is_missing_dimension_intervention_shown_) { + is_missing_dimension_intervention_shown_ = true; + root_document->AddConsoleMessage(ConsoleMessage::Create( + mojom::ConsoleMessageSource::kIntervention, + mojom::ConsoleMessageLevel::kInfo, + "An <img> element was lazyloaded with loading=lazy, but had no " + "dimensions specified. Specifying dimensions improves performance. See " + "https://crbug.com/954323")); + UseCounter::Count(root_document, + WebFeature::kLazyLoadImageMissingDimensionsForLazy); } }
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer.h b/third_party/blink/renderer/core/html/lazy_load_image_observer.h index 4d3ea5d..946b482 100644 --- a/third_party/blink/renderer/core/html/lazy_load_image_observer.h +++ b/third_party/blink/renderer/core/html/lazy_load_image_observer.h
@@ -21,6 +21,12 @@ class LazyLoadImageObserver final : public GarbageCollected<LazyLoadImageObserver> { public: + enum class DeferralMessage { + kNone, + kLoadEventsDeferred, + kMissingDimensionForLazy + }; + struct VisibleLoadTimeMetrics { // Keeps track of whether the image was initially intersecting the viewport. bool is_initially_intersecting = false; @@ -35,7 +41,9 @@ LazyLoadImageObserver(); - static void StartMonitoring(Element*, bool is_for_intervention); + static void StartMonitoring( + Element*, + DeferralMessage deferral_message = DeferralMessage::kNone); static void StopMonitoring(Element*); static void StartTrackingVisibilityMetrics(HTMLImageElement*); @@ -44,9 +52,7 @@ void Trace(Visitor*); private: - void StartMonitoringNearViewport(Document*, - Element*, - bool is_for_intervention); + void StartMonitoringNearViewport(Document*, Element*, DeferralMessage); void LoadIfNearViewport(const HeapVector<Member<IntersectionObserverEntry>>&); void StartMonitoringVisibility(Document*, HTMLImageElement*); @@ -64,6 +70,7 @@ // Used to show the intervention console message one time only. bool is_load_event_deferred_intervention_shown_ = false; + bool is_missing_dimension_intervention_shown_ = false; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc index 01498a4..069431c 100644 --- a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc +++ b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
@@ -36,7 +36,12 @@ const char* kLazyLoadEventsDeferredMessage = "Images loaded lazily and replaced with placeholders. Load events are " - "deferred. See https://crbug.com/846170"; + "deferred. See https://crbug.com/954323"; + +const char* kLazyLoadMissingDimensionMessage = + "An <img> element was lazyloaded with loading=lazy, but had no dimensions " + "specified. Specifying dimensions improves performance. See " + "https://crbug.com/954323"; Vector<char> ReadTestImage() { return test::ReadFromFile(test::CoreTestDataPath("notifications/500x500.png")) @@ -88,6 +93,13 @@ } EXPECT_TRUE(is_background_image_found); EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadEventsDeferredMessage)); + EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadMissingDimensionMessage)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageMissingDimensionsForLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeEager)); } void VerifyCSSBackgroundImageInPseudoStyleDeferred( @@ -134,6 +146,13 @@ } } EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadEventsDeferredMessage)); + EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadMissingDimensionMessage)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageMissingDimensionsForLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeEager)); } void VerifyImageElementWithDimensionDeferred(const char* img_attribute) { @@ -170,6 +189,13 @@ } EXPECT_EQ(is_lazyload_image_enabled, ConsoleMessages().Contains(kLazyLoadEventsDeferredMessage)); + EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadMissingDimensionMessage)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageMissingDimensionsForLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeEager)); } private: @@ -544,6 +570,19 @@ EXPECT_TRUE(ConsoleMessages().Contains("lazy onload")); EXPECT_TRUE(ConsoleMessages().Contains("auto onload")); EXPECT_TRUE(ConsoleMessages().Contains("unset onload")); + + switch (std::get<LazyImageLoadingFeatureStatus>(GetParam())) { + case LazyImageLoadingFeatureStatus::kEnabledAutomatic: + case LazyImageLoadingFeatureStatus:: + kEnabledAutomaticRestrictedAndDataSaverOn: + EXPECT_TRUE(ConsoleMessages().Contains(kLazyLoadEventsDeferredMessage)); + EXPECT_TRUE(ConsoleMessages().Contains(kLazyLoadMissingDimensionMessage)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageMissingDimensionsForLazy)); + break; + default: + break; + } } TEST_P(LazyLoadImagesParamsTest, FarFromViewport) { @@ -697,6 +736,19 @@ EXPECT_TRUE(ConsoleMessages().Contains("lazy onload")); EXPECT_TRUE(ConsoleMessages().Contains("auto onload")); EXPECT_TRUE(ConsoleMessages().Contains("unset onload")); + + switch (std::get<LazyImageLoadingFeatureStatus>(GetParam())) { + case LazyImageLoadingFeatureStatus::kEnabledAutomatic: + case LazyImageLoadingFeatureStatus:: + kEnabledAutomaticRestrictedAndDataSaverOn: + EXPECT_TRUE(ConsoleMessages().Contains(kLazyLoadEventsDeferredMessage)); + EXPECT_TRUE(ConsoleMessages().Contains(kLazyLoadMissingDimensionMessage)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageMissingDimensionsForLazy)); + break; + default: + break; + } } INSTANTIATE_TEST_SUITE_P( @@ -812,6 +864,13 @@ EXPECT_TRUE(ConsoleMessages().Contains("main body onload")); EXPECT_TRUE(ConsoleMessages().Contains("image onload")); EXPECT_TRUE(ConsoleMessages().Contains(kLazyLoadEventsDeferredMessage)); + EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadMissingDimensionMessage)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageMissingDimensionsForLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeEager)); } void TestLoadImageExpectingFullImageLoad(const char* image_attributes) { @@ -833,6 +892,13 @@ EXPECT_TRUE(ConsoleMessages().Contains("main body onload")); EXPECT_TRUE(ConsoleMessages().Contains("image onload")); EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadEventsDeferredMessage)); + EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadMissingDimensionMessage)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageMissingDimensionsForLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeEager)); } private: @@ -865,6 +931,13 @@ EXPECT_TRUE(ConsoleMessages().Contains("main body onload")); EXPECT_TRUE(ConsoleMessages().Contains("image onload")); EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadEventsDeferredMessage)); + EXPECT_TRUE(ConsoleMessages().Contains(kLazyLoadMissingDimensionMessage)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageMissingDimensionsForLazy)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeEager)); } TEST_F(LazyLoadAutomaticImagesTest, AttributeChangedFromAutoToEager) { @@ -889,6 +962,13 @@ EXPECT_TRUE(ConsoleMessages().Contains("main body onload")); EXPECT_TRUE(ConsoleMessages().Contains("image onload")); EXPECT_TRUE(ConsoleMessages().Contains(kLazyLoadEventsDeferredMessage)); + EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadMissingDimensionMessage)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageMissingDimensionsForLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeEager)); } TEST_F(LazyLoadAutomaticImagesTest, AttributeChangedFromUnsetToEager) { @@ -913,17 +993,32 @@ EXPECT_TRUE(ConsoleMessages().Contains("main body onload")); EXPECT_TRUE(ConsoleMessages().Contains("image onload")); EXPECT_TRUE(ConsoleMessages().Contains(kLazyLoadEventsDeferredMessage)); + EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadMissingDimensionMessage)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageMissingDimensionsForLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeEager)); } TEST_F(LazyLoadAutomaticImagesTest, TinyImageWithLazyAttr) { TestLoadImageExpectingLazyLoad("loading='lazy' width='1px' height='1px'"); EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadEventsDeferredMessage)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeEager)); } TEST_F(LazyLoadAutomaticImagesTest, TinyImageViaStyleWithLazyAttr) { TestLoadImageExpectingLazyLoad( "loading='lazy' style='width:1px;height:1px;'"); EXPECT_FALSE(ConsoleMessages().Contains(kLazyLoadEventsDeferredMessage)); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeLazy)); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kLazyLoadImageLoadingAttributeEager)); } TEST_F(LazyLoadAutomaticImagesTest, TinyImageWidth1Height1) {
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc index eebd6d4..b2dbdd5 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow.cc +++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -540,8 +540,7 @@ if (IsHTMLDialogElement(GetNode()) && IsOutOfFlowPositioned()) PositionDialog(); - // Only clear child dirty bits, if we allowed child layout. - ClearNeedsLayout(!LayoutBlockedByDisplayLock(DisplayLockContext::kChildren)); + ClearNeedsLayout(); UpdateIsSelfCollapsing(); NotifyDisplayLockDidLayout(DisplayLockContext::kSelf); }
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index edee4a8..7a8621f 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -2448,14 +2448,16 @@ if (*out_cache_status == NGLayoutCacheStatus::kNeedsSimplifiedLayout) return nullptr; + physical_fragment.CheckType(); + DCHECK_EQ(*out_cache_status, NGLayoutCacheStatus::kHit); // We can safely re-use this fragment if we are positioned, and only our // position constraints changed (left/top/etc). However we need to clear the // dirty layout bit(s). Note that we may be here because we are display locked - // and have cached a locked layout result. In that case, we still need to - // retain child bits. - ClearNeedsLayout(!LayoutBlockedByDisplayLock(DisplayLockContext::kChildren)); + // and have cached a locked layout result. In that case, this function will + // not clear the child dirty bits. + ClearNeedsLayout(); // The checks above should be enough to bail if layout is incomplete, but // let's verify:
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index d9ec29c7..43e1b619 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -1298,12 +1298,10 @@ MarkingBehavior = kMarkContainerChain, SubtreeLayoutScope* = nullptr); - void ClearNeedsLayoutWithoutPaintInvalidation( - bool clear_child_dirty_bits = true); + void ClearNeedsLayoutWithoutPaintInvalidation(); // |ClearNeedsLayout()| calls |SetShouldCheckForPaintInvalidation()|. - void ClearNeedsLayout(bool clear_child_dirty_bits = true); - void ClearNeedsLayoutWithFullPaintInvalidation( - bool clear_child_dirty_bits = true); + void ClearNeedsLayout(); + void ClearNeedsLayoutWithFullPaintInvalidation(); void SetChildNeedsLayout(MarkingBehavior = kMarkContainerChain, SubtreeLayoutScope* = nullptr); @@ -2386,7 +2384,7 @@ bitfields_.SetOutlineMayBeAffectedByDescendants(b); } - bool LayoutBlockedByDisplayLock( + inline bool LayoutBlockedByDisplayLock( DisplayLockContext::LifecycleTarget target) const { auto* context = GetDisplayLockContext(); return context && !context->ShouldLayout(target); @@ -3273,8 +3271,7 @@ SetShouldDoFullPaintInvalidation(); } -inline void LayoutObject::ClearNeedsLayoutWithoutPaintInvalidation( - bool clear_child_dirty_bits) { +inline void LayoutObject::ClearNeedsLayoutWithoutPaintInvalidation() { // Set flags for later stages/cycles. SetEverHadLayout(); @@ -3284,10 +3281,19 @@ SetNeedsPositionedMovementLayout(false); SetAncestorLineBoxDirty(false); - if (clear_child_dirty_bits) { + if (!LayoutBlockedByDisplayLock(DisplayLockContext::kChildren)) { SetPosChildNeedsLayout(false); SetNormalChildNeedsLayout(false); SetNeedsSimplifiedNormalFlowLayout(false); + } else if (!PosChildNeedsLayout() && !NormalChildNeedsLayout() && + !NeedsSimplifiedNormalFlowLayout()) { + // We aren't clearing the child dirty bits because the node is locked and + // layout for children is not done. If the children aren't dirty, we need + // to notify the display lock that child traversal was blocked so that when + // the subtree gets updated/unlocked we will traverse the children. + auto* context = GetDisplayLockContext(); + DCHECK(context); + context->NotifyChildLayoutWasBlocked(); } #if DCHECK_IS_ON() @@ -3297,14 +3303,13 @@ SetScrollAnchorDisablingStyleChanged(false); } -inline void LayoutObject::ClearNeedsLayout(bool clear_child_dirty_bits) { - ClearNeedsLayoutWithoutPaintInvalidation(clear_child_dirty_bits); +inline void LayoutObject::ClearNeedsLayout() { + ClearNeedsLayoutWithoutPaintInvalidation(); SetShouldCheckForPaintInvalidation(); } -inline void LayoutObject::ClearNeedsLayoutWithFullPaintInvalidation( - bool clear_child_dirty_bits) { - ClearNeedsLayoutWithoutPaintInvalidation(clear_child_dirty_bits); +inline void LayoutObject::ClearNeedsLayoutWithFullPaintInvalidation() { + ClearNeedsLayoutWithoutPaintInvalidation(); SetShouldDoFullPaintInvalidation(); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc index b0c718a..10efe80 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -725,14 +725,19 @@ } box_->UpdateAfterLayout(); - // We should only clear the child layout bits if display-locking has not - // prevented us from laying the children out. - box_->ClearNeedsLayout( - !box_->LayoutBlockedByDisplayLock(DisplayLockContext::kChildren)); + box_->ClearNeedsLayout(); // Overflow computation depends on this being set. if (LIKELY(block_flow)) block_flow->UpdateIsSelfCollapsing(); + + // We should notify the display lock that we've done layout on self, and if + // it's not blocked, on children. + if (auto* context = box_->GetDisplayLockContext()) { + context->DidLayout(DisplayLockContext::kSelf); + if (!LayoutBlockedByDisplayLock(DisplayLockContext::kChildren)) + context->DidLayout(DisplayLockContext::kChildren); + } } void NGBlockNode::PlaceChildrenInLayoutBox(
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc index 648a6fc3..7668edb 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
@@ -261,6 +261,7 @@ scoped_refptr<const NGPhysicalBoxFragment> fragment = NGPhysicalBoxFragment::Create(this, block_or_line_writing_mode); + fragment->CheckType(); return base::AdoptRef(new NGLayoutResult(std::move(fragment), this)); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc index 91742b4..5fbf64f7 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
@@ -357,6 +357,58 @@ } #if DCHECK_IS_ON() +void NGPhysicalFragment::CheckType() const { + switch (Type()) { + case kFragmentBox: + case kFragmentRenderedLegend: + if (IsInlineBox()) { + DCHECK(layout_object_.IsLayoutInline()); + } else { + DCHECK(layout_object_.IsBox()); + } + if (IsColumnBox()) { + // TODO(kojii): Column box can fail following checks, needs review. + break; + } + if (layout_object_.IsLayoutNGListMarker()) { + // List marker is an atomic inline if it appears in a line box, or a + // block box. + DCHECK(!IsFloating()); + DCHECK(!IsOutOfFlowPositioned()); + DCHECK(IsAtomicInline() || (IsBox() && BoxType() == kBlockFlowRoot)); + break; + } + DCHECK_EQ(IsFloating(), layout_object_.IsFloating()); + DCHECK_EQ(IsOutOfFlowPositioned(), + layout_object_.IsOutOfFlowPositioned()); + DCHECK_EQ(IsAtomicInline(), layout_object_.IsInline() && + layout_object_.IsAtomicInlineLevel()); + break; + case kFragmentText: + if (To<NGPhysicalTextFragment>(this)->IsGeneratedText()) { + // Ellipsis has the truncated in-flow LayoutObject. + DCHECK(layout_object_.IsText() || + (layout_object_.IsInline() && + layout_object_.IsAtomicInlineLevel()) || + layout_object_.IsLayoutInline()); + } else { + DCHECK(layout_object_.IsText()); + } + DCHECK(!IsFloating()); + DCHECK(!IsOutOfFlowPositioned()); + DCHECK(!IsInlineBox()); + DCHECK(!IsAtomicInline()); + break; + case kFragmentLineBox: + DCHECK(layout_object_.IsLayoutBlockFlow()); + DCHECK(!IsFloating()); + DCHECK(!IsOutOfFlowPositioned()); + DCHECK(!IsInlineBox()); + DCHECK(!IsAtomicInline()); + break; + } +} + void NGPhysicalFragment::CheckCanUpdateInkOverflow() const { if (!GetLayoutObject()) return;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h index 8488674..3e9fe50 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
@@ -242,6 +242,7 @@ String ToString() const; + void CheckType() const; void CheckCanUpdateInkOverflow() const; enum DumpFlag { @@ -335,6 +336,7 @@ }; #if !DCHECK_IS_ON() +inline void NGPhysicalFragment::CheckType() const {} inline void NGPhysicalFragment::CheckCanUpdateInkOverflow() const {} #endif
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc index 161f88c..b173bbe 100644 --- a/third_party/blink/renderer/core/loader/image_loader.cc +++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -97,10 +97,15 @@ return LazyLoadImageEligibility::kDisabled; LoadingAttrValue loading_attr = GetLoadingAttrValue(html_image); - if (loading_attr == LoadingAttrValue::kLazy) + if (loading_attr == LoadingAttrValue::kLazy) { + UseCounter::Count(frame.GetDocument(), + WebFeature::kLazyLoadImageLoadingAttributeLazy); return LazyLoadImageEligibility::kEnabledExplicit; + } if (loading_attr == LoadingAttrValue::kEager && !frame.GetDocument()->IsLazyLoadPolicyEnforced()) { + UseCounter::Count(frame.GetDocument(), + WebFeature::kLazyLoadImageLoadingAttributeEager); return LazyLoadImageEligibility::kDisabled; } @@ -497,9 +502,16 @@ image_complete_ = false; if (lazy_image_load_state_ == LazyImageLoadState::kDeferred) { if (auto* html_image = ToHTMLImageElementOrNull(GetElement())) { - LazyLoadImageObserver::StartMonitoring( - html_image, - GetLoadingAttrValue(*html_image) != LoadingAttrValue::kLazy); + using DeferralMessage = LazyLoadImageObserver::DeferralMessage; + LoadingAttrValue loading_attr = GetLoadingAttrValue(*html_image); + DCHECK(loading_attr != LoadingAttrValue::kEager); + auto deferral_message = DeferralMessage::kNone; + if (loading_attr == LoadingAttrValue::kAuto) { + deferral_message = DeferralMessage::kLoadEventsDeferred; + } else if (!was_fully_deferred_) { + deferral_message = DeferralMessage::kMissingDimensionForLazy; + } + LazyLoadImageObserver::StartMonitoring(html_image, deferral_message); } } }
diff --git a/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc b/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc index 58264732..98ca60a 100644 --- a/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc +++ b/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator_test.cc
@@ -76,9 +76,6 @@ .GetTextPaintTimingDetector(); text_detector->ReportSwapTime(WebWidgetClient::SwapResult::kDidSwap, simulated_clock_.NowTicks()); - // TexPaintTimingDetector does not update the candidate on the swap - // callback, so manually call it. - text_detector->UpdateCandidate(); } private:
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc index 6ace85bc2..3d85459 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -415,6 +415,8 @@ !box_physical_fragment || box_physical_fragment->ChildrenInline(); for (const NGLink& child_fragment : container.Children()) { + child_fragment->CheckType(); + // OOF objects are not needed because they always have self painting layer. if (UNLIKELY(child_fragment->IsOutOfFlowPositioned())) continue;
diff --git a/third_party/blink/renderer/core/paint/paint_timing_detector.cc b/third_party/blink/renderer/core/paint/paint_timing_detector.cc index 169c55d..bc3add6 100644 --- a/third_party/blink/renderer/core/paint/paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/paint_timing_detector.cc
@@ -54,7 +54,7 @@ PaintTimingDetector::PaintTimingDetector(LocalFrameView* frame_view) : frame_view_(frame_view), text_paint_timing_detector_( - MakeGarbageCollected<TextPaintTimingDetector>(frame_view)), + MakeGarbageCollected<TextPaintTimingDetector>(frame_view, this)), image_paint_timing_detector_( MakeGarbageCollected<ImagePaintTimingDetector>(frame_view)) {}
diff --git a/third_party/blink/renderer/core/paint/text_element_timing.cc b/third_party/blink/renderer/core/paint/text_element_timing.cc index 294a42e..62179ed 100644 --- a/third_party/blink/renderer/core/paint/text_element_timing.cc +++ b/third_party/blink/renderer/core/paint/text_element_timing.cc
@@ -42,7 +42,7 @@ Node* node, const IntRect& aggregated_visual_rect, const PropertyTreeState& property_tree_state, - LocalFrameView* frame_view) { + const LocalFrameView* frame_view) { if (!NeededForElementTiming(node)) return FloatRect();
diff --git a/third_party/blink/renderer/core/paint/text_element_timing.h b/third_party/blink/renderer/core/paint/text_element_timing.h index 1754f87..79a2eb2 100644 --- a/third_party/blink/renderer/core/paint/text_element_timing.h +++ b/third_party/blink/renderer/core/paint/text_element_timing.h
@@ -44,7 +44,7 @@ Node*, const IntRect& aggregated_visual_rect, const PropertyTreeState&, - LocalFrameView*); + const LocalFrameView*); // Called when the swap promise queued by TextPaintTimingDetector has been // resolved. Dispatches PerformanceElementTiming entries to WindowPerformance.
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc index 9bfc68c..d5306ed 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
@@ -27,8 +27,6 @@ namespace { -// Calculate metrics candidate every 1 second after the first text pre-paint. -constexpr base::TimeDelta kTimerDelay = base::TimeDelta::FromSeconds(1); constexpr size_t kTextNodeNumberLimit = 5000; bool LargeTextFirst(const base::WeakPtr<TextRecord>& a, @@ -44,14 +42,13 @@ } // namespace -TextPaintTimingDetector::TextPaintTimingDetector(LocalFrameView* frame_view) - : records_manager_(), - timer_(frame_view->GetFrame().GetTaskRunner(TaskType::kInternalDefault), - this, - &TextPaintTimingDetector::TimerFired), +TextPaintTimingDetector::TextPaintTimingDetector( + LocalFrameView* frame_view, + PaintTimingDetector* paint_timing_detector) + : records_manager_(frame_view, paint_timing_detector), frame_view_(frame_view) {} -void TextPaintTimingDetector::PopulateTraceValue( +void LargestTextPaintManager::PopulateTraceValue( TracedValue& value, const TextRecord& first_text_paint) { // TODO(crbug.com/976893): Remove DOMNodeId. @@ -63,7 +60,7 @@ !frame_view_->GetFrame().LocalFrameRoot().IsMainFrame()); } -void TextPaintTimingDetector::ReportCandidateToTrace( +void LargestTextPaintManager::ReportCandidateToTrace( const TextRecord& largest_text_record) { auto value = std::make_unique<TracedValue>(); PopulateTraceValue(*value, largest_text_record); @@ -75,7 +72,7 @@ ToTraceValue(&frame_view_->GetFrame())); } -void TextPaintTimingDetector::ReportNoCandidateToTrace() { +void LargestTextPaintManager::ReportNoCandidateToTrace() { auto value = std::make_unique<TracedValue>(); value->SetInteger("candidateIndex", ++count_candidates_); value->SetBoolean("isMainFrame", frame_view_->GetFrame().IsMainFrame()); @@ -86,37 +83,26 @@ ToTraceValue(&frame_view_->GetFrame())); } -// The timer has guaranteed that |this| exists when this function is invoked. -void TextPaintTimingDetector::TimerFired(TimerBase* time) { - // Wrap |UpdateCandidate| method in TimerFired so that we can drop |time| for - // |UpdateCandidate| in testing. - UpdateCandidate(); -} - -void TextPaintTimingDetector::UpdateCandidate() { - if (!is_recording_) - return; - if (!is_recording_ltp_) - return; - - DCHECK(RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled()); - base::WeakPtr<TextRecord> largest_text_record = - records_manager_.FindLargestPaintCandidate(); +void LargestTextPaintManager::UpdateCandidate() { + base::WeakPtr<TextRecord> largest_text_record = FindLargestPaintCandidate(); const base::TimeTicks time = largest_text_record ? largest_text_record->paint_time : base::TimeTicks(); const uint64_t size = largest_text_record ? largest_text_record->first_size : 0; - PaintTimingDetector& detector = frame_view_->GetPaintTimingDetector(); - bool changed = detector.NotifyIfChangedLargestTextPaint(time, size); + DCHECK(paint_timing_detector_); + bool changed = + paint_timing_detector_->NotifyIfChangedLargestTextPaint(time, size); if (!changed) return; if (largest_text_record && !largest_text_record->paint_time.is_null()) { - if (auto* lcp_calculator = detector.GetLargestContentfulPaintCalculator()) + if (auto* lcp_calculator = + paint_timing_detector_->GetLargestContentfulPaintCalculator()) lcp_calculator->OnLargestTextUpdated(largest_text_record); ReportCandidateToTrace(*largest_text_record); } else { - if (auto* lcp_calculator = detector.GetLargestContentfulPaintCalculator()) + if (auto* lcp_calculator = + paint_timing_detector_->GetLargestContentfulPaintCalculator()) lcp_calculator->OnLargestTextUpdated(nullptr); ReportNoCandidateToTrace(); } @@ -125,12 +111,10 @@ void TextPaintTimingDetector::OnPaintFinished() { if (need_update_timing_at_frame_end_) { need_update_timing_at_frame_end_ = false; - UpdateCandidate(); + if (records_manager_.GetLargestTextPaintManager()) + records_manager_.GetLargestTextPaintManager()->UpdateCandidate(); } if (records_manager_.NeedMeausuringPaintTime()) { - // Start repeating timer only once at the first text paint. - if (!timer_.IsActive() && is_recording_ltp_) - timer_.StartRepeating(kTimerDelay, FROM_HERE); if (!awaiting_swap_promise_) { // |WrapCrossThreadWeakPersistent| guarantees that when |this| is killed, // the callback function will not be invoked. @@ -180,6 +164,8 @@ } } records_manager_.AssignPaintTimeToQueuedNodes(timestamp); + if (records_manager_.GetLargestTextPaintManager()) + records_manager_.GetLargestTextPaintManager()->UpdateCandidate(); awaiting_swap_promise_ = false; } @@ -195,7 +181,8 @@ // If we have finished recording Largest Text Paint and the element is a // shadow element or has no elementtiming attribute, then we should not record // its text. - if (!is_recording_ltp_ && !TextElementTiming::NeededForElementTiming(node)) + if (!records_manager_.IsRecordingLargestTextPaint() && + !TextElementTiming::NeededForElementTiming(node)) return false; DOMNodeId node_id = DOMNodeIds::ExistingIdForNode(node); @@ -246,20 +233,13 @@ } } -base::WeakPtr<TextRecord> TextPaintTimingDetector::FindLargestPaintCandidate() { - return records_manager_.FindLargestPaintCandidate(); -} - void TextPaintTimingDetector::StopRecordEntries() { - timer_.Stop(); is_recording_ = false; records_manager_.CleanUp(); } void TextPaintTimingDetector::StopRecordingLargestTextPaint() { - timer_.Stop(); - is_recording_ltp_ = false; - records_manager_.CleanUpLargestContentfulPaint(); + records_manager_.CleanUpLargestTextPaint(); } void TextPaintTimingDetector::Trace(blink::Visitor* visitor) { @@ -267,26 +247,36 @@ visitor->Trace(frame_view_); } -TextRecordsManager::TextRecordsManager() : size_ordered_set_(&LargeTextFirst) {} +LargestTextPaintManager::LargestTextPaintManager( + LocalFrameView* frame_view, + PaintTimingDetector* paint_timing_detector) + : size_ordered_set_(&LargeTextFirst), + frame_view_(frame_view), + paint_timing_detector_(paint_timing_detector) {} + +void LargestTextPaintManager::Trace(blink::Visitor* visitor) { + visitor->Trace(frame_view_); + visitor->Trace(paint_timing_detector_); +} void TextRecordsManager::RemoveVisibleRecord(const LayoutObject& object) { DCHECK(visible_node_map_.Contains(&object)); - size_ordered_set_.erase(visible_node_map_.at(&object)->AsWeakPtr()); + if (ltp_manager_) { + ltp_manager_->RemoveVisibleRecord( + visible_node_map_.at(&object)->AsWeakPtr()); + } visible_node_map_.erase(&object); // We don't need to remove elements in |texts_queued_for_paint_time_| and // |cached_largest_paint_candidate_| as they are weak ptr. - is_result_invalidated_ = true; } -void TextRecordsManager::CleanUpLargestContentfulPaint() { - size_ordered_set_.clear(); - is_result_invalidated_ = true; +void TextRecordsManager::CleanUpLargestTextPaint() { + ltp_manager_.reset(); } void TextRecordsManager::RemoveInvisibleRecord(const LayoutObject& object) { DCHECK(invisible_node_ids_.Contains(&object)); invisible_node_ids_.erase(&object); - is_result_invalidated_ = true; } void TextRecordsManager::AssignPaintTimeToQueuedNodes( @@ -310,7 +300,8 @@ if (text_element_timing_) text_element_timing_->OnTextNodesPainted(texts_queued_for_paint_time_); texts_queued_for_paint_time_.clear(); - is_result_invalidated_ = true; + if (ltp_manager_) + ltp_manager_->SetCachedResultInvalidated(true); } void TextRecordsManager::RecordVisibleObject( @@ -323,11 +314,12 @@ std::unique_ptr<TextRecord> record = std::make_unique<TextRecord>(node_id, visual_size, element_timing_rect); - if (is_recording_ltp_) - size_ordered_set_.emplace(record->AsWeakPtr()); - QueueToMeasurePaintTime(record->AsWeakPtr()); + base::WeakPtr<TextRecord> record_weak_ptr = record->AsWeakPtr(); + if (ltp_manager_) + ltp_manager_->InsertRecord(record_weak_ptr); + + QueueToMeasurePaintTime(record_weak_ptr); visible_node_map_.insert(&object, std::move(record)); - is_result_invalidated_ = true; } bool TextRecordsManager::HasTooManyNodes() const { @@ -335,8 +327,7 @@ kTextNodeNumberLimit; } -base::WeakPtr<TextRecord> TextRecordsManager::FindLargestPaintCandidate() { - DCHECK_EQ(visible_node_map_.size(), size_ordered_set_.size()); +base::WeakPtr<TextRecord> LargestTextPaintManager::FindLargestPaintCandidate() { if (!is_result_invalidated_ && cached_largest_paint_candidate_) return cached_largest_paint_candidate_; base::WeakPtr<TextRecord> new_largest_paint_candidate = nullptr; @@ -352,15 +343,23 @@ return new_largest_paint_candidate; } +TextRecordsManager::TextRecordsManager( + LocalFrameView* frame_view, + PaintTimingDetector* paint_timing_detector) { + if (RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled()) + ltp_manager_.emplace(frame_view, paint_timing_detector); +} + void TextRecordsManager::CleanUp() { visible_node_map_.clear(); invisible_node_ids_.clear(); texts_queued_for_paint_time_.clear(); - CleanUpLargestContentfulPaint(); + CleanUpLargestTextPaint(); } void TextRecordsManager::Trace(blink::Visitor* visitor) { visitor->Trace(text_element_timing_); + visitor->Trace(ltp_manager_); } } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h index 5f6d10f..d296c9fc 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
@@ -13,7 +13,6 @@ #include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/paint/text_element_timing.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/time.h" @@ -43,17 +42,64 @@ DISALLOW_COPY_AND_ASSIGN(TextRecord); }; -class TextRecordsManager { +class CORE_EXPORT LargestTextPaintManager { DISALLOW_NEW(); using TextRecordSetComparator = bool (*)(const base::WeakPtr<TextRecord>&, const base::WeakPtr<TextRecord>&); using TextRecordSet = std::set<base::WeakPtr<TextRecord>, TextRecordSetComparator>; + + public: + LargestTextPaintManager(LocalFrameView*, PaintTimingDetector*); + + inline void RemoveVisibleRecord(base::WeakPtr<TextRecord> record) { + size_ordered_set_.erase(record); + if (cached_largest_paint_candidate_.get() == record.get()) + cached_largest_paint_candidate_ = nullptr; + is_result_invalidated_ = true; + } + + base::WeakPtr<TextRecord> FindLargestPaintCandidate(); + + void ReportCandidateToTrace(const TextRecord&); + void ReportNoCandidateToTrace(); + void UpdateCandidate(); + void PopulateTraceValue(TracedValue&, const TextRecord& first_text_paint); + inline void SetCachedResultInvalidated(bool value) { + is_result_invalidated_ = value; + } + + inline void InsertRecord(base::WeakPtr<TextRecord> record) { + size_ordered_set_.emplace(record); + SetCachedResultInvalidated(true); + } + + void Trace(blink::Visitor*); + + private: + friend class LargestContentfulPaintCalculatorTest; + friend class TextPaintTimingDetectorTest; + + TextRecordSet size_ordered_set_; + base::WeakPtr<TextRecord> cached_largest_paint_candidate_; + // This is used to cache the largest text paint result for better + // efficiency. + // The result will be invalidated whenever any change is done to the + // variables used in |FindLargestPaintCandidate|. + bool is_result_invalidated_ = false; + unsigned count_candidates_ = 0; + + Member<const LocalFrameView> frame_view_; + Member<PaintTimingDetector> paint_timing_detector_; + DISALLOW_COPY_AND_ASSIGN(LargestTextPaintManager); +}; + +class CORE_EXPORT TextRecordsManager { + DISALLOW_NEW(); friend class TextPaintTimingDetectorTest; public: - TextRecordsManager(); - base::WeakPtr<TextRecord> FindLargestPaintCandidate(); + TextRecordsManager(LocalFrameView*, PaintTimingDetector*); void RemoveVisibleRecord(const LayoutObject&); void RemoveInvisibleRecord(const LayoutObject&); @@ -88,40 +134,39 @@ } void CleanUp(); - - void CleanUpLargestContentfulPaint(); + void CleanUpLargestTextPaint(); void StopRecordingLargestTextPaint(); - bool IsRecordingLargestTextPaint() const { return is_recording_ltp_; } - bool HasTextElementTiming() const { return !!text_element_timing_; } + bool HasTextElementTiming() const { return text_element_timing_; } void SetTextElementTiming(TextElementTiming* text_element_timing) { text_element_timing_ = text_element_timing; } + inline base::Optional<LargestTextPaintManager>& GetLargestTextPaintManager() { + return ltp_manager_; + } + + inline bool IsRecordingLargestTextPaint() const { + return ltp_manager_.has_value(); + } + void Trace(blink::Visitor*); private: - inline void QueueToMeasurePaintTime(base::WeakPtr<TextRecord> record) { + friend class LargestContentfulPaintCalculatorTest; + friend class TextPaintTimingDetectorTest; + inline void QueueToMeasurePaintTime(base::WeakPtr<TextRecord>& record) { texts_queued_for_paint_time_.push_back(std::move(record)); } - // This is used to cache the largest text paint result for better efficiency. - // The result will be invalidated whenever any change is done to the variables - // used in |FindLargestPaintCandidate|. - bool is_result_invalidated_ = false; - // This is used to know whether |size_ordered_set_| should be populated or - // not, since this is used by Largest Text Paint but not by Text Element - // Timing. - bool is_recording_ltp_ = - RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled(); + // Once LayoutObject* is destroyed, |visible_node_map_| and // |invisible_node_ids_| must immediately clear the corresponding record from // themselves. HashMap<const LayoutObject*, std::unique_ptr<TextRecord>> visible_node_map_; HashSet<const LayoutObject*> invisible_node_ids_; - TextRecordSet size_ordered_set_; Deque<base::WeakPtr<TextRecord>> texts_queued_for_paint_time_; - base::WeakPtr<TextRecord> cached_largest_paint_candidate_; + base::Optional<LargestTextPaintManager> ltp_manager_; Member<TextElementTiming> text_element_timing_; DISALLOW_COPY_AND_ASSIGN(TextRecordsManager); @@ -151,49 +196,35 @@ friend class TextPaintTimingDetectorTest; public: - TextPaintTimingDetector(LocalFrameView* frame_view); + explicit TextPaintTimingDetector(LocalFrameView*, PaintTimingDetector*); bool ShouldWalkObject(const LayoutBoxModelObject&) const; void RecordAggregatedText(const LayoutBoxModelObject& aggregator, const IntRect& aggregated_visual_rect, const PropertyTreeState&); void OnPaintFinished(); void LayoutObjectWillBeDestroyed(const LayoutObject&); - base::WeakPtr<TextRecord> FindLargestPaintCandidate(); void StopRecordEntries(); void StopRecordingLargestTextPaint(); bool IsRecording() const { return is_recording_; } - bool FinishedReportingText() const { - return !is_recording_ && !need_update_timing_at_frame_end_; - } + inline bool FinishedReportingText() const { return !is_recording_; } void Trace(blink::Visitor*); private: friend class LargestContentfulPaintCalculatorTest; - void PopulateTraceValue(TracedValue&, const TextRecord& first_text_paint); - void TimerFired(TimerBase*); - void UpdateCandidate(); - void ReportSwapTime(WebWidgetClient::SwapResult result, base::TimeTicks timestamp); void RegisterNotifySwapTime(ReportTimeCallback callback); - void ReportCandidateToTrace(const TextRecord&); - void ReportNoCandidateToTrace(); TextRecordsManager records_manager_; // Make sure that at most one swap promise is ongoing. bool awaiting_swap_promise_ = false; - unsigned count_candidates_ = 0; bool is_recording_ = true; - bool is_recording_ltp_ = - RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled(); - bool has_records_changed_ = true; bool need_update_timing_at_frame_end_ = false; - TaskRunnerTimer<TextPaintTimingDetector> timer_; - Member<LocalFrameView> frame_view_; + Member<const LocalFrameView> frame_view_; DISALLOW_COPY_AND_ASSIGN(TextPaintTimingDetector); };
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc index ee2b8cf..51d1c86 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
@@ -55,7 +55,8 @@ wtf_size_t CountRankingSetSize() { return GetPaintTimingDetector() .GetTextPaintTimingDetector() - ->records_manager_.size_ordered_set_.size(); + ->records_manager_.GetLargestTextPaintManager() + ->size_ordered_set_.size(); } void InvokeCallback() { @@ -95,10 +96,6 @@ test_task_runner_->NowTicks()); } - void UpdateCandidate() { - GetPaintTimingDetector().GetTextPaintTimingDetector()->UpdateCandidate(); - } - Element* AppendFontBlockToBody(String content) { Element* font = GetDocument().CreateRawElement(html_names::kFontTag); font->setAttribute(html_names::kSizeAttr, AtomicString("5")); @@ -123,6 +120,7 @@ return GetFrameView() .GetPaintTimingDetector() .GetTextPaintTimingDetector() + ->records_manager_.GetLargestTextPaintManager() ->FindLargestPaintCandidate(); } @@ -130,6 +128,7 @@ return GetChildFrameView() .GetPaintTimingDetector() .GetTextPaintTimingDetector() + ->records_manager_.GetLargestTextPaintManager() ->FindLargestPaintCandidate(); } @@ -236,7 +235,6 @@ <div>small text</div> )HTML"); UpdateAllLifecyclePhasesAndSimulateSwapTime(); - UpdateCandidate(); base::TimeTicks time2 = NowTicks(); base::TimeTicks first_largest = LargestPaintStoredResult(); EXPECT_GE(first_largest, time1); @@ -244,7 +242,6 @@ AppendDivElementToBody("a long-long-long text"); UpdateAllLifecyclePhasesAndSimulateSwapTime(); - UpdateCandidate(); base::TimeTicks time3 = NowTicks(); base::TimeTicks second_largest = LargestPaintStoredResult(); EXPECT_GE(second_largest, time2); @@ -335,14 +332,12 @@ )HTML"); Element* text = AppendDivElementToBody("text to remove"); UpdateAllLifecyclePhasesAndSimulateSwapTime(); - UpdateCandidate(); EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id, DOMNodeIds::ExistingIdForNode(text)); EXPECT_NE(LargestPaintStoredResult(), base::TimeTicks()); RemoveElement(text); UpdateAllLifecyclePhasesAndSimulateSwapTime(); - UpdateCandidate(); EXPECT_FALSE(TextRecordOfLargestTextPaint()); EXPECT_EQ(LargestPaintStoredResult(), base::TimeTicks()); }
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc index 0ce0e92e..bdc97712 100644 --- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc +++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
@@ -1619,6 +1619,9 @@ // the passed string has more than one reference. Append(rest.ToString().Impl()); + if (IsDetached()) + return; + // Finally, if finish() has been called and write() didn't result // in any further callbacks being queued, call end() if (finish_called_ && pending_callbacks_.IsEmpty())
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl index ef921cdf..335e2e9 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl
@@ -9,8 +9,8 @@ [RuntimeEnabled=RTCDtlsTransport] readonly attribute RTCDtlsTransport? transport; [RuntimeEnabled=RTCDtlsTransport] readonly attribute RTCDtlsTransport? rtcpTransport; static RTCRtpCapabilities? getCapabilities(DOMString kind); - [RuntimeEnabled=RTCRtpSenderParameters, CallWith=ScriptState] Promise<void> setParameters(optional RTCRtpSendParameters parameters); - [RuntimeEnabled=RTCRtpSenderParameters] RTCRtpSendParameters getParameters(); + [CallWith=ScriptState] Promise<void> setParameters(optional RTCRtpSendParameters parameters); + RTCRtpSendParameters getParameters(); [Measure, CallWith=ScriptState] Promise<void> replaceTrack(MediaStreamTrack? withTrack); [Measure] readonly attribute RTCDTMFSender? dtmf; [Measure, RaisesException] void setStreams(MediaStream... streams);
diff --git a/third_party/blink/renderer/modules/sensor/magnetometer.idl b/third_party/blink/renderer/modules/sensor/magnetometer.idl index 0b74b93..6edcbc7a 100644 --- a/third_party/blink/renderer/modules/sensor/magnetometer.idl +++ b/third_party/blink/renderer/modules/sensor/magnetometer.idl
@@ -6,6 +6,7 @@ // https://w3c.github.io/magnetometer/#magnetometer-interface [ + Exposed=Window, RuntimeEnabled=SensorExtraClasses, Constructor(optional SpatialSensorOptions sensorOptions), ConstructorCallWith=ExecutionContext,
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc index 89f3891..63762d1 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
@@ -177,7 +177,7 @@ ScriptState::Scope scope( WorkerGlobalScope()->ScriptController()->GetScriptState()); Client().DidInitializeWorkerContext( - WorkerGlobalScope()->ScriptController()->GetContext()); + this, WorkerGlobalScope()->ScriptController()->GetContext()); TRACE_EVENT_END0("ServiceWorker", "ServiceWorkerGlobalScopeProxy::InitializeWorkerContext"); } @@ -338,6 +338,10 @@ embedded_worker_->TerminateWorkerContext(); } +bool ServiceWorkerGlobalScopeProxy::IsWindowInteractionAllowed() { + return WorkerGlobalScope()->IsWindowInteractionAllowed(); +} + WebServiceWorkerContextClient& ServiceWorkerGlobalScopeProxy::Client() const { DCHECK(client_); return *client_;
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h index a8b2097..1928852 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
@@ -93,6 +93,7 @@ int64_t encoded_data_length, int64_t encoded_body_length, int64_t decoded_body_length) override; + bool IsWindowInteractionAllowed() override; // WorkerReportingProxy overrides: void CountFeature(WebFeature) override;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index baf5762..ddf056f 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1323,10 +1323,6 @@ origin_trial_feature_name: "RTCQuicTransport", status: "experimental", }, - { - name: "RTCRtpSenderParameters", - status: "stable", - }, // Enables the use of the RTCSctpTransport object. { name: "RTCSctpTransport",
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index c478f550..ea4b31a 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -2147,6 +2147,11 @@ virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https.html [ WontFix ] virtual/omt-worker-fetch/external/wpt/xhr/send-authentication-existing-session-manual.htm [ WontFix ] virtual/omt-worker-fetch/external/wpt/xhr/send-authentication-prompt-2-manual.htm [ WontFix ] +virtual/not-omt-sw-fetch/external/wpt/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html [ WontFix ] +virtual/not-omt-sw-fetch/external/wpt/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https.html [ WontFix ] +virtual/not-omt-sw-fetch/external/wpt/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https.html [ WontFix ] +virtual/not-omt-sw-fetch/external/wpt/xhr/send-authentication-existing-session-manual.htm [ WontFix ] +virtual/not-omt-sw-fetch/external/wpt/xhr/send-authentication-prompt-2-manual.htm [ WontFix ] virtual/speech-with-unified-autoplay/external/wpt/speech-api/SpeechRecognition-abort-manual.https.html [ WontFix ] virtual/speech-with-unified-autoplay/external/wpt/speech-api/SpeechRecognition-onerror-manual.https.html [ WontFix ] virtual/speech-with-unified-autoplay/external/wpt/speech-api/SpeechRecognition-onresult-manual.https.html [ WontFix ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 55291a7..5157177 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3069,6 +3069,7 @@ crbug.com/832071 virtual/blink-cors/external/wpt/service-workers/service-worker/worker-client-id.https.html [ Failure ] crbug.com/832071 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/worker-client-id.https.html [ Failure ] crbug.com/832071 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-client-id.https.html [ Timeout ] +crbug.com/832071 virtual/not-omt-sw-fetch/external/wpt/service-workers/service-worker/worker-client-id.https.html [ Failure ] # failures in external/wpt/css/css-animations/ and web-animations/ from Mozilla tests crbug.com/849859 external/wpt/css/css-animations/CSSAnimation-pausing.tentative.html [ Failure ] @@ -3227,6 +3228,7 @@ crbug.com/626703 external/wpt/service-workers/service-worker/ready.https.html [ Timeout ] crbug.com/626703 virtual/blink-cors/external/wpt/service-workers/service-worker/ready.https.html [ Timeout ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/ready.https.html [ Timeout ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/service-workers/service-worker/ready.https.html [ Timeout ] crbug.com/626703 [ Linux ] external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-002.tentative.html [ Failure ] crbug.com/626703 [ Mac ] external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-002.tentative.html [ Failure ] crbug.com/626703 [ Win ] external/wpt/css/css-fonts/math-script-level-and-math-style/math-script-level-auto-and-math-style-002.tentative.html [ Failure ] @@ -3296,6 +3298,7 @@ crbug.com/626703 external/wpt/xhr/abort-after-stop.any.worker.html [ Timeout ] crbug.com/626703 virtual/blink-cors/external/wpt/xhr/abort-after-stop.any.worker.html [ Timeout ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/abort-after-stop.any.worker.html [ Timeout ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/xhr/abort-after-stop.any.worker.html [ Timeout ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/vertical_rl.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/vertical_ruby-position.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_vertical_text-combine-upright.html [ Failure ] @@ -3363,6 +3366,7 @@ crbug.com/626703 external/wpt/xhr/event-readystatechange-loaded.any.worker.html [ Timeout Failure ] crbug.com/626703 virtual/blink-cors/external/wpt/xhr/event-readystatechange-loaded.any.worker.html [ Timeout Failure ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/event-readystatechange-loaded.any.worker.html [ Timeout Failure ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/xhr/event-readystatechange-loaded.any.worker.html [ Timeout Failure ] crbug.com/626703 external/wpt/css/css-sizing/image-min-max-content-intrinsic-size-change-003.html [ Failure ] crbug.com/626703 external/wpt/css/css-text/line-breaking/line-breaking-017.html [ Failure ] crbug.com/626703 external/wpt/css/css-scroll-snap/scroll-target-padding-003.html [ Failure ] @@ -3385,6 +3389,7 @@ crbug.com/626703 external/wpt/xhr/event-readystatechange-loaded.any.html [ Timeout Failure ] crbug.com/626703 virtual/blink-cors/external/wpt/xhr/event-readystatechange-loaded.any.html [ Timeout Failure ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/event-readystatechange-loaded.any.html [ Timeout Failure ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/xhr/event-readystatechange-loaded.any.html [ Timeout Failure ] crbug.com/626703 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-margin-002.html [ Failure ] crbug.com/626703 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-padding-002.html [ Failure ] crbug.com/626703 virtual/threaded/external/wpt/css/css-scroll-snap/scroll-target-snap-003.html [ Failure ] @@ -3527,6 +3532,7 @@ crbug.com/626703 external/wpt/fetch/content-type/response.window.html [ Timeout ] crbug.com/626703 virtual/blink-cors/external/wpt/fetch/content-type/response.window.html [ Timeout ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/fetch/content-type/response.window.html [ Timeout ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/fetch/content-type/response.window.html [ Timeout ] crbug.com/626703 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-manual-module.html [ Timeout ] crbug.com/626703 virtual/streaming-preload/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-manual-classic.html [ Timeout ] crbug.com/626703 external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-manual-classic.html [ Timeout ] @@ -3609,6 +3615,11 @@ crbug.com/626703 virtual/omt-worker-fetch/external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout Failure ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout Failure ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/referrer-policy/css-integration/svg/processing-instruction.html [ Timeout Failure ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout Failure ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout Failure ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout Failure ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout Failure ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/css-integration/svg/processing-instruction.html [ Timeout Failure ] crbug.com/906959 external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] crbug.com/906959 external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] @@ -3706,6 +3717,38 @@ crbug.com/906959 virtual/omt-worker-fetch/external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] crbug.com/906959 virtual/omt-worker-fetch/external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] crbug.com/906959 virtual/omt-worker-fetch/external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/origin/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/origin/http-rp/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/same-origin-insecure.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/shared-worker/no-redirect/same-origin-insecure.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/same-origin-insecure.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/shared-worker/no-redirect/same-origin-insecure.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/same-origin/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/same-origin-insecure.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/same-origin/http-rp/same-origin/http-http/shared-worker/no-redirect/same-origin-insecure.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/same-origin/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/same-origin-insecure.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/same-origin/meta-referrer/same-origin/http-http/shared-worker/no-redirect/same-origin-insecure.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/same-insecure.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/shared-worker/no-redirect/same-insecure.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/same-insecure.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/shared-worker/no-redirect/same-insecure.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/insecure-protocol.http.html [ Failure ] +crbug.com/906959 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-complex-001.svg [ Failure ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-bicubic-001.svg [ Failure ] @@ -3832,6 +3875,7 @@ crbug.com/626703 external/wpt/fetch/security/redirect-to-url-with-credentials.https.html [ Timeout ] crbug.com/626703 virtual/blink-cors/external/wpt/fetch/security/redirect-to-url-with-credentials.https.html [ Timeout ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/fetch/security/redirect-to-url-with-credentials.https.html [ Timeout ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/fetch/security/redirect-to-url-with-credentials.https.html [ Timeout ] crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-polygon-024.html [ Failure ] crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-ellipse-048.html [ Failure ] crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-inset-026.html [ Failure ] @@ -3906,6 +3950,7 @@ crbug.com/626703 external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ] crbug.com/626703 virtual/blink-cors/external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/fetch/http-cache/basic-auth-cache-test.html [ Timeout ] crbug.com/626703 external/wpt/css/css-fonts/font-feature-settings-descriptor-01.html [ Failure ] crbug.com/626703 [ Win10 ] external/wpt/fetch/api/redirect/redirect-count.any.worker.html [ Timeout ] crbug.com/626703 [ Win10 ] external/wpt/fetch/api/redirect/redirect-count.any.html [ Timeout ] @@ -4147,6 +4192,7 @@ crbug.com/648295 external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ] crbug.com/648295 virtual/blink-cors/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ] crbug.com/648295 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ] +crbug.com/648295 virtual/not-omt-sw-fetch/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ] crbug.com/626703 external/wpt/svg/linking/reftests/href-filter-element.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_down.html [ Failure ] @@ -4362,9 +4408,11 @@ crbug.com/626703 external/wpt/xhr/preserve-ua-header-on-redirect.htm [ Failure ] crbug.com/626703 virtual/blink-cors/external/wpt/xhr/preserve-ua-header-on-redirect.htm [ Failure ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/preserve-ua-header-on-redirect.htm [ Failure ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/xhr/preserve-ua-header-on-redirect.htm [ Failure ] crbug.com/626703 external/wpt/xhr/setrequestheader-header-allowed.htm [ Failure ] crbug.com/626703 virtual/blink-cors/external/wpt/xhr/setrequestheader-header-allowed.htm [ Failure ] crbug.com/626703 virtual/omt-worker-fetch/external/wpt/xhr/setrequestheader-header-allowed.htm [ Failure ] +crbug.com/626703 virtual/not-omt-sw-fetch/external/wpt/xhr/setrequestheader-header-allowed.htm [ Failure ] crbug.com/626703 [ Win10 ] external/wpt/preload/delaying-onload-link-preload-after-discovery.html [ Timeout ] crbug.com/626703 [ Win ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vlr-005.xht [ Failure ] crbug.com/626703 [ Win ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vrl-004.xht [ Failure ] @@ -4422,6 +4470,7 @@ crbug.com/917554 external/wpt/upgrade-insecure-requests/worker-subresource-fetch-upgrade.https.html [ Crash ] crbug.com/917554 virtual/omt-worker-fetch/external/wpt/upgrade-insecure-requests/worker-subresource-fetch-upgrade.https.html [ Crash ] +crbug.com/917554 virtual/not-omt-sw-fetch/external/wpt/upgrade-insecure-requests/worker-subresource-fetch-upgrade.https.html [ Crash ] # Different results on try bots and CQ, skipped to unblock wpt import. crbug.com/888443 external/wpt/css/cssom-view/scroll-behavior-default-css.html [ Skip ] @@ -4440,6 +4489,8 @@ crbug.com/888470 virtual/blink-cors/external/wpt/referrer-policy/css-integration/child-css/processing-instruction.html [ Failure ] crbug.com/888470 virtual/omt-worker-fetch/external/wpt/referrer-policy/css-integration/child-css/internal-import-stylesheet.html [ Failure ] crbug.com/888470 virtual/omt-worker-fetch/external/wpt/referrer-policy/css-integration/child-css/processing-instruction.html [ Failure ] +crbug.com/888470 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/css-integration/child-css/internal-import-stylesheet.html [ Failure ] +crbug.com/888470 virtual/not-omt-sw-fetch/external/wpt/referrer-policy/css-integration/child-css/processing-instruction.html [ Failure ] # This behavior (popups during unload) is being reverted on trunk; this test is # expected to fail when this change is merged back to earlier branches. @@ -4472,11 +4523,14 @@ crbug.com/881180 external/wpt/xhr/open-url-multi-window-4.htm [ Timeout ] crbug.com/881180 virtual/blink-cors/external/wpt/xhr/open-url-multi-window-4.htm [ Timeout ] crbug.com/881180 virtual/omt-worker-fetch/external/wpt/xhr/open-url-multi-window-4.htm [ Timeout ] +crbug.com/881180 virtual/not-omt-sw-fetch/external/wpt/xhr/open-url-multi-window-4.htm [ Timeout ] crbug.com/655458 external/wpt/workers/Worker_terminate_event_queue.htm [ Pass Timeout ] crbug.com/655458 external/wpt/workers/semantics/multiple-workers/007.html [ Timeout ] crbug.com/655458 virtual/omt-worker-fetch/external/wpt/workers/Worker_terminate_event_queue.htm [ Pass Timeout ] crbug.com/655458 virtual/omt-worker-fetch/external/wpt/workers/semantics/multiple-workers/007.html [ Timeout ] +crbug.com/655458 virtual/not-omt-sw-fetch/external/wpt/workers/Worker_terminate_event_queue.htm [ Pass Timeout ] +crbug.com/655458 virtual/not-omt-sw-fetch/external/wpt/workers/semantics/multiple-workers/007.html [ Timeout ] crbug.com/910709 navigator_language/worker_navigator_language.html [ Timeout ] @@ -4567,6 +4621,7 @@ # worker script, because the script url has a .html file extension. crbug.com/655458 external/wpt/workers/semantics/multiple-workers/003.html [ Timeout ] crbug.com/655458 virtual/omt-worker-fetch/external/wpt/workers/semantics/multiple-workers/003.html [ Timeout ] +crbug.com/655458 virtual/not-omt-sw-fetch/external/wpt/workers/semantics/multiple-workers/003.html [ Timeout ] crbug.com/435547 http/tests/cachestorage/serviceworker/ignore-search-with-credentials.html [ Skip ] @@ -4623,11 +4678,13 @@ crbug.com/691944 external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ] crbug.com/691944 virtual/blink-cors/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ] crbug.com/691944 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ] +crbug.com/691944 virtual/not-omt-sw-fetch/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ] # These tests (erroneously) see a platform-specific User-Agent header crbug.com/595993 external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ] crbug.com/595993 virtual/blink-cors/external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ] crbug.com/595993 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ] +crbug.com/595993 virtual/not-omt-sw-fetch/external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ] crbug.com/619427 [ Mac ] fast/overflow/overflow-height-float-not-removed-crash3.html [ Pass Failure ] @@ -5778,6 +5835,7 @@ crbug.com/933880 external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] crbug.com/933880 virtual/blink-cors/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] crbug.com/933880 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] +crbug.com/933880 virtual/not-omt-sw-fetch/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] crbug.com/933880 http/tests/inspector-protocol/network/interception-take-stream.js [ Failure ] crbug.com/933880 http/tests/inspector-protocol/network/xhr-interception-auth-fail.js [ Failure ] # This passes in content_shell but not in chrome with network service disabled, @@ -6079,6 +6137,7 @@ crbug.com/943636 virtual/mouseevent_fractional/fast/events/set-attribute-listener-window-onerror-crash.html [ Pass Failure ] crbug.com/943636 virtual/mouseevent_fractional/fast/events/window-onerror-05.html [ Pass Failure ] crbug.com/943636 virtual/omt-worker-fetch/fast/workers/worker-onerror-01.html [ Pass Failure ] +crbug.com/943636 virtual/not-omt-sw-fetch/fast/workers/worker-onerror-01.html [ Pass Failure ] # Sheriff 2019-05-27 crbug.com/942411 [ Win ] http/tests/devtools/network/network-search.js [ Pass Timeout ] @@ -6140,3 +6199,5 @@ # Sheriff 2019-06-24 crbug.com/978000 inspector-protocol/page/setWebLifecycleState.js [ Pass Timeout ] + +crbug.com/946700 [ Win ] http/tests/devtools/coverage/decorations-after-script-formatter.js [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index a4f8e0f..620195f 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -642,6 +642,96 @@ "args": ["--enable-features=OffMainThreadDedicatedWorkerScriptFetch,PlzDedicatedWorker,OffMainThreadServiceWorkerScriptFetch,OffMainThreadSharedWorkerScriptFetch"] }, { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/content-security-policy/inside-worker", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/content-security-policy/worker-src", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/fetch/", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/html/browsers/offline/appcache/workers/", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/mixed-content/classic-data-worker-fetch", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/mixed-content/module-data-worker-import", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/mixed-content/module-worker-top-level", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/mixed-content/worker-request", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/referrer-policy", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/resource-timing", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/service-workers", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/upgrade-insecure-requests", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/workers", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "external/wpt/xhr", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "fast/workers", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "http/tests/origin_trials", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "http/tests/security/cors-rfc1918", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch", "--enable-blink-features=CorsRFC1918"] + }, + { + "prefix": "not-omt-sw-fetch", + "base": "http/tests/workers", + "args": ["--disable-features=OffMainThreadServiceWorkerScriptFetch"] + }, + { "prefix": "webrtc-wpt-plan-b", "base": "external/wpt/webrtc", "args": ["--disable-features=RTCUnifiedPlanByDefault"]
diff --git a/third_party/blink/web_tests/http/tests/navigation/xhtml-location-change-crash-expected.txt b/third_party/blink/web_tests/http/tests/navigation/xhtml-location-change-crash-expected.txt new file mode 100644 index 0000000..7ef22e9 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/navigation/xhtml-location-change-crash-expected.txt
@@ -0,0 +1 @@ +PASS
diff --git a/third_party/blink/web_tests/http/tests/navigation/xhtml-location-change-crash.xhtml b/third_party/blink/web_tests/http/tests/navigation/xhtml-location-change-crash.xhtml new file mode 100644 index 0000000..55b079c --- /dev/null +++ b/third_party/blink/web_tests/http/tests/navigation/xhtml-location-change-crash.xhtml
@@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html> +<html lang="fr" xml:lang="fr" xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script type="text/javascript" src="../resources/dummy.js"/> +</head> +<body> +<script type="text/javascript"> +if (window.testRunner) { + testRunner.dumpAsText(); + testRunner.waitUntilDone(); +} +window.location = "resources/pass-and-notify-done.html"; +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/virtual/not-omt-sw-fetch/README.md b/third_party/blink/web_tests/virtual/not-omt-sw-fetch/README.md new file mode 100644 index 0000000..a00c8fe --- /dev/null +++ b/third_party/blink/web_tests/virtual/not-omt-sw-fetch/README.md
@@ -0,0 +1,4 @@ +# virtual/not-omt-sw-fetch + +Fetch toplevel service worker scripts on the main thread. This virtual tests +and `virtual/omt-worker-fetch` contradict each other.
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/get-bounding-client-rect-block-layout.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/get-bounding-client-rect-block-layout.html index f89cdc8d..bbe152d5 100644 --- a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/get-bounding-client-rect-block-layout.html +++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/get-bounding-client-rect-block-layout.html
@@ -74,6 +74,40 @@ t.done(); }, "getBoundingClientRect with re-acquire"); +async_test(async (t) => { + let container = document.createElement("div"); + container.style = "width: 11px; height: 22px;"; + let child = document.createElement("div"); + container.appendChild(child); + document.body.appendChild(container); + + await container.displayLock.acquire({ timeout: Infinity, size: [ACQUIRE_WIDTH, ACQUIRE_HEIGHT] }); + + let rect = container.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, 11, + "Styled locked element uses width from style")); + t.step(() => assert_equals(rect.height, 22, + "Styled locked element uses height from style")); + rect = child.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, 11, + "Child of styled locked element uses width from locked element's style")); + t.step(() => assert_equals(rect.height, 0, + "Child of styled locked element with no content has zero height")); + + container.style = ""; + rect = container.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, BODY_WIDTH, + "Unstyled locked element uses width from body")); + t.step(() => assert_equals(rect.height, ACQUIRE_HEIGHT, + "Unstyled locked element uses height given in acquire()")); + + rect = child.getBoundingClientRect(); + t.step(() => assert_equals(rect.width, BODY_WIDTH, + "Child of unstyled locked element uses width from locked element's width")); + t.step(() => assert_equals(rect.height, 0, + "Child of unstyled locked element with no content has zero height")); + t.done(); +}, "getBoundingClientRect with styled width & height"); </script> </body> </html>
diff --git a/third_party/blink/web_tests/xr/resources/xr-internal-device-mocking.js b/third_party/blink/web_tests/xr/resources/xr-internal-device-mocking.js index 009df5c..fb200746 100644 --- a/third_party/blink/web_tests/xr/resources/xr-internal-device-mocking.js +++ b/third_party/blink/web_tests/xr/resources/xr-internal-device-mocking.js
@@ -232,6 +232,28 @@ this.gamepad_ = null; } + setGamepadButtonCount(button_count) { + this.gamepad_.buttons = []; + for (let i = 0; i < button_count; ++i) { + this.gamepad_.buttons.push(new device.mojom.GamepadButton()); + } + } + + setGamepadAxesCount(axes_count) { + this.gamepad_.axes = []; + for (let i = 0; i < axes_count; ++i) { + this.gamepad_.axes.push(0); + } + } + + setGamepadButtonPressed(button_index, is_pressed) { + this.gamepad_.buttons[button_index].pressed = is_pressed; + } + + setGamepadAxisValue(index, value) { + this.gamepad_.axes[index] = value; + } + getInputSourceState() { let input_state = new device.mojom.XRInputSourceState();
diff --git a/third_party/blink/web_tests/xr/xrInputSource_gamepad_input_registered.html b/third_party/blink/web_tests/xr/xrInputSource_gamepad_input_registered.html new file mode 100644 index 0000000..b321826 --- /dev/null +++ b/third_party/blink/web_tests/xr/xrInputSource_gamepad_input_registered.html
@@ -0,0 +1,110 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> +<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script> +<script src="../external/wpt/resources/chromium/webxr-test.js"></script> +<script src="../external/wpt/webxr/resources/webxr_test_constants.js"></script> +<script src="../xr/resources/xr-internal-device-mocking.js"></script> +<script src="../xr/resources/xr-test-utils.js"></script> +<canvas id="webgl-canvas"></canvas> + +<script> +let testName = "WebXR InputSource's gamepad properly registers input"; + +let fakeDeviceInitParams = { supportsImmersive:true }; + +let requestSessionModes = ['immersive-vr']; + +let testFunction = function(session, t, fakeDeviceController) { + // Need to have a valid pose or input events don't process. + fakeDeviceController.setXRPresentationFrameData(VALID_POSE_MATRIX, [{ + eye:"left", + projectionMatrix: VALID_PROJECTION_MATRIX, + viewMatrix: VALID_VIEW_MATRIX + }, { + eye:"right", + projectionMatrix: VALID_PROJECTION_MATRIX, + viewMatrix: VALID_VIEW_MATRIX + }]); + + // There should only be one input source change event, which is from adding + // the input source at the start of the test. + let inputChangeEvents = 0; + function onInputSourcesChange(event) { + assert_equals(inputChangeEvents, 0, + "Gamepad button or input axis value changes should not fire an input source change event."); + inputChangeEvents++; + } + + session.addEventListener('inputsourceschange', onInputSourcesChange, false); + + // Session must have a baseLayer or frame requests will be ignored. + session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) }); + + // Create our input source and immediately toggle the primary input so that + // it appears as already needing to send a click event when it appears. + let input_source = new MockXRInputSource(); + input_source.connectGamepad(); + input_source.setGamepadButtonCount(1); + input_source.setGamepadAxesCount(2); + fakeDeviceController.addInputSource(input_source); + + let cached_input_source = null; + let cached_gamepad = null; + + function assertSameObjects() { + assert_equals(session.inputSources[0], cached_input_source); + assert_equals(cached_input_source.gamepad, cached_gamepad); + } + + // Input events and gamepad state changes (button presses, axis movements) + // need one frame to propagate, so this does (in order and running a rAF after + // each step): + // 1) Press the mock gamepad's button (so we can verify the button press makes + // its way to the WebXR gamepad and that it does not fire an + // inputsourceschange event). + // 2) Update the mock gamepad's input axes values (so we can verify the + // updated values make their way to the WebXR gamepad and that it does not + // fire an inputsourceschange event). + return new Promise((resolve) => { + session.requestAnimationFrame(() => { + // Make sure the exposed gamepad has the number of buttons and axes we + // requested. + cached_input_source = session.inputSources[0]; + cached_gamepad = cached_input_source.gamepad; + assert_equals(cached_gamepad.buttons.length, 1); + assert_equals(cached_gamepad.axes.length, 2); + // Initially, the button should not be pressed and the axes values should + // be set to 0. + assert_false(cached_gamepad.buttons[0].pressed); + assert_equals(cached_gamepad.axes[0], 0); + assert_equals(cached_gamepad.axes[1], 0); + // Simulate button press. + input_source.setGamepadButtonPressed(0, true); + session.requestAnimationFrame(() => { + // Input source and gamepad should not be re-created. They should be + // updated in place when a button is pressed. + assertSameObjects(); + assert_true(cached_gamepad.buttons[0].pressed); + // Simulate input axes movement. + input_source.setGamepadAxisValue(0, 0.5); + input_source.setGamepadAxisValue(1, -0.5); + session.requestAnimationFrame(() => { + // Input source and gamepad should not be re-created. They should be + // updated in place when input axes values change. + assertSameObjects(); + assert_equals(cached_gamepad.axes[0], 0.5); + assert_equals(cached_gamepad.axes[1], -0.5); + // Button that was pressed last frame should still be pressed. + assert_true(cached_gamepad.buttons[0].pressed); + resolve(); + }); + }); + }); + }); +}; + +xr_session_promise_test( + testFunction, fakeDeviceInitParams, requestSessionModes, testName); +</script>
diff --git a/third_party/libsync/OWNERS b/third_party/libsync/OWNERS index fe51e0c..c21539f 100644 --- a/third_party/libsync/OWNERS +++ b/third_party/libsync/OWNERS
@@ -1,2 +1,3 @@ -reveman@chromium.org +dcastagna@chromium.org +dnicoara@chromium.org piman@chromium.org
diff --git a/tools/mb/mb.py b/tools/mb/mb.py index fcec84e..f1c828a 100755 --- a/tools/mb/mb.py +++ b/tools/mb/mb.py
@@ -1240,6 +1240,7 @@ '../../testing/test_env.py', os.path.join('bin', 'run_%s' % target), '--test-launcher-bot-mode', + '--system-log-file', '${ISOLATED_OUTDIR}/system_log' ] elif is_simplechrome and test_type != 'script': cmdline = [
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 8b4eee8..3e0ef62 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -6248,11 +6248,6 @@ <int value="1" label="Present"/> </enum> -<enum name="BooleanProcessReuseDisallowed"> - <int value="0" label="Process reuse allowed"/> - <int value="1" label="Process reuse disallowed"/> -</enum> - <enum name="BooleanProfileSignedIn"> <int value="0" label="Profile was not Signed In"/> <int value="1" label="Profile was Signed In"/> @@ -23719,6 +23714,11 @@ <int value="2929" label="PageLifecycleTransitionsOptOut"/> <int value="2930" label="PeriodicBackgroundSync"/> <int value="2931" label="PeriodicBackgroundSyncRegister"/> + <int value="2932" label="LazyLoadFrameLoadingAttributeEager"/> + <int value="2933" label="LazyLoadFrameLoadingAttributeLazy"/> + <int value="2934" label="LazyLoadImageLoadingAttributeEager"/> + <int value="2935" label="LazyLoadImageLoadingAttributeLazy"/> + <int value="2936" label="LazyLoadImageMissingDimensionsForLazy"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -29682,9 +29682,6 @@ <int value="15" label="OpenCleanupBlobJournalFailed"> Open failed because the blob journal could not be cleaned up. </int> - <int value="16" label="OpenFailedMetadataSetup"> - Open failed because the backing store's metadata could not be set up. - </int> </enum> <enum name="IdleDeadlineCallbackType"> @@ -33592,6 +33589,8 @@ <int value="-1847835522" label="disable-touch-adjustment"/> <int value="-1847776781" label="enable-loading-ipc-optimization-for-small-resources"/> + <int value="-1846471618" + label="enable-experimental-accessibility-switch-access-text"/> <int value="-1844754731" label="Mash:disabled"/> <int value="-1840608422" label="AdvancedPpdAttributes:disabled"/> <int value="-1839874877" label="WebXROrientationSensorDevice:enabled"/> @@ -34048,8 +34047,10 @@ <int value="-1208501269" label="AutofillScanThemeDialog:enabled"/> <int value="-1206875404" label="EnableIncognitoWindowCounter:enabled"/> <int value="-1206698676" label="MacV2Sandbox:disabled"/> + <int value="-1206524306" label="EnableAuraTooltipsOnWindows:disabled"/> <int value="-1206337150" label="OmniboxUIExperimentHideSuggestionUrlScheme:disabled"/> + <int value="-1205076560" label="EnableSearchBoxSelection:disabled"/> <int value="-1203955801" label="enable-password-change-support:disabled"/> <int value="-1203742042" label="enable-gesture-selection"/> <int value="-1201741587" label="DataReductionProxyDecidesTransform:disabled"/> @@ -34227,6 +34228,7 @@ <int value="-965842218" label="MultiDeviceApi:disabled"/> <int value="-964676765" label="enable-accelerated-mjpeg-decode"/> <int value="-962030536" label="ChromeDuetLabeled:enabled"/> + <int value="-960077963" label="EnableAuraTooltipsOnWindows:enabled"/> <int value="-957200826" label="enable-spdy-proxy-auth"/> <int value="-956696029" label="scheduler-configuration"/> <int value="-951394314" label="top-chrome-md"/> @@ -34278,6 +34280,7 @@ <int value="-874602599" label="HorizontalTabSwitcherAndroid:enabled"/> <int value="-872764392" label="ContextualSuggestionsBottomSheet:disabled"/> <int value="-872302695" label="PeriodicBackgroundSync:enabled"/> + <int value="-870120067" label="EnableSearchBoxSelection:enabled"/> <int value="-867087281" label="enable-virtual-keyboard"/> <int value="-866993841" label="OfflinePagesCTV2:disabled"/> <int value="-864266073" label="cros-regions-mode"/> @@ -47713,6 +47716,8 @@ <int value="5" label="NoScript"/> <int value="6" label="Unspecified"/> <int value="7" label="ResourceLoadingHints"/> + <int value="8" label="LitePageRedirect"/> + <int value="9" label="DeferAllScript"/> </enum> <enum name="PreviewsUserOmniboxAction">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index d7a0d64..2ea4e86 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -29942,7 +29942,7 @@ </histogram> <histogram name="Download.IOSDownloadReplaced" enum="BooleanReplaced" - expires_after="M77"> + expires_after="M84"> <owner>eugenebut@chromium.org</owner> <summary> The user discarded in-progress download and replaced with the new one. Only @@ -29953,7 +29953,7 @@ </histogram> <histogram name="Download.IOSPresentAddPassesDialogResult" - enum="PresentAddPassesDialogResult" expires_after="M77"> + enum="PresentAddPassesDialogResult" expires_after="M84"> <owner>eugenebut@chromium.org</owner> <summary>Result of an attempt to present Add Passes dialog on iOS.</summary> </histogram> @@ -72057,7 +72057,7 @@ </histogram> <histogram name="Net.QuicSession.ClosedByRtoAtClient.ReceivedPacketCount" - units="packets" expires_after="2019-07-01"> + units="packets" expires_after="2020-01-15"> <owner>wub@chromium.org</owner> <owner>fayang@chromium.org</owner> <summary> @@ -72067,7 +72067,7 @@ </histogram> <histogram name="Net.QuicSession.ClosedByRtoAtClient.SentPacketCount" - units="packets" expires_after="2019-07-01"> + units="packets" expires_after="2020-01-15"> <owner>wub@chromium.org</owner> <owner>fayang@chromium.org</owner> <summary> @@ -123487,20 +123487,6 @@ </summary> </histogram> -<histogram name="SiteIsolation.PendingSitelessNavigationDisallowsProcessReuse" - enum="BooleanProcessReuseDisallowed" expires_after="M82"> - <owner>alexmos@chromium.org</owner> - <owner>creis@chromium.org</owner> - <owner>site-isolation-dev@chromium.org</owner> - <summary> - Whether or not the RenderProcessHost is disqualified from process reuse - because it has a pending navigation to a URL for which SiteInstance does not - assign a site URL, such as chrome-native://newtab. This is intended to - measure how often this scenario results in spinning up extra processes. - Measured once per IsSuitableHost() invocation. - </summary> -</histogram> - <histogram name="SiteIsolation.ProxyCount"> <owner>creis@chromium.org</owner> <owner>lukasza@chromium.org</owner>
diff --git a/ui/accessibility/accessibility_switches.cc b/ui/accessibility/accessibility_switches.cc index e96dd18..563912d 100644 --- a/ui/accessibility/accessibility_switches.cc +++ b/ui/accessibility/accessibility_switches.cc
@@ -32,6 +32,10 @@ const char kEnableExperimentalAccessibilitySwitchAccess[] = "enable-experimental-accessibility-switch-access"; +// Enables in progress Switch Access features for text input. +const char kEnableExperimentalAccessibilitySwitchAccessText[] = + "enable-experimental-accessibility-switch-access-text"; + // Enables language switching feature that hasn't launched yet. const char kEnableExperimentalAccessibilityChromeVoxLanguageSwitching[] = "enable-experimental-accessibility-chromevox-language-switching";
diff --git a/ui/accessibility/accessibility_switches.h b/ui/accessibility/accessibility_switches.h index 159a0ad..831e5df 100644 --- a/ui/accessibility/accessibility_switches.h +++ b/ui/accessibility/accessibility_switches.h
@@ -16,6 +16,7 @@ AX_EXPORT extern const char kEnableExperimentalAccessibilityLabelsDebugging[]; AX_EXPORT extern const char kEnableExperimentalAccessibilityLanguageDetection[]; AX_EXPORT extern const char kEnableExperimentalAccessibilitySwitchAccess[]; +AX_EXPORT extern const char kEnableExperimentalAccessibilitySwitchAccessText[]; AX_EXPORT extern const char kEnableExperimentalAccessibilityChromeVoxLanguageSwitching[]; AX_EXPORT extern const char
diff --git a/ui/base/models/tree_node_iterator.h b/ui/base/models/tree_node_iterator.h index 755a8a3..dda10c96 100644 --- a/ui/base/models/tree_node_iterator.h +++ b/ui/base/models/tree_node_iterator.h
@@ -30,23 +30,22 @@ // its descendants will be skipped by the iterator. TreeNodeIterator(NodeType* node, const PruneCallback& prune) : prune_(prune) { - int index = 0; - // Move forward through the children list until the first non prunable node. // This is to satisfy the iterator invariant that the current index in the // Position at the top of the _positions list must point to a node the // iterator will be returning. - for (; index < node->child_count(); ++index) - if (prune.is_null() || !prune.Run(node->GetChild(index))) - break; - - if (index < node->child_count()) - positions_.push(Position<NodeType>(node, index)); + const auto i = + std::find_if(node->children().cbegin(), node->children().cend(), + [prune](const auto& child) { + return prune.is_null() || !prune.Run(child.get()); + }); + if (i != node->children().cend()) + positions_.emplace(node, i - node->children().cbegin()); } explicit TreeNodeIterator(NodeType* node) { if (!node->children().empty()) - positions_.push(Position<NodeType>(node, 0)); + positions_.emplace(node, 0); } // Returns true if there are more descendants. @@ -54,30 +53,29 @@ // Returns the next descendant. NodeType* Next() { - if (!has_next()) { - NOTREACHED(); - return nullptr; - } + DCHECK(has_next()); // There must always be a valid node in the current Position index. - NodeType* result = positions_.top().node->GetChild(positions_.top().index); + NodeType* result = + positions_.top().node->children()[positions_.top().index].get(); // Make sure we don't attempt to visit result again. - positions_.top().index++; + ++positions_.top().index; // Iterate over result's children. - positions_.push(Position<NodeType>(result, 0)); + positions_.emplace(result, 0); // Advance to next valid node by skipping over the pruned nodes and the // empty Positions. At the end of this loop two cases are possible: // - the current index of the top() Position points to a valid node // - the _position list is empty, the iterator has_next() will return false. while (!positions_.empty()) { - if (positions_.top().index >= positions_.top().node->child_count()) + auto& top = positions_.top(); + if (top.index >= top.node->children().size()) positions_.pop(); // This Position is all processed, move to the next. else if (!prune_.is_null() && - prune_.Run(positions_.top().node->GetChild(positions_.top().index))) - positions_.top().index++; // Prune the branch. + prune_.Run(top.node->children()[top.index].get())) + ++top.index; // Prune the branch. else break; // Now positioned at the next node to be returned. } @@ -88,11 +86,10 @@ private: template <class PositionNodeType> struct Position { - Position(PositionNodeType* node, int index) : node(node), index(index) {} - Position() : node(nullptr), index(-1) {} + Position(PositionNodeType* node, size_t index) : node(node), index(index) {} PositionNodeType* node; - int index; + size_t index; }; base::stack<Position<NodeType>> positions_;
diff --git a/ui/base/models/tree_node_model.h b/ui/base/models/tree_node_model.h index 90c7b31f..4224f77 100644 --- a/ui/base/models/tree_node_model.h +++ b/ui/base/models/tree_node_model.h
@@ -123,10 +123,6 @@ const TreeNodes& children() const { return children_; } - // Returns the number of children. - // TODO(https://crbug.com/956419): Remove; use children().size(). - int child_count() const { return static_cast<int>(children_.size()); } - // Returns the number of all nodes in the subtree rooted at this node, // including this node. int GetTotalNodeCount() const {
diff --git a/ui/base/models/tree_node_model_unittest.cc b/ui/base/models/tree_node_model_unittest.cc index 351096f..2b9418cf 100644 --- a/ui/base/models/tree_node_model_unittest.cc +++ b/ui/base/models/tree_node_model_unittest.cc
@@ -81,9 +81,9 @@ EXPECT_EQ("added=1 removed=0 changed=0", GetObserverCountStateAndClear()); - EXPECT_EQ(2, root->child_count()); - EXPECT_EQ(2, child1->child_count()); - EXPECT_EQ(0, child2->child_count()); + EXPECT_EQ(2u, root->children().size()); + EXPECT_EQ(2u, child1->children().size()); + EXPECT_EQ(0u, child2->children().size()); } // Verifies if the model is properly removing a node from the tree @@ -129,14 +129,14 @@ for (size_t i = 0; i < 3; ++i) foo->Add(std::make_unique<TestNode>(), i); // bar[n] - EXPECT_EQ(3, root.child_count()); - EXPECT_EQ(1, child1->child_count()); - EXPECT_EQ(3, foo->child_count()); + EXPECT_EQ(3u, root.children().size()); + EXPECT_EQ(1u, child1->children().size()); + EXPECT_EQ(3u, foo->children().size()); // Now remove the child nodes from root. root.DeleteAll(); - EXPECT_EQ(0, root.child_count()); + EXPECT_EQ(0u, root.children().size()); EXPECT_TRUE(root.children().empty()); } @@ -259,22 +259,22 @@ TEST_F(TreeNodeModelTest, BasicOperations) { TestNode root; - EXPECT_EQ(0, root.child_count()); + EXPECT_EQ(0u, root.children().size()); TestNode* child1 = root.Add(std::make_unique<TestNode>()); - EXPECT_EQ(1, root.child_count()); + EXPECT_EQ(1u, root.children().size()); EXPECT_EQ(&root, child1->parent()); TestNode* child2 = root.Add(std::make_unique<TestNode>()); - EXPECT_EQ(2, root.child_count()); + EXPECT_EQ(2u, root.children().size()); EXPECT_EQ(child1->parent(), child2->parent()); std::unique_ptr<TestNode> c2 = root.Remove(1); - EXPECT_EQ(1, root.child_count()); + EXPECT_EQ(1u, root.children().size()); EXPECT_EQ(NULL, child2->parent()); std::unique_ptr<TestNode> c1 = root.Remove(0); - EXPECT_EQ(0, root.child_count()); + EXPECT_EQ(0u, root.children().size()); } TEST_F(TreeNodeModelTest, IsRoot) {
diff --git a/ui/chromeos/ime/candidate_view_unittest.cc b/ui/chromeos/ime/candidate_view_unittest.cc index 39cacf3..730bb38f 100644 --- a/ui/chromeos/ime/candidate_view_unittest.cc +++ b/ui/chromeos/ime/candidate_view_unittest.cc
@@ -45,8 +45,8 @@ init_params.delegate = new views::WidgetDelegateView(); container_ = init_params.delegate->GetContentsView(); - container_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + container_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); for (size_t i = 0; i < base::size(kDummyCandidates); ++i) { CandidateView* candidate = new CandidateView( this, ui::CandidateWindow::VERTICAL);
diff --git a/ui/chromeos/ime/candidate_window_view.cc b/ui/chromeos/ime/candidate_window_view.cc index c945c12..b2661fb 100644 --- a/ui/chromeos/ime/candidate_window_view.cc +++ b/ui/chromeos/ime/candidate_window_view.cc
@@ -160,8 +160,8 @@ 1, GetNativeTheme()->GetSystemColor( ui::NativeTheme::kColorId_MenuBorderColor))); - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); auxiliary_text_ = new InformationTextArea(gfx::ALIGN_RIGHT, 0); preedit_ = new InformationTextArea(gfx::ALIGN_LEFT, kMinPreeditAreaWidth); candidate_area_ = new views::View; @@ -174,16 +174,16 @@ AddChildView(candidate_area_); AddChildView(auxiliary_text_); auxiliary_text_->SetBorderFromPosition(InformationTextArea::TOP); - candidate_area_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + candidate_area_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); } else { AddChildView(preedit_); AddChildView(auxiliary_text_); AddChildView(candidate_area_); auxiliary_text_->SetAlignment(gfx::ALIGN_LEFT); auxiliary_text_->SetBorderFromPosition(InformationTextArea::BOTTOM); - candidate_area_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + candidate_area_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); } } @@ -248,14 +248,14 @@ ReorderChildView(auxiliary_text_, -1); auxiliary_text_->SetAlignment(gfx::ALIGN_RIGHT); auxiliary_text_->SetBorderFromPosition(InformationTextArea::TOP); - candidate_area_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + candidate_area_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); } else { ReorderChildView(auxiliary_text_, 1); auxiliary_text_->SetAlignment(gfx::ALIGN_LEFT); auxiliary_text_->SetBorderFromPosition(InformationTextArea::BOTTOM); - candidate_area_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + candidate_area_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); } }
diff --git a/ui/chromeos/ime/infolist_window.cc b/ui/chromeos/ime/infolist_window.cc index 3bb181b..e72755a8 100644 --- a/ui/chromeos/ime/infolist_window.cc +++ b/ui/chromeos/ime/infolist_window.cc
@@ -114,8 +114,8 @@ const gfx::FontList& title_font_list, const gfx::FontList& description_font_list) : entry_(entry) { - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); title_label_ = new views::Label(entry.title, {title_font_list}); title_label_->SetPosition(gfx::Point(0, 0)); @@ -183,8 +183,8 @@ 1, GetNativeTheme()->GetSystemColor( ui::NativeTheme::kColorId_MenuBorderColor))); - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); views::Label* caption_label = new views::Label( l10n_util::GetStringUTF16(IDS_CHROMEOS_IME_INFOLIST_WINDOW_TITLE));
diff --git a/ui/chromeos/search_box/search_box_view_base.cc b/ui/chromeos/search_box/search_box_view_base.cc index eefe02e..aba1059 100644 --- a/ui/chromeos/search_box/search_box_view_base.cc +++ b/ui/chromeos/search_box/search_box_view_base.cc
@@ -252,7 +252,7 @@ box_layout_ = content_container_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(0, kPadding), + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(0, kPadding), kInnerPadding - views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_TEXTFIELD_HORIZONTAL_TEXT_PADDING)));
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index 144541e..2326c3b 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -1431,7 +1431,7 @@ #list-container list > li.accepts, #list-container list:focus > li[lead], #default-tasks-list > li[selected] { - background-color: rgb(232, 232, 232); + background-color: rgb(232, 234, 237); } #list-container list:focus > li[selected], @@ -1441,12 +1441,12 @@ background-color: rgb(216, 223, 240); } -body.check-select #list-container list > li[lead], +body.check-select #list-container list > li[lead]:not([selected]), #list-container list > li[lead]:not([selected]) { background-color: rgba(232, 234, 237, 0.5); } -body.check-select #list-container list:focus > li[lead], +body.check-select #list-container list:focus > li[lead]:not([selected]), #list-container list > li[lead]:not([selected]):focus { background-color: rgb(232, 234, 237); }
diff --git a/ui/gl/gl_image_dxgi_swap_chain.cc b/ui/gl/gl_image_dxgi_swap_chain.cc index 08b1cc7..0ace826 100644 --- a/ui/gl/gl_image_dxgi_swap_chain.cc +++ b/ui/gl/gl_image_dxgi_swap_chain.cc
@@ -7,28 +7,15 @@ #include "ui/gl/egl_util.h" #include "ui/gl/gl_bindings.h" -#ifndef EGL_ANGLE_d3d_texture_client_buffer -#define EGL_ANGLE_d3d_texture_client_buffer 1 -#define EGL_D3D_TEXTURE_ANGLE 0x33A3 -#endif /* EGL_ANGLE_d3d_texture_client_buffer */ +#ifndef EGL_ANGLE_image_d3d11_texture +#define EGL_D3D11_TEXTURE_ANGLE 0x3484 +#endif /* EGL_ANGLE_image_d3d11_texture */ namespace gl { namespace { -bool SwapChainSupportedBindFormat(gfx::BufferFormat format) { - switch (format) { - case gfx::BufferFormat::RGBA_8888: - case gfx::BufferFormat::RGBX_8888: - case gfx::BufferFormat::RGBA_F16: - return true; - default: - return false; - }; -} - bool SwapChainHasAlpha(gfx::BufferFormat format) { - DCHECK(SwapChainSupportedBindFormat(format)); switch (format) { case gfx::BufferFormat::RGBA_8888: case gfx::BufferFormat::RGBA_F16: @@ -41,94 +28,6 @@ }; } -EGLConfig ChooseCompatibleConfig(gfx::BufferFormat format, EGLDisplay display) { - DCHECK(SwapChainSupportedBindFormat(format)); - - const EGLint color_bits = format == gfx::BufferFormat::RGBA_F16 ? 16 : 8; - const EGLint buffer_bind_to_texture = SwapChainHasAlpha(format) - ? EGL_BIND_TO_TEXTURE_RGBA - : EGL_BIND_TO_TEXTURE_RGB; - const EGLint buffer_size = - color_bits * 3 + (SwapChainHasAlpha(format) ? color_bits : 0); - - std::vector<EGLint> attrib_list = { - EGL_RED_SIZE, color_bits, EGL_GREEN_SIZE, color_bits, - EGL_BLUE_SIZE, color_bits, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, - buffer_bind_to_texture, EGL_TRUE, EGL_BUFFER_SIZE, buffer_size}; - // It is assumed that EGL_EXT_pixel_format_float extension is supported by - // ANGLE. - if (format == gfx::BufferFormat::RGBA_F16) { - attrib_list.push_back(EGL_COLOR_COMPONENT_TYPE_EXT); - attrib_list.push_back(EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT); - } - attrib_list.push_back(EGL_NONE); - - EGLint num_config = 0; - EGLBoolean result = - eglChooseConfig(display, attrib_list.data(), nullptr, 0, &num_config); - if (result != EGL_TRUE) - return nullptr; - std::vector<EGLConfig> all_configs(num_config); - result = eglChooseConfig(display, attrib_list.data(), all_configs.data(), - num_config, &num_config); - if (result != EGL_TRUE) - return nullptr; - for (EGLConfig config : all_configs) { - EGLint bits = 0; - // Ensures that the config chosen has requested number of bits. - if (!eglGetConfigAttrib(display, config, EGL_RED_SIZE, &bits) || - bits != color_bits) { - continue; - } - - if (!eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &bits) || - bits != color_bits) { - continue; - } - - if (!eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &bits) || - bits != color_bits) { - continue; - } - - if (SwapChainHasAlpha(format) && - (!eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &bits) || - bits != color_bits)) { - continue; - } - - return config; - } - return nullptr; -} - -EGLSurface CreatePbuffer(const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture, - gfx::BufferFormat format, - EGLConfig config, - EGLDisplay display, - unsigned target) { - DCHECK(SwapChainSupportedBindFormat(format)); - - D3D11_TEXTURE2D_DESC desc; - texture->GetDesc(&desc); - EGLint width = desc.Width; - EGLint height = desc.Height; - - EGLint pBufferAttributes[] = { - EGL_WIDTH, - width, - EGL_HEIGHT, - height, - EGL_TEXTURE_TARGET, - EGL_TEXTURE_2D, - EGL_TEXTURE_FORMAT, - SwapChainHasAlpha(format) ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB, - EGL_NONE}; - - return eglCreatePbufferFromClientBuffer( - display, EGL_D3D_TEXTURE_ANGLE, texture.Get(), config, pBufferAttributes); -} - } // anonymous namespace GLImageDXGISwapChain::GLImageDXGISwapChain( @@ -136,38 +35,29 @@ gfx::BufferFormat buffer_format, Microsoft::WRL::ComPtr<ID3D11Texture2D> texture, Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain) - : size_(size), + : GLImageEGL(size), buffer_format_(buffer_format), texture_(texture), - swap_chain_(swap_chain), - display_(eglGetCurrentDisplay()), - config_(ChooseCompatibleConfig(buffer_format, display_)) { + swap_chain_(swap_chain) { DCHECK(texture_); DCHECK(swap_chain_); - DCHECK(config_); } -GLImage::BindOrCopy GLImageDXGISwapChain::ShouldBindOrCopy() { - return BIND; +// static +GLImageDXGISwapChain* GLImageDXGISwapChain::FromGLImage(GLImage* image) { + if (!image || image->GetType() != Type::DXGI_SWAP_CHAIN) + return nullptr; + return static_cast<GLImageDXGISwapChain*>(image); } -bool GLImageDXGISwapChain::BindTexImage(unsigned target) { - DestroySurface(); +bool GLImageDXGISwapChain::Initialize() { DCHECK(texture_); - DCHECK_EQ(surface_, EGL_NO_SURFACE); - DCHECK(config_); - surface_ = CreatePbuffer(texture_, buffer_format_, config_, display_, target); - if (surface_ == EGL_NO_SURFACE) { - DLOG(ERROR) << "eglCreatePbufferSurface failed with error " - << ui::GetLastEGLErrorString(); - return false; - } - - return eglBindTexImage(display_, surface_, EGL_BACK_BUFFER) == EGL_TRUE; + const EGLint attribs[] = {EGL_NONE}; + return GLImageEGL::Initialize(EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE, + static_cast<EGLClientBuffer>(texture_.Get()), + attribs); } -void GLImageDXGISwapChain::ReleaseTexImage(unsigned target) {} - bool GLImageDXGISwapChain::CopyTexImage(unsigned target) { return false; } @@ -184,10 +74,6 @@ return SwapChainHasAlpha(buffer_format_) ? GL_RGBA : GL_RGB; } -gfx::Size GLImageDXGISwapChain::GetSize() { - return size_; -} - void GLImageDXGISwapChain::OnMemoryDump( base::trace_event::ProcessMemoryDump* pmd, uint64_t process_tracing_id, @@ -209,18 +95,6 @@ return false; } -void GLImageDXGISwapChain::DestroySurface() { - if (surface_ != EGL_NO_SURFACE) { - if (!eglDestroySurface(display_, surface_)) { - DLOG(ERROR) << "eglDestroySurface failed with error " - << ui::GetLastEGLErrorString(); - } - surface_ = EGL_NO_SURFACE; - } -} - -GLImageDXGISwapChain::~GLImageDXGISwapChain() { - DestroySurface(); -} +GLImageDXGISwapChain::~GLImageDXGISwapChain() {} } // namespace gl
diff --git a/ui/gl/gl_image_dxgi_swap_chain.h b/ui/gl/gl_image_dxgi_swap_chain.h index af9c93f..4a2f67f3 100644 --- a/ui/gl/gl_image_dxgi_swap_chain.h +++ b/ui/gl/gl_image_dxgi_swap_chain.h
@@ -11,31 +11,30 @@ #include <wrl/client.h> #include "ui/gfx/buffer_types.h" -#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_export.h" -#include "ui/gl/gl_image.h" +#include "ui/gl/gl_image_egl.h" namespace gl { -class GL_EXPORT GLImageDXGISwapChain : public gl::GLImage { +class GL_EXPORT GLImageDXGISwapChain : public gl::GLImageEGL { public: GLImageDXGISwapChain(const gfx::Size& size, gfx::BufferFormat buffer_format, Microsoft::WRL::ComPtr<ID3D11Texture2D> texture, Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain); + // Safe downcast. Returns nullptr on failure. + static GLImageDXGISwapChain* FromGLImage(GLImage* image); + + bool Initialize(); + // GLImage implementation - BindOrCopy ShouldBindOrCopy() override; - // Destroys surface(if present), and binds image to new pixel buffer surface. - bool BindTexImage(unsigned target) override; - void ReleaseTexImage(unsigned target) override; bool CopyTexImage(unsigned target) override; bool CopyTexSubImage(unsigned target, const gfx::Point& offset, const gfx::Rect& rect) override; void Flush() override; unsigned GetInternalFormat() override; - gfx::Size GetSize() override; Type GetType() const override; void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, uint64_t process_tracing_id, @@ -48,22 +47,19 @@ bool enable_blend, std::unique_ptr<gfx::GpuFence> gpu_fence) override; - Microsoft::WRL::ComPtr<ID3D11Texture2D> texture() { return texture_; } + const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture() { return texture_; } + const Microsoft::WRL::ComPtr<IDXGISwapChain1>& swap_chain() { + return swap_chain_; + } protected: ~GLImageDXGISwapChain() override; private: - void DestroySurface(); - - const gfx::Size size_; const gfx::BufferFormat buffer_format_; - EGLSurface surface_ = nullptr; Microsoft::WRL::ComPtr<ID3D11Texture2D> texture_; // Required by Direct composition surface to pass swap chain handle to OS. Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain_; - const EGLDisplay display_; - const EGLConfig config_; DISALLOW_COPY_AND_ASSIGN(GLImageDXGISwapChain); };
diff --git a/ui/message_center/views/notification_button.cc b/ui/message_center/views/notification_button.cc index a015edd..50b70d13 100644 --- a/ui/message_center/views/notification_button.cc +++ b/ui/message_center/views/notification_button.cc
@@ -24,8 +24,8 @@ SetBackground(views::CreateSolidBackground(kNotificationBackgroundColor)); set_notify_enter_exit_on_child(true); SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(0, kButtonHorizontalPadding), - kButtonIconToTitlePadding)); + views::BoxLayout::Orientation::kHorizontal, + gfx::Insets(0, kButtonHorizontalPadding), kButtonIconToTitlePadding)); SetFocusPainter(views::Painter::CreateSolidFocusPainter( kFocusBorderColor, gfx::Insets(1, 2, 2, 2))); }
diff --git a/ui/message_center/views/notification_control_buttons_view.cc b/ui/message_center/views/notification_control_buttons_view.cc index 09dff69..69b1fba 100644 --- a/ui/message_center/views/notification_control_buttons_view.cc +++ b/ui/message_center/views/notification_control_buttons_view.cc
@@ -28,8 +28,8 @@ MessageView* message_view) : message_view_(message_view) { DCHECK(message_view); - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); // Use layer to change the opacity. SetPaintToLayer();
diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc index c6e5f35..283cb25 100644 --- a/ui/message_center/views/notification_view_md.cc +++ b/ui/message_center/views/notification_view_md.cc
@@ -176,7 +176,7 @@ std::unique_ptr<views::View> CreateItemView(const NotificationItem& item) { auto view = std::make_unique<views::View>(); view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), 0)); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), 0)); const gfx::FontList font_list = GetTextFontList(); @@ -383,7 +383,7 @@ textfield_(new views::Textfield()), button_(new views::ImageButton(this)) { auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), 0)); + views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), 0)); SetBackground(views::CreateSolidBackground(kActionsRowBackgroundColor)); SetInkDropMode(InkDropMode::ON); @@ -533,7 +533,7 @@ : MessageView(notification), ink_drop_container_(new views::InkDropContainerView()) { SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), 0)); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), 0)); set_ink_drop_visible_opacity(1); @@ -554,7 +554,7 @@ content_row_ = new views::View(); auto* content_row_layout = content_row_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, kContentRowPadding, 0)); + views::BoxLayout::Orientation::kHorizontal, kContentRowPadding, 0)); content_row_layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStart); AddChildView(content_row_); @@ -562,7 +562,7 @@ // |left_content_| contains most contents like title, message, etc... left_content_ = new views::View(); left_content_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), 0)); + views::BoxLayout::Orientation::kVertical, gfx::Insets(), 0)); left_content_->SetBorder(views::CreateEmptyBorder(kLeftContentPadding)); content_row_->AddChildView(left_content_); content_row_layout->SetFlexForView(left_content_, 1); @@ -581,7 +581,7 @@ // |action_buttons_row_| contains inline action buttons. action_buttons_row_ = new views::View(); action_buttons_row_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, kActionsRowPadding, + views::BoxLayout::Orientation::kHorizontal, kActionsRowPadding, kActionsRowHorizontalSpacing)); action_buttons_row_->SetVisible(false); actions_row_->AddChildView(action_buttons_row_); @@ -1131,7 +1131,7 @@ // |settings_row_| contains inline settings. settings_row_ = new views::View(); settings_row_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, kSettingsRowPadding, 0)); + views::BoxLayout::Orientation::kVertical, kSettingsRowPadding, 0)); int block_notifications_message_id = 0; switch (notification.notifier_id().type) { @@ -1174,7 +1174,7 @@ auto* settings_button_row = new views::View; auto settings_button_layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, kSettingsButtonRowPadding, 0); + views::BoxLayout::Orientation::kHorizontal, kSettingsButtonRowPadding, 0); settings_button_layout->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kEnd); settings_button_row->SetLayoutManager(std::move(settings_button_layout));
diff --git a/ui/native_theme/native_theme_win.cc b/ui/native_theme/native_theme_win.cc index 0e10023..e74d07035 100644 --- a/ui/native_theme/native_theme_win.cc +++ b/ui/native_theme/native_theme_win.cc
@@ -502,9 +502,9 @@ // Tooltip case kColorId_TooltipBackground: + return system_colors_[COLOR_WINDOW]; case kColorId_TooltipText: - NOTREACHED(); - return gfx::kPlaceholderColor; + return system_colors_[COLOR_WINDOWTEXT]; // Tree // NOTE: these aren't right for all themes, but as close as I could get.
diff --git a/ui/views/bubble/footnote_container_view.cc b/ui/views/bubble/footnote_container_view.cc index b4ab1985..835ba7f 100644 --- a/ui/views/bubble/footnote_container_view.cc +++ b/ui/views/bubble/footnote_container_view.cc
@@ -51,8 +51,8 @@ FootnoteContainerView::FootnoteContainerView(const gfx::Insets& margins, std::unique_ptr<View> child_view, float corner_radius) { - SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical, margins, 0)); + SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kVertical, margins, 0)); SetCornerRadius(corner_radius); SetBorder(CreateSolidSidedBorder(1, 0, 0, 0, GetNativeTheme()->SystemDarkModeEnabled()
diff --git a/ui/views/color_chooser/color_chooser_view.cc b/ui/views/color_chooser/color_chooser_view.cc index f59734e..3427ed0d 100644 --- a/ui/views/color_chooser/color_chooser_view.cc +++ b/ui/views/color_chooser/color_chooser_view.cc
@@ -369,12 +369,13 @@ DCHECK(listener_); SetBackground(CreateSolidBackground(SK_ColorLTGRAY)); - SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kVertical, gfx::Insets(kMarginWidth), kMarginWidth)); + SetLayoutManager( + std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical, + gfx::Insets(kMarginWidth), kMarginWidth)); auto container = std::make_unique<View>(); container->SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kHorizontal, gfx::Insets(), kMarginWidth)); + BoxLayout::Orientation::kHorizontal, gfx::Insets(), kMarginWidth)); saturation_value_ = container->AddChildView(std::make_unique<SaturationValueView>(this)); hue_ = container->AddChildView(std::make_unique<HueView>(this));
diff --git a/ui/views/controls/image_view_unittest.cc b/ui/views/controls/image_view_unittest.cc index 1ff073b..f5b69ab8 100644 --- a/ui/views/controls/image_view_unittest.cc +++ b/ui/views/controls/image_view_unittest.cc
@@ -51,9 +51,9 @@ widget_.Init(params); View* container = new View(); // Make sure children can take up exactly as much space as they require. - BoxLayout::Orientation orientation = GetParam() == Axis::kHorizontal - ? BoxLayout::kHorizontal - : BoxLayout::kVertical; + BoxLayout::Orientation orientation = + GetParam() == Axis::kHorizontal ? BoxLayout::Orientation::kHorizontal + : BoxLayout::Orientation::kVertical; container->SetLayoutManager(std::make_unique<BoxLayout>(orientation)); widget_.SetContentsView(container);
diff --git a/ui/views/controls/message_box_view.cc b/ui/views/controls/message_box_view.cc index 6c0b2c9..a5f60ec0 100644 --- a/ui/views/controls/message_box_view.cc +++ b/ui/views/controls/message_box_view.cc
@@ -185,8 +185,8 @@ // We explicitly set insets on the message contents instead of the scroll view // so that the scroll view borders are not capped by dialog insets. message_contents->SetBorder(CreateEmptyBorder(GetHorizontalInsets(provider))); - message_contents->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + message_contents->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); auto add_label = [&message_contents, this]( const base::string16& text, bool multi_line, gfx::HorizontalAlignment alignment) {
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.cc b/ui/views/controls/tabbed_pane/tabbed_pane.cc index 758ef6c..a367c86 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -437,14 +437,15 @@ if (orientation == TabbedPane::Orientation::kHorizontal) { constexpr int kTabStripLeadingEdgePadding = 9; layout = std::make_unique<BoxLayout>( - BoxLayout::kHorizontal, gfx::Insets(0, kTabStripLeadingEdgePadding)); + BoxLayout::Orientation::kHorizontal, + gfx::Insets(0, kTabStripLeadingEdgePadding)); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kEnd); } else { constexpr int kTabStripEdgePadding = 8; constexpr int kTabSpacing = 8; layout = std::make_unique<BoxLayout>( - BoxLayout::kVertical, gfx::Insets(kTabStripEdgePadding, 0, 0, 0), - kTabSpacing); + BoxLayout::Orientation::kVertical, + gfx::Insets(kTabStripEdgePadding, 0, 0, 0), kTabSpacing); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStart); } layout->set_main_axis_alignment(BoxLayout::MainAxisAlignment::kStart); @@ -561,7 +562,8 @@ TabbedPane::TabStripStyle style) : TabStrip(orientation, style) { if (orientation == TabbedPane::Orientation::kHorizontal) { - auto layout = std::make_unique<BoxLayout>(BoxLayout::kHorizontal); + auto layout = + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal); layout->set_main_axis_alignment(BoxLayout::MainAxisAlignment::kCenter); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStretch); layout->SetDefaultFlex(1);
diff --git a/ui/views/controls/tree/tree_view.cc b/ui/views/controls/tree/tree_view.cc index 870553c..704750a 100644 --- a/ui/views/controls/tree/tree_view.cc +++ b/ui/views/controls/tree/tree_view.cc
@@ -139,8 +139,8 @@ root_.set_is_expanded(true); if (root_shown_) selected_node_ = &root_; - else if (root_.child_count()) - selected_node_ = root_.GetChild(0); + else if (!root_.children().empty()) + selected_node_ = root_.children().front().get(); } DrawnNodesChanged(); } @@ -683,7 +683,7 @@ } void TreeView::LoadChildren(InternalNode* node) { - DCHECK_EQ(0, node->child_count()); + DCHECK(node->children().empty()); DCHECK(!node->loaded_children()); node->set_loaded_children(true); for (auto* model_child : model_->GetChildren(node->model_node())) { @@ -769,8 +769,8 @@ if (!node->is_expanded()) return; depth++; - for (int i = 0; i < node->child_count() && *row < max_row; ++i) - PaintRows(canvas, min_row, max_row, node->GetChild(i), depth, row); + for (size_t i = 0; i < node->children().size() && *row < max_row; ++i) + PaintRows(canvas, min_row, max_row, node->children()[i].get(), depth, row); } void TreeView::PaintRow(gfx::Canvas* canvas, @@ -1007,10 +1007,9 @@ (*current_row)++; if (node->is_expanded()) { current_depth++; - for (int i = 0; i < node->child_count(); ++i) { + for (const auto& child : node->children()) { InternalNode* result = GetNodeByRowImpl( - node->GetChild(i), target_row, current_depth, current_row, - node_depth); + child.get(), target_row, current_depth, current_row, node_depth); if (result) return result; } @@ -1024,7 +1023,7 @@ if (!GetSelectedNode()) { // If nothing is selected select the first or last node. - if (!root_.child_count()) + if (root_.children().empty()) return; if (type == INCREMENT_PREVIOUS) { int row_count = GetRowCount(); @@ -1062,7 +1061,7 @@ if (selected_node_) { if (!selected_node_->is_expanded()) Expand(selected_node_->model_node()); - else if (selected_node_->child_count()) + else if (!selected_node_->children().empty()) SetSelectedNode(selected_node_->GetChild(0)->model_node()); } } @@ -1139,8 +1138,8 @@ int result = 1; // For this. if (!is_expanded_) return result; - for (int i = 0; i < child_count(); ++i) - result += GetChild(i)->NumExpandedNodes(); + for (const auto& child : children()) + result += child->NumExpandedNodes(); return result; } @@ -1150,9 +1149,9 @@ int max_width = (has_icon ? text_width_ : kArrowRegionSize) + indent * depth; if (!is_expanded_) return max_width; - for (int i = 0; i < child_count(); ++i) { + for (const auto& child : children()) { max_width = - std::max(max_width, GetChild(i)->GetMaxWidth(tree, indent, depth + 1)); + std::max(max_width, child->GetMaxWidth(tree, indent, depth + 1)); } return max_width; }
diff --git a/ui/views/controls/tree/tree_view_unittest.cc b/ui/views/controls/tree/tree_view_unittest.cc index aecde93..37bffe1 100644 --- a/ui/views/controls/tree/tree_view_unittest.cc +++ b/ui/views/controls/tree/tree_view_unittest.cc
@@ -4,6 +4,7 @@ #include "ui/views/controls/tree/tree_view.h" +#include <numeric> #include <string> #include "base/macros.h" @@ -123,10 +124,10 @@ const base::string16& title) { if (node->GetTitle() == title) return node; - for (int i = 0; i < node->child_count(); ++i) { - TestNode* child = GetNodeByTitleImpl(node->GetChild(i), title); - if (child) - return child; + for (auto& child : node->children()) { + TestNode* matching_node = GetNodeByTitleImpl(child.get(), title); + if (matching_node) + return matching_node; } return nullptr; } @@ -134,14 +135,14 @@ std::string TreeViewTest::InternalNodeAsString( TreeView::InternalNode* node) { std::string result = base::UTF16ToASCII(node->model_node()->GetTitle()); - if (node->is_expanded() && node->child_count()) { - result += " ["; - for (int i = 0; i < node->child_count(); ++i) { - if (i > 0) - result += " "; - result += InternalNodeAsString(node->GetChild(i)); - } - result += "]"; + if (node->is_expanded() && !node->children().empty()) { + result += std::accumulate( + node->children().cbegin() + 1, node->children().cend(), + " [" + InternalNodeAsString(node->children().front().get()), + [this](const std::string& str, const auto& child) { + return str + " " + InternalNodeAsString(child.get()); + }) + + "]"; } return result; }
diff --git a/ui/views/corewm/tooltip_aura.cc b/ui/views/corewm/tooltip_aura.cc index 3bb4ca0..9ff7e6a 100644 --- a/ui/views/corewm/tooltip_aura.cc +++ b/ui/views/corewm/tooltip_aura.cc
@@ -13,6 +13,7 @@ #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/gfx/canvas.h" +#include "ui/gfx/color_utils.h" #include "ui/gfx/render_text.h" #include "ui/gfx/text_elider.h" #include "ui/gfx/text_utils.h" @@ -27,15 +28,20 @@ // Max visual tooltip width. If a tooltip is greater than this width, it will // be wrapped. -constexpr int kTooltipMaxWidthPixels = 400; +constexpr int kTooltipMaxWidthPixels = 800; // FIXME: get cursor offset from actual cursor size. constexpr int kCursorOffsetX = 10; constexpr int kCursorOffsetY = 15; +// Paddings +constexpr int kHorizontalPadding = 8; +constexpr int kVerticalPaddingTop = 4; +constexpr int kVerticalPaddingBottom = 5; + // TODO(varkha): Update if native widget can be transparent on Linux. bool CanUseTranslucentTooltipWidget() { -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) +#if (defined(OS_LINUX) && !defined(OS_CHROMEOS)) || defined(OS_WIN) return false; #else return true; @@ -71,9 +77,6 @@ class TooltipAura::TooltipView : public views::View { public: TooltipView() : render_text_(gfx::RenderText::CreateHarfBuzzInstance()) { - constexpr int kHorizontalPadding = 8; - constexpr int kVerticalPaddingTop = 4; - constexpr int kVerticalPaddingBottom = 5; SetBorder(CreateEmptyBorder(kVerticalPaddingTop, kHorizontalPadding, kVerticalPaddingBottom, kHorizontalPadding)); @@ -122,13 +125,22 @@ } void SetBackgroundColor(SkColor background_color) { - // Corner radius of tooltip background. - const float kTooltipCornerRadius = 2.f; - SetBackground(CanUseTranslucentTooltipWidget() - ? views::CreateBackgroundFromPainter( - views::Painter::CreateSolidRoundRectPainter( - background_color, kTooltipCornerRadius)) - : views::CreateSolidBackground(background_color)); + if (CanUseTranslucentTooltipWidget()) { + // Corner radius of tooltip background. + const float kTooltipCornerRadius = 2.f; + SetBackground(views::CreateBackgroundFromPainter( + views::Painter::CreateSolidRoundRectPainter(background_color, + kTooltipCornerRadius))); + } else { + SetBackground(views::CreateSolidBackground(background_color)); + + auto border_color = + color_utils::GetColorWithMaxContrast(background_color); + SetBorder(views::CreatePaddedBorder( + views::CreateSolidBorder(1, border_color), + gfx::Insets(kVerticalPaddingTop - 1, kHorizontalPadding - 1, + kVerticalPaddingBottom - 1, kHorizontalPadding - 1))); + } // Force the text color to be readable when |background_color| is not // opaque. @@ -220,10 +232,16 @@ } ui::NativeTheme* native_theme = widget_->GetNativeTheme(); - tooltip_view_->SetBackgroundColor(native_theme->GetSystemColor( - ui::NativeTheme::kColorId_TooltipBackground)); - tooltip_view_->SetForegroundColor(native_theme->GetSystemColor( - ui::NativeTheme::kColorId_TooltipText)); + auto background_color = + native_theme->GetSystemColor(ui::NativeTheme::kColorId_TooltipBackground); + if (!CanUseTranslucentTooltipWidget()) + background_color = SkColorSetA(background_color, 0xFF); + tooltip_view_->SetBackgroundColor(background_color); + auto foreground_color = + native_theme->GetSystemColor(ui::NativeTheme::kColorId_TooltipText); + if (!CanUseTranslucentTooltipWidget()) + foreground_color = SkColorSetA(foreground_color, 0xFF); + tooltip_view_->SetForegroundColor(foreground_color); } void TooltipAura::Show() {
diff --git a/ui/views/examples/animated_image_view_example.cc b/ui/views/examples/animated_image_view_example.cc index 98959097..dc26fde 100644 --- a/ui/views/examples/animated_image_view_example.cc +++ b/ui/views/examples/animated_image_view_example.cc
@@ -47,8 +47,8 @@ CreateSolidSidedBorder(1, 1, 1, 1, SK_ColorBLACK)); image_view_container_ = AddChildView(std::move(image_view_container)); - BoxLayout* box = SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical, gfx::Insets(10), 10)); + BoxLayout* box = SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kVertical, gfx::Insets(10), 10)); box->SetFlexForView(image_view_container_, 1); auto file_chooser = std::make_unique<Textfield>(); @@ -57,7 +57,7 @@ auto file_container = std::make_unique<View>(); BoxLayout* file_box = file_container->SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kHorizontal, gfx::Insets(10), 10)); + BoxLayout::Orientation::kHorizontal, gfx::Insets(10), 10)); file_chooser_ = file_container->AddChildView(std::move(file_chooser)); file_go_button_ = file_container->AddChildView( MdTextButton::Create(this, base::ASCIIToUTF16("Render")));
diff --git a/ui/views/examples/bubble_example.cc b/ui/views/examples/bubble_example.cc index 26c8d9e..644d1059 100644 --- a/ui/views/examples/bubble_example.cc +++ b/ui/views/examples/bubble_example.cc
@@ -59,8 +59,8 @@ int GetDialogButtons() const override { return ui::DIALOG_BUTTON_NONE; } void Init() override { - SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical, gfx::Insets(50))); + SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kVertical, gfx::Insets(50))); AddChildView(new Label(GetArrowName(arrow()))); } @@ -75,8 +75,8 @@ BubbleExample::~BubbleExample() = default; void BubbleExample::CreateExampleView(View* container) { - container->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(), 10)); + container->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(), 10)); no_shadow_ = new LabelButton(this, ASCIIToUTF16("No Shadow")); container->AddChildView(no_shadow_); no_shadow_opaque_ = new LabelButton(this, ASCIIToUTF16("Opaque Border"));
diff --git a/ui/views/examples/button_example.cc b/ui/views/examples/button_example.cc index 993e0ef..50197395 100644 --- a/ui/views/examples/button_example.cc +++ b/ui/views/examples/button_example.cc
@@ -37,8 +37,8 @@ void ButtonExample::CreateExampleView(View* container) { container->SetBackground(CreateSolidBackground(SK_ColorWHITE)); - auto layout = - std::make_unique<BoxLayout>(BoxLayout::kVertical, gfx::Insets(10), 10); + auto layout = std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical, + gfx::Insets(10), 10); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kCenter); container->SetLayoutManager(std::move(layout));
diff --git a/ui/views/examples/combobox_example.cc b/ui/views/examples/combobox_example.cc index d8acc7b..32f0867 100644 --- a/ui/views/examples/combobox_example.cc +++ b/ui/views/examples/combobox_example.cc
@@ -51,8 +51,8 @@ disabled_combobox->SetSelectedIndex(4); disabled_combobox->SetEnabled(false); - container->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical, gfx::Insets(10, 0), 5)); + container->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kVertical, gfx::Insets(10, 0), 5)); container->AddChildView(combobox_); container->AddChildView(disabled_combobox); }
diff --git a/ui/views/examples/label_example.cc b/ui/views/examples/label_example.cc index 530ba13c..c8d8ceb 100644 --- a/ui/views/examples/label_example.cc +++ b/ui/views/examples/label_example.cc
@@ -62,8 +62,8 @@ void LabelExample::CreateExampleView(View* container) { // A very simple label example, followed by additional helpful examples. - container->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical, gfx::Insets(), 10)); + container->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kVertical, gfx::Insets(), 10)); container->AddChildView( std::make_unique<Label>(ASCIIToUTF16("Hello world!")));
diff --git a/ui/views/examples/slider_example.cc b/ui/views/examples/slider_example.cc index edc6f84..a3e1ce7e 100644 --- a/ui/views/examples/slider_example.cc +++ b/ui/views/examples/slider_example.cc
@@ -25,8 +25,8 @@ slider_->SetValue(0.5); - container->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(3), 3)); + container->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(3), 3)); container->AddChildView(slider_); container->AddChildView(label_); }
diff --git a/ui/views/examples/toggle_button_example.cc b/ui/views/examples/toggle_button_example.cc index 700edfd..fd47653 100644 --- a/ui/views/examples/toggle_button_example.cc +++ b/ui/views/examples/toggle_button_example.cc
@@ -19,7 +19,7 @@ void ToggleButtonExample::CreateExampleView(View* container) { button_ = new ToggleButton(this); - auto layout = std::make_unique<BoxLayout>(BoxLayout::kVertical); + auto layout = std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kCenter); container->SetLayoutManager(std::move(layout)); container->AddChildView(button_);
diff --git a/ui/views/examples/vector_example.cc b/ui/views/examples/vector_example.cc index bae6772..f631b382 100644 --- a/ui/views/examples/vector_example.cc +++ b/ui/views/examples/vector_example.cc
@@ -39,7 +39,8 @@ auto image_view_container = std::make_unique<views::View>(); image_view_ = image_view_container->AddChildView(std::make_unique<ImageView>()); - auto image_layout = std::make_unique<BoxLayout>(BoxLayout::kHorizontal); + auto image_layout = + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal); image_layout->set_cross_axis_alignment( BoxLayout::CrossAxisAlignment::kCenter); image_layout->set_main_axis_alignment( @@ -48,8 +49,8 @@ image_view_->SetBorder(CreateSolidSidedBorder(1, 1, 1, 1, SK_ColorBLACK)); image_view_container_ = AddChildView(std::move(image_view_container)); - BoxLayout* box = SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical, gfx::Insets(10), 10)); + BoxLayout* box = SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kVertical, gfx::Insets(10), 10)); box->SetFlexForView(image_view_container_, 1); auto file_chooser = std::make_unique<Textfield>(); @@ -58,7 +59,7 @@ auto file_container = std::make_unique<View>(); BoxLayout* file_box = file_container->SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kHorizontal, gfx::Insets(10), 10)); + BoxLayout::Orientation::kHorizontal, gfx::Insets(10), 10)); file_chooser_ = file_container->AddChildView(std::move(file_chooser)); file_go_button_ = file_container->AddChildView( MdTextButton::Create(this, base::ASCIIToUTF16("Render")));
diff --git a/ui/views/examples/widget_example.cc b/ui/views/examples/widget_example.cc index 5429fe6..0a36f58 100644 --- a/ui/views/examples/widget_example.cc +++ b/ui/views/examples/widget_example.cc
@@ -45,8 +45,8 @@ WidgetDialogExample::WidgetDialogExample() { SetBackground(CreateSolidBackground(SK_ColorGRAY)); - SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical, gfx::Insets(10), 10)); + SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kVertical, gfx::Insets(10), 10)); AddChildView(new Label(ASCIIToUTF16("Dialog contents label!"))); } @@ -74,8 +74,8 @@ WidgetExample::~WidgetExample() = default; void WidgetExample::CreateExampleView(View* container) { - container->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(), 10)); + container->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(), 10)); BuildButton(container, "Popup widget", POPUP); BuildButton(container, "Dialog widget", DIALOG); BuildButton(container, "Modal Dialog", MODAL_DIALOG); @@ -108,7 +108,7 @@ if (!widget->GetContentsView()) { View* contents = new View(); contents->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal)); contents->SetBackground(CreateSolidBackground(SK_ColorGRAY)); BuildButton(contents, "Close", CLOSE_WIDGET); widget->SetContentsView(contents);
diff --git a/ui/views/layout/box_layout.cc b/ui/views/layout/box_layout.cc index 94322109..b846609 100644 --- a/ui/views/layout/box_layout.cc +++ b/ui/views/layout/box_layout.cc
@@ -201,10 +201,11 @@ gfx::Rect min_child_area(child_area); gfx::Insets child_margins; if (collapse_margins_spacing_) { - child_margins = MaxAxisInsets( - orientation_ == kVertical ? HORIZONTAL_AXIS : VERTICAL_AXIS, - child.margins(), inside_border_insets_, child.margins(), - inside_border_insets_); + child_margins = + MaxAxisInsets(orientation_ == Orientation::kVertical ? HORIZONTAL_AXIS + : VERTICAL_AXIS, + child.margins(), inside_border_insets_, child.margins(), + inside_border_insets_); } else { child_margins = child.margins(); } @@ -289,7 +290,7 @@ DCHECK_EQ(host_, host); // Calculate the child views' preferred width. int width = 0; - if (orientation_ == kVertical) { + if (orientation_ == Orientation::kVertical) { // Calculating the child views' overall preferred width is a little involved // because of the way the margins interact with |cross_axis_alignment_|. int leading = 0; @@ -371,49 +372,51 @@ if (it == flex_map_.end() || !it->second.use_min_size) return 0; - return (orientation_ == kHorizontal) ? view->GetMinimumSize().width() - : view->GetMinimumSize().height(); + return (orientation_ == Orientation::kHorizontal) + ? view->GetMinimumSize().width() + : view->GetMinimumSize().height(); } int BoxLayout::MainAxisSize(const gfx::Rect& rect) const { - return orientation_ == kHorizontal ? rect.width() : rect.height(); + return orientation_ == Orientation::kHorizontal ? rect.width() + : rect.height(); } int BoxLayout::MainAxisPosition(const gfx::Rect& rect) const { - return orientation_ == kHorizontal ? rect.x() : rect.y(); + return orientation_ == Orientation::kHorizontal ? rect.x() : rect.y(); } void BoxLayout::SetMainAxisSize(int size, gfx::Rect* rect) const { - if (orientation_ == kHorizontal) + if (orientation_ == Orientation::kHorizontal) rect->set_width(size); else rect->set_height(size); } void BoxLayout::SetMainAxisPosition(int position, gfx::Rect* rect) const { - if (orientation_ == kHorizontal) + if (orientation_ == Orientation::kHorizontal) rect->set_x(position); else rect->set_y(position); } int BoxLayout::CrossAxisSize(const gfx::Rect& rect) const { - return orientation_ == kVertical ? rect.width() : rect.height(); + return orientation_ == Orientation::kVertical ? rect.width() : rect.height(); } int BoxLayout::CrossAxisPosition(const gfx::Rect& rect) const { - return orientation_ == kVertical ? rect.x() : rect.y(); + return orientation_ == Orientation::kVertical ? rect.x() : rect.y(); } void BoxLayout::SetCrossAxisSize(int size, gfx::Rect* rect) const { - if (orientation_ == kVertical) + if (orientation_ == Orientation::kVertical) rect->set_width(size); else rect->set_height(size); } void BoxLayout::SetCrossAxisPosition(int position, gfx::Rect* rect) const { - if (orientation_ == kVertical) + if (orientation_ == Orientation::kVertical) rect->set_x(position); else rect->set_y(position); @@ -421,7 +424,7 @@ int BoxLayout::MainAxisSizeForView(const ViewWrapper& view, int child_area_width) const { - return orientation_ == kHorizontal + return orientation_ == Orientation::kHorizontal ? view.GetPreferredSize().width() : view.GetHeightForWidth(cross_axis_alignment_ == CrossAxisAlignment::kStretch @@ -430,23 +433,26 @@ } int BoxLayout::MainAxisLeadingInset(const gfx::Insets& insets) const { - return orientation_ == kHorizontal ? insets.left() : insets.top(); + return orientation_ == Orientation::kHorizontal ? insets.left() + : insets.top(); } int BoxLayout::MainAxisTrailingInset(const gfx::Insets& insets) const { - return orientation_ == kHorizontal ? insets.right() : insets.bottom(); + return orientation_ == Orientation::kHorizontal ? insets.right() + : insets.bottom(); } int BoxLayout::CrossAxisLeadingEdge(const gfx::Rect& rect) const { - return orientation_ == kVertical ? rect.x() : rect.y(); + return orientation_ == Orientation::kVertical ? rect.x() : rect.y(); } int BoxLayout::CrossAxisLeadingInset(const gfx::Insets& insets) const { - return orientation_ == kVertical ? insets.left() : insets.top(); + return orientation_ == Orientation::kVertical ? insets.left() : insets.top(); } int BoxLayout::CrossAxisTrailingInset(const gfx::Insets& insets) const { - return orientation_ == kVertical ? insets.right() : insets.bottom(); + return orientation_ == Orientation::kVertical ? insets.right() + : insets.bottom(); } int BoxLayout::MainAxisMarginBetweenViews(const ViewWrapper& leading, @@ -462,15 +468,17 @@ if (collapse_margins_spacing_) { const ViewWrapper first(this, FirstVisibleView()); const ViewWrapper last(this, LastVisibleView()); - return MaxAxisInsets( - orientation_ == kHorizontal ? HORIZONTAL_AXIS : VERTICAL_AXIS, - inside_border_insets_, first.margins(), inside_border_insets_, - last.margins()); + return MaxAxisInsets(orientation_ == Orientation::kHorizontal + ? HORIZONTAL_AXIS + : VERTICAL_AXIS, + inside_border_insets_, first.margins(), + inside_border_insets_, last.margins()); } - return MaxAxisInsets( - orientation_ == kHorizontal ? HORIZONTAL_AXIS : VERTICAL_AXIS, - inside_border_insets_, gfx::Insets(), inside_border_insets_, - gfx::Insets()); + return MaxAxisInsets(orientation_ == Orientation::kHorizontal + ? HORIZONTAL_AXIS + : VERTICAL_AXIS, + inside_border_insets_, gfx::Insets(), + inside_border_insets_, gfx::Insets()); } gfx::Insets BoxLayout::CrossAxisMaxViewMargin() const { @@ -503,15 +511,15 @@ int BoxLayout::CrossAxisSizeForView(const ViewWrapper& view) const { // TODO(bruthig): For horizontal case use the available width and not the // preferred width. See https://crbug.com/682266. - return orientation_ == kVertical + return orientation_ == Orientation::kVertical ? view.GetPreferredSize().width() : view.GetHeightForWidth(view.GetPreferredSize().width()); } int BoxLayout::CrossAxisMarginSizeForView(const ViewWrapper& view) const { - return collapse_margins_spacing_ - ? 0 - : (orientation_ == kVertical ? view.margins().width() + return collapse_margins_spacing_ ? 0 + : (orientation_ == Orientation::kVertical + ? view.margins().width() : view.margins().height()); } @@ -522,7 +530,7 @@ void BoxLayout::InsetCrossAxis(gfx::Rect* rect, int leading, int trailing) const { - if (orientation_ == kVertical) + if (orientation_ == Orientation::kVertical) rect->Inset(leading, 0, trailing, 0); else rect->Inset(0, leading, 0, trailing); @@ -533,7 +541,7 @@ DCHECK_EQ(host, host_); gfx::Rect child_area_bounds; - if (orientation_ == kHorizontal) { + if (orientation_ == Orientation::kHorizontal) { // Horizontal layouts ignore |child_area_width|, meaning they mimic the // default behavior of GridLayout::GetPreferredHeightForWidth(). // TODO(estade|bruthig): Fix this See // https://crbug.com/682266.
diff --git a/ui/views/layout/box_layout.h b/ui/views/layout/box_layout.h index 62aeb7c..63567e76 100644 --- a/ui/views/layout/box_layout.h +++ b/ui/views/layout/box_layout.h
@@ -27,7 +27,7 @@ // Excess space will not be distributed. class VIEWS_EXPORT BoxLayout : public LayoutManager { public: - enum Orientation { + enum class Orientation { kHorizontal, kVertical, };
diff --git a/ui/views/layout/box_layout_unittest.cc b/ui/views/layout/box_layout_unittest.cc index 1c54e4cc..9e7702f7 100644 --- a/ui/views/layout/box_layout_unittest.cc +++ b/ui/views/layout/box_layout_unittest.cc
@@ -34,14 +34,14 @@ } // namespace TEST_F(BoxLayoutTest, Empty) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(10), 20)); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(10), 20)); EXPECT_EQ(gfx::Size(20, 20), layout->GetPreferredSize(host_.get())); } TEST_F(BoxLayoutTest, AlignmentHorizontal) { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal)); View* v1 = new StaticSizedView(gfx::Size(10, 20)); host_->AddChildView(v1); View* v2 = new StaticSizedView(gfx::Size(10, 10)); @@ -55,7 +55,7 @@ TEST_F(BoxLayoutTest, AlignmentVertical) { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical)); View* v1 = new StaticSizedView(gfx::Size(20, 10)); host_->AddChildView(v1); View* v2 = new StaticSizedView(gfx::Size(10, 10)); @@ -68,8 +68,8 @@ } TEST_F(BoxLayoutTest, SetInsideBorderInsets) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(20, 10))); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(20, 10))); View* v1 = new StaticSizedView(gfx::Size(10, 20)); host_->AddChildView(v1); View* v2 = new StaticSizedView(gfx::Size(10, 10)); @@ -90,8 +90,8 @@ } TEST_F(BoxLayoutTest, Spacing) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(7), 8)); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(7), 8)); View* v1 = new StaticSizedView(gfx::Size(10, 20)); host_->AddChildView(v1); View* v2 = new StaticSizedView(gfx::Size(10, 20)); @@ -105,7 +105,7 @@ TEST_F(BoxLayoutTest, Overflow) { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal)); View* v1 = new StaticSizedView(gfx::Size(20, 20)); host_->AddChildView(v1); View* v2 = new StaticSizedView(gfx::Size(10, 20)); @@ -137,8 +137,8 @@ } TEST_F(BoxLayoutTest, NoSpace) { - host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(10), 10)); + host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(10), 10)); View* childView = new StaticSizedView(gfx::Size(20, 20)); host_->AddChildView(childView); host_->SetBounds(0, 0, 10, 10); @@ -147,8 +147,8 @@ } TEST_F(BoxLayoutTest, InvisibleChild) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(10), 10)); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(10), 10)); View* v1 = new StaticSizedView(gfx::Size(20, 20)); v1->SetVisible(false); host_->AddChildView(v1); @@ -162,7 +162,7 @@ TEST_F(BoxLayoutTest, UseHeightForWidth) { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical)); View* v1 = new StaticSizedView(gfx::Size(20, 10)); host_->AddChildView(v1); ProportionallySizedView* v2 = new ProportionallySizedView(2); @@ -192,8 +192,9 @@ TEST_F(BoxLayoutTest, EmptyPreferredSize) { for (size_t i = 0; i < 2; i++) { - BoxLayout::Orientation orientation = i == 0 ? BoxLayout::kHorizontal : - BoxLayout::kVertical; + BoxLayout::Orientation orientation = + i == 0 ? BoxLayout::Orientation::kHorizontal + : BoxLayout::Orientation::kVertical; host_->RemoveAllChildViews(true); host_->SetLayoutManager( std::make_unique<BoxLayout>(orientation, gfx::Insets(), 5)); @@ -217,8 +218,8 @@ // empty preferred size, simultaneously. TEST_F(BoxLayoutTest, EmptyPreferredSizeWithFlexLayoutAndChildSpacing) { host_->RemoveAllChildViews(true); - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(), 5)); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(), 5)); View* v1 = new StaticSizedView(gfx::Size()); host_->AddChildView(v1); View* v2 = new StaticSizedView(gfx::Size(10, 10)); @@ -233,8 +234,8 @@ } TEST_F(BoxLayoutTest, MainAxisAlignmentHorizontal) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(10), 10)); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(10), 10)); View* v1 = new StaticSizedView(gfx::Size(20, 20)); host_->AddChildView(v1); @@ -269,8 +270,8 @@ } TEST_F(BoxLayoutTest, MainAxisAlignmentVertical) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical, gfx::Insets(10), 10)); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kVertical, gfx::Insets(10), 10)); View* v1 = new StaticSizedView(gfx::Size(20, 20)); host_->AddChildView(v1); @@ -305,8 +306,8 @@ } TEST_F(BoxLayoutTest, CrossAxisAlignmentHorizontal) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(10), 10)); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(10), 10)); View* v1 = new StaticSizedView(gfx::Size(20, 20)); host_->AddChildView(v1); @@ -347,8 +348,8 @@ } TEST_F(BoxLayoutTest, CrossAxisAlignmentVertical) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical, gfx::Insets(10), 10)); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kVertical, gfx::Insets(10), 10)); View* v1 = new StaticSizedView(gfx::Size(20, 20)); host_->AddChildView(v1); @@ -389,8 +390,8 @@ } TEST_F(BoxLayoutTest, FlexAll) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(10), 10)); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(10), 10)); layout->SetDefaultFlex(1); View* v1 = new StaticSizedView(gfx::Size(20, 20)); @@ -409,8 +410,8 @@ } TEST_F(BoxLayoutTest, FlexGrowVertical) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical, gfx::Insets(10), 10)); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kVertical, gfx::Insets(10), 10)); View* v1 = new StaticSizedView(gfx::Size(20, 20)); host_->AddChildView(v1); @@ -462,7 +463,7 @@ TEST_F(BoxLayoutTest, FlexGrowHorizontalWithRemainder) { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal)); layout->SetDefaultFlex(1); std::vector<View*> views; for (int i = 0; i < 5; ++i) { @@ -486,7 +487,7 @@ TEST_F(BoxLayoutTest, FlexGrowHorizontalWithRemainder2) { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal)); layout->SetDefaultFlex(1); std::vector<View*> views; for (int i = 0; i < 4; ++i) { @@ -508,8 +509,8 @@ } TEST_F(BoxLayoutTest, FlexShrinkHorizontal) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets(10), 10)); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(10), 10)); View* v1 = new StaticSizedView(gfx::Size(20, 20)); host_->AddChildView(v1); @@ -563,7 +564,7 @@ TEST_F(BoxLayoutTest, FlexShrinkVerticalWithRemainder) { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical)); View* v1 = new StaticSizedView(gfx::Size(20, 10)); host_->AddChildView(v1); View* v2 = new StaticSizedView(gfx::Size(20, 20)); @@ -608,7 +609,7 @@ TEST_F(BoxLayoutTest, MinimumCrossAxisVertical) { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical)); View* v1 = new StaticSizedView(gfx::Size(20, 10)); host_->AddChildView(v1); layout->set_minimum_cross_axis_size(30); @@ -618,7 +619,7 @@ TEST_F(BoxLayoutTest, MinimumCrossAxisHorizontal) { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal)); View* v1 = new StaticSizedView(gfx::Size(20, 10)); host_->AddChildView(v1); layout->set_minimum_cross_axis_size(30); @@ -628,7 +629,7 @@ TEST_F(BoxLayoutTest, MarginsUncollapsedHorizontal) { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal)); View* v1 = new StaticSizedView(gfx::Size(20, 10)); v1->SetProperty(kMarginsKey, gfx::Insets(5, 5, 5, 5)); host_->AddChildView(v1); @@ -645,7 +646,7 @@ TEST_F(BoxLayoutTest, MarginsCollapsedHorizontal) { BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kHorizontal, gfx::Insets(0, 0), 0, true)); + BoxLayout::Orientation::kHorizontal, gfx::Insets(0, 0), 0, true)); View* v1 = new StaticSizedView(gfx::Size(20, 10)); v1->SetProperty(kMarginsKey, gfx::Insets(5, 5, 5, 5)); host_->AddChildView(v1); @@ -662,7 +663,7 @@ TEST_F(BoxLayoutTest, MarginsUncollapsedVertical) { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical)); View* v1 = new StaticSizedView(gfx::Size(20, 10)); v1->SetProperty(kMarginsKey, gfx::Insets(5, 5, 5, 5)); host_->AddChildView(v1); @@ -679,7 +680,7 @@ TEST_F(BoxLayoutTest, MarginsCollapsedVertical) { BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kVertical, gfx::Insets(0, 0), 0, true)); + BoxLayout::Orientation::kVertical, gfx::Insets(0, 0), 0, true)); View* v1 = new StaticSizedView(gfx::Size(20, 10)); v1->SetProperty(kMarginsKey, gfx::Insets(5, 5, 5, 5)); host_->AddChildView(v1); @@ -695,7 +696,8 @@ } TEST_F(BoxLayoutTest, UnbalancedMarginsUncollapsedHorizontal) { - auto layout_owner = std::make_unique<BoxLayout>(BoxLayout::kHorizontal); + auto layout_owner = + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal); layout_owner->set_cross_axis_alignment( BoxLayout::CrossAxisAlignment::kCenter); BoxLayout* layout = host_->SetLayoutManager(std::move(layout_owner)); @@ -714,8 +716,8 @@ } TEST_F(BoxLayoutTest, UnbalancedMarginsCollapsedHorizontal) { - auto layout_owner = std::make_unique<BoxLayout>(BoxLayout::kHorizontal, - gfx::Insets(0, 0), 0, true); + auto layout_owner = std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets(0, 0), 0, true); layout_owner->set_cross_axis_alignment( BoxLayout::CrossAxisAlignment::kCenter); BoxLayout* layout = host_->SetLayoutManager(std::move(layout_owner)); @@ -734,7 +736,8 @@ } TEST_F(BoxLayoutTest, UnbalancedMarginsUncollapsedVertical) { - auto layout_owner = std::make_unique<BoxLayout>(BoxLayout::kVertical); + auto layout_owner = + std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical); layout_owner->set_cross_axis_alignment( BoxLayout::CrossAxisAlignment::kCenter); BoxLayout* layout = host_->SetLayoutManager(std::move(layout_owner)); @@ -753,8 +756,8 @@ } TEST_F(BoxLayoutTest, UnbalancedMarginsCollapsedVertical) { - auto layout_owner = std::make_unique<BoxLayout>(BoxLayout::kVertical, - gfx::Insets(0, 0), 0, true); + auto layout_owner = std::make_unique<BoxLayout>( + BoxLayout::Orientation::kVertical, gfx::Insets(0, 0), 0, true); layout_owner->set_cross_axis_alignment( BoxLayout::CrossAxisAlignment::kCenter); BoxLayout* layout = host_->SetLayoutManager(std::move(layout_owner)); @@ -775,7 +778,7 @@ TEST_F(BoxLayoutTest, OverlappingCrossMarginsAlignEnd) { { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal)); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kEnd); View* v1 = new StaticSizedView(gfx::Size(20, 4)); v1->SetProperty(kMarginsKey, gfx::Insets(3, 0, 0, 0)); @@ -789,7 +792,7 @@ host_->RemoveAllChildViews(true); { BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kHorizontal, gfx::Insets(0, 0), 0, true)); + BoxLayout::Orientation::kHorizontal, gfx::Insets(0, 0), 0, true)); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kEnd); View* v1 = new StaticSizedView(gfx::Size(20, 4)); v1->SetProperty(kMarginsKey, gfx::Insets(3, 0, 0, 0)); @@ -805,7 +808,7 @@ TEST_F(BoxLayoutTest, OverlappingCrossMarginsAlignStretch) { { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal)); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStretch); View* v1 = new StaticSizedView(gfx::Size(20, 4)); v1->SetProperty(kMarginsKey, gfx::Insets(3, 0, 0, 0)); @@ -819,7 +822,7 @@ host_->RemoveAllChildViews(true); { BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kHorizontal, gfx::Insets(0, 0), 0, true)); + BoxLayout::Orientation::kHorizontal, gfx::Insets(0, 0), 0, true)); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStretch); View* v1 = new StaticSizedView(gfx::Size(20, 4)); v1->SetProperty(kMarginsKey, gfx::Insets(3, 0, 0, 0)); @@ -835,7 +838,7 @@ TEST_F(BoxLayoutTest, OverlappingCrossMarginsAlignStart) { { BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal)); + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal)); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStart); View* v1 = new StaticSizedView(gfx::Size(20, 4)); v1->SetProperty(kMarginsKey, gfx::Insets(0, 0, 3, 0)); @@ -849,7 +852,7 @@ host_->RemoveAllChildViews(true); { BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kHorizontal, gfx::Insets(0, 0), 0, true)); + BoxLayout::Orientation::kHorizontal, gfx::Insets(0, 0), 0, true)); layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStart); View* v1 = new StaticSizedView(gfx::Size(20, 4)); v1->SetProperty(kMarginsKey, gfx::Insets(0, 0, 3, 0)); @@ -863,8 +866,8 @@ } TEST_F(BoxLayoutTest, NegativeBetweenChildSpacing) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kVertical, gfx::Insets(), -10)); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kVertical, gfx::Insets(), -10)); View* v1 = new StaticSizedView(gfx::Size(20, 20)); host_->AddChildView(v1); View* v2 = new StaticSizedView(gfx::Size(20, 15)); @@ -879,8 +882,8 @@ } TEST_F(BoxLayoutTest, MinimumChildSize) { - BoxLayout* layout = host_->SetLayoutManager( - std::make_unique<BoxLayout>(BoxLayout::kHorizontal, gfx::Insets())); + BoxLayout* layout = host_->SetLayoutManager(std::make_unique<BoxLayout>( + BoxLayout::Orientation::kHorizontal, gfx::Insets())); StaticSizedView* v1 = new StaticSizedView(gfx::Size(20, 20)); host_->AddChildView(v1); StaticSizedView* v2 = new StaticSizedView(gfx::Size(20, 20));
diff --git a/ui/views/test/test_views.cc b/ui/views/test/test_views.cc index 0d56fa3a..c1e20e37 100644 --- a/ui/views/test/test_views.cc +++ b/ui/views/test/test_views.cc
@@ -111,7 +111,8 @@ } ResizeAwareParentView::ResizeAwareParentView() { - SetLayoutManager(std::make_unique<BoxLayout>(BoxLayout::kHorizontal)); + SetLayoutManager( + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal)); } void ResizeAwareParentView::ChildPreferredSizeChanged(View* child) {
diff --git a/ui/views/touchui/touch_selection_menu_views.cc b/ui/views/touchui/touch_selection_menu_views.cc index 4f12977..1081c83 100644 --- a/ui/views/touchui/touch_selection_menu_views.cc +++ b/ui/views/touchui/touch_selection_menu_views.cc
@@ -54,8 +54,9 @@ set_adjust_if_offscreen(true); EnableCanvasFlippingForRTLUI(true); - SetLayoutManager(std::make_unique<BoxLayout>( - BoxLayout::kHorizontal, gfx::Insets(), kSpacingBetweenButtons)); + SetLayoutManager( + std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal, + gfx::Insets(), kSpacingBetweenButtons)); } void TouchSelectionMenuViews::ShowMenu(const gfx::Rect& anchor_rect,
diff --git a/ui/views/view.cc b/ui/views/view.cc index bc9d671..093f46fd 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc
@@ -1004,6 +1004,16 @@ void View::SetBorder(std::unique_ptr<Border> b) { border_ = std::move(b); + + // Conceptually, this should be PreferredSizeChanged(), but for some view + // hierarchies that triggers synchronous add/remove operations that are unsafe + // in some contexts where SetBorder is called. + // + // InvalidateLayout() still triggers a re-layout of the view, which should + // include re-querying its preferred size so in practice this is both safe and + // has the intended effect. + InvalidateLayout(); + SchedulePaint(); } @@ -2176,6 +2186,11 @@ view->PropagateThemeChanged(); } + // Need to notify the layout manager because one of the callbacks below might + // want to know the view's new preferred size, minimum size, etc. + if (layout_manager_) + layout_manager_->ViewAdded(this, view); + ViewHierarchyChangedDetails details(true, this, view, parent); for (View* v = this; v; v = v->parent_) @@ -2192,9 +2207,6 @@ view->SchedulePaint(); } - if (layout_manager_) - layout_manager_->ViewAdded(this, view); - for (ViewObserver& observer : observers_) observer.OnChildViewAdded(this, view); } @@ -2238,6 +2250,11 @@ if (widget) widget->LayerTreeChanged(); + // Need to notify the layout manager because one of the callbacks below might + // want to know the view's new preferred size, minimum size, etc. + if (layout_manager_) + layout_manager_->ViewRemoved(this, view); + view->PropagateRemoveNotifications(this, new_parent, is_removed_from_widget); view->parent_ = nullptr; @@ -2252,9 +2269,6 @@ if (update_tool_tip) UpdateTooltip(); - if (layout_manager_) - layout_manager_->ViewRemoved(this, view); - for (ViewObserver& observer : observers_) observer.OnChildViewRemoved(this, view); }
diff --git a/ui/views/views_features.cc b/ui/views/views_features.cc index 500931f..7f54bb0 100644 --- a/ui/views/views_features.cc +++ b/ui/views/views_features.cc
@@ -11,6 +11,12 @@ // Please keep alphabetized. +#if defined(OS_WIN) +// Uses aura tooltips instead of the native comctl32 tooltips on Windows. +const base::Feature kEnableAuraTooltipsOnWindows{ + "EnableAuraTooltipsOnWindows", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif // OS_WIN + // Increases corner radius on Dialogs for the material design refresh. // TODO(sajadm): Remove this feature flag when platform inconsistencies // have been fixed as recorded on: https://crbug.com/932970
diff --git a/ui/views/views_features.h b/ui/views/views_features.h index 0df9cff..629df27 100644 --- a/ui/views/views_features.h +++ b/ui/views/views_features.h
@@ -6,12 +6,17 @@ #define UI_VIEWS_VIEWS_FEATURES_H_ #include "base/feature_list.h" +#include "build/build_config.h" #include "ui/views/views_export.h" namespace views { namespace features { // Please keep alphabetized. +#if defined(OS_WIN) +VIEWS_EXPORT extern const base::Feature kEnableAuraTooltipsOnWindows; +#endif // OS_WIN + VIEWS_EXPORT extern const base::Feature kEnableMDRoundedCornersOnDialogs; } // namespace features
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc index d423f5f..eed8b61 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -8,6 +8,7 @@ #include "base/containers/flat_set.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" +#include "base/win/win_util.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkRegion.h" #include "ui/aura/client/aura_constants.h" @@ -29,7 +30,9 @@ #include "ui/gfx/geometry/vector2d.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/path_win.h" +#include "ui/views/corewm/tooltip_aura.h" #include "ui/views/corewm/tooltip_win.h" +#include "ui/views/views_features.h" #include "ui/views/views_switches.h" #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h" #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" @@ -165,6 +168,9 @@ void DesktopWindowTreeHostWin::OnWidgetInitDone() {} std::unique_ptr<corewm::Tooltip> DesktopWindowTreeHostWin::CreateTooltip() { + if (base::FeatureList::IsEnabled(features::kEnableAuraTooltipsOnWindows)) + return std::make_unique<corewm::TooltipAura>(); + DCHECK(!tooltip_); tooltip_ = new corewm::TooltipWin(GetAcceleratedWidget()); return base::WrapUnique(tooltip_);
diff --git a/ui/views/widget/widget_hwnd_utils.cc b/ui/views/widget/widget_hwnd_utils.cc index 5bcb8d8b..7d74fdff 100644 --- a/ui/views/widget/widget_hwnd_utils.cc +++ b/ui/views/widget/widget_hwnd_utils.cc
@@ -109,6 +109,9 @@ case Widget::InitParams::TYPE_MENU: *style |= WS_POPUP; break; + case Widget::InitParams::TYPE_TOOLTIP: + *style |= WS_POPUP; + break; default: NOTREACHED(); }