diff --git a/.clang-tidy b/.clang-tidy index 3477d88..c7515c8 100644 --- a/.clang-tidy +++ b/.clang-tidy
@@ -1,5 +1,4 @@ --- ---- Checks: '-*, bugprone-string-integer-assignment, bugprone-unused-raii, @@ -25,6 +24,8 @@ modernize-use-transparent-functors, readability-redundant-member-init' CheckOptions: + - key: modernize-use-default-member-init.UseAssignment + value: 1 # This relaxes modernize-use-emplace in some cases; we might want to make it # more aggressive in the future. See discussion on # https://groups.google.com/a/chromium.org/g/cxx/c/noMMTNYiM0w .
diff --git a/DEPS b/DEPS index aaa31148..c5f60ca 100644 --- a/DEPS +++ b/DEPS
@@ -206,11 +206,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': 'be8004d2fb6c8575d7da7c580811639654a9d255', + 'skia_revision': '260029435baaefe42548c0be0fa408e6f8dee42a', # 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': '992b13db26c29db225f812aa1dfc637940e99cb8', + 'v8_revision': '93ed90e664430291b53e3ee3f26d4dbc0e3c7804', # 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. @@ -218,7 +218,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': '07ea804e620132517b6af0ef92fe85ea737d0c27', + 'angle_revision': 'c69ef8bf34ca3d7c1e8a4e187280e5b06e21e605', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -226,7 +226,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': '2f56cfe7fc9eb21eab44ed0f9bcfa3538afe1305', + 'pdfium_revision': '1105ef875a9375fc4e7030161817412f1db283c2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -269,7 +269,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': '5d73338a50dcee6d9f6a4e92afcf41e281715779', + 'catapult_revision': '91f276e903b3495d5fd4ad74e289e0893787d9a1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -277,7 +277,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'b055d47b4a3a91dc67e13f5be947299278e29496', + 'devtools_frontend_revision': '69e28b68cab8dc34cdbd8c6ec3503546a57875df', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -912,7 +912,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '4761cf50d032aa5d1e0c51f47d20fa43380c01fd', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '4c45ca0dd90a390224b1031d068900f3e4c3f5c5', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1497,7 +1497,7 @@ }, 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '37d41eea047799ccca2f09c941870c26ee3ffc0a', + Var('webrtc_git') + '/src.git' + '@' + '1f7eab68c0ce267b935f9ea3544d3105d7fd19dc', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1569,7 +1569,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0c7a073b194f0e80b5dacda0f5d8dd1c8b322d8f', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@8216043b1fc4e7c0160ed64a18c273a1874faba3', 'condition': 'checkout_src_internal', }, @@ -1588,7 +1588,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'vBjX1UUxt2Xw11p044tIxezzzvpljMVlif9zIUpKokcC', + 'version': 'wHmgVwhdw29vHqkyUXbbeSCuBeOGOHCSL0B8dd3273MC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 47bace3..9c2f3d5b 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -1366,6 +1366,7 @@ 'build/android/test_wrapper/logdog_wrapper.pydeps', 'build/lacros/lacros_resource_sizes.pydeps', 'build/protoc_java.pydeps', + 'chrome/android/monochrome/scripts/monochrome_python_tests.pydeps', 'chrome/test/chromedriver/log_replay/client_replay_unittest.pydeps', 'chrome/test/chromedriver/test/run_py_tests.pydeps', 'components/cronet/tools/generate_javadoc.pydeps',
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn index 8b23b50d..e017dd49 100644 --- a/ash/public/cpp/BUILD.gn +++ b/ash/public/cpp/BUILD.gn
@@ -300,8 +300,6 @@ "window_animation_types.h", "window_backdrop.cc", "window_backdrop.h", - "window_pin_type.cc", - "window_pin_type.h", "window_properties.cc", "window_properties.h", ]
diff --git a/ash/public/cpp/window_properties.cc b/ash/public/cpp/window_properties.cc index 2c3531a..6889994 100644 --- a/ash/public/cpp/window_properties.cc +++ b/ash/public/cpp/window_properties.cc
@@ -6,7 +6,6 @@ #include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/window_backdrop.h" -#include "ash/public/cpp/window_pin_type.h" #include "chromeos/ui/base/chromeos_ui_constants.h" #include "chromeos/ui/base/window_state_type.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" @@ -14,7 +13,6 @@ #include "ui/aura/window.h" #include "ui/wm/core/window_properties.h" -DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(ASH_PUBLIC_EXPORT, ash::WindowPinType) DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(ASH_PUBLIC_EXPORT, chromeos::WindowStateType) DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(ASH_PUBLIC_EXPORT, ash::WindowBackdrop*) @@ -33,7 +31,6 @@ DEFINE_UI_CLASS_PROPERTY_KEY(bool, kExcludeInMruKey, false) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kHideInOverviewKey, false) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kHideInShelfKey, false) -DEFINE_UI_CLASS_PROPERTY_KEY(bool, kHideShelfWhenFullscreenKey, true) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIsDeferredTabDraggingTargetWindowKey, false) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIsDraggingTabsKey, false) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kHideInDeskMiniViewKey, false) @@ -71,9 +68,6 @@ DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(base::string16, kWindowOverviewTitleKey, nullptr) -DEFINE_UI_CLASS_PROPERTY_KEY(WindowPinType, - kWindowPinTypeKey, - WindowPinType::kNone) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kWindowPositionManagedTypeKey, false) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kWindowPipTypeKey, false)
diff --git a/ash/public/cpp/window_properties.h b/ash/public/cpp/window_properties.h index 319edcb9..5012133b 100644 --- a/ash/public/cpp/window_properties.h +++ b/ash/public/cpp/window_properties.h
@@ -31,8 +31,6 @@ namespace ash { -enum class WindowPinType; - class WindowBackdrop; // Shell-specific window property keys for use by ash and its clients. @@ -80,11 +78,6 @@ ASH_PUBLIC_EXPORT extern const aura::WindowProperty<bool>* const kHideInShelfKey; -// Whether the shelf should be hidden when this window is put into fullscreen. -// Exposed because some windows want to explicitly opt-out of this. -ASH_PUBLIC_EXPORT extern const aura::WindowProperty<bool>* const - kHideShelfWhenFullscreenKey; - // If true, the window is the target window for the tab-dragged window. The key // is used by overview to show a highlight indication to indicate which overview // window the dragged tabs will merge into when the user releases the pointer. @@ -206,14 +199,6 @@ ASH_PUBLIC_EXPORT extern const aura::WindowProperty<base::string16*>* const kWindowOverviewTitleKey; -// A property key to store ash::WindowPinType for a window. -// When setting this property to PINNED or TRUSTED_PINNED, the window manager -// will try to fullscreen the window and pin it on the top of the screen. If the -// window manager failed to do it, the property will be restored to NONE. When -// setting this property to NONE, the window manager will restore the window. -ASH_PUBLIC_EXPORT extern const aura::WindowProperty<WindowPinType>* const - kWindowPinTypeKey; - // A property key to indicate whether ash should perform auto management of // window positions; when you open a second browser, ash will move the two to // minimize overlap.
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc index 3f6fc60..eaa21d4 100644 --- a/ash/shelf/shelf_layout_manager_unittest.cc +++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -34,7 +34,6 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/test/shell_test_api.h" #include "ash/public/cpp/wallpaper_controller_observer.h" -#include "ash/public/cpp/window_properties.h" #include "ash/root_window_controller.h" #include "ash/screen_util.h" #include "ash/session/session_controller_impl.h" @@ -81,6 +80,7 @@ #include "base/test/scoped_feature_list.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_switches.h" +#include "chromeos/ui/base/window_properties.h" #include "components/prefs/pref_service.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/window_parenting_client.h" @@ -109,6 +109,8 @@ namespace ash { namespace { +using ::chromeos::kHideShelfWhenFullscreenKey; + void PressHomeButton() { Shell::Get()->app_list_controller()->ToggleAppList( display::Screen::GetScreen()->GetPrimaryDisplay().id(),
diff --git a/ash/system/phonehub/phone_hub_notification_controller_unittest.cc b/ash/system/phonehub/phone_hub_notification_controller_unittest.cc index b9506f58..4f208835 100644 --- a/ash/system/phonehub/phone_hub_notification_controller_unittest.cc +++ b/ash/system/phonehub/phone_hub_notification_controller_unittest.cc
@@ -136,6 +136,11 @@ notification_manager_.RemoveNotificationsInternal(base::flat_set<int64_t>( {kPhoneHubNotificationId1, kPhoneHubNotificationId2})); EXPECT_FALSE(message_center_->NotificationCount()); + + // Attempt removing the same notifications again and expect nothing to happen. + notification_manager_.RemoveNotificationsInternal(base::flat_set<int64_t>( + {kPhoneHubNotificationId1, kPhoneHubNotificationId2})); + EXPECT_FALSE(message_center_->NotificationCount()); } TEST_F(PhoneHubNotificationControllerTest, CloseByUser) {
diff --git a/ash/wm/fullscreen_window_finder_unittest.cc b/ash/wm/fullscreen_window_finder_unittest.cc index 20eb0a3..6fcd99f 100644 --- a/ash/wm/fullscreen_window_finder_unittest.cc +++ b/ash/wm/fullscreen_window_finder_unittest.cc
@@ -6,10 +6,10 @@ #include <memory> -#include "ash/public/cpp/window_pin_type.h" -#include "ash/public/cpp/window_properties.h" #include "ash/test/ash_test_base.h" #include "base/macros.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/base/ui_base_types.h" @@ -17,6 +17,9 @@ namespace ash { +using ::chromeos::kWindowPinTypeKey; +using ::chromeos::WindowPinType; + class FullscreenWindowFinderTest : public AshTestBase { public: FullscreenWindowFinderTest() = default;
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index 6da6761..1f4c7d6 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -12,7 +12,6 @@ #include "ash/public/cpp/app_types.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/window_animation_types.h" -#include "ash/public/cpp/window_pin_type.h" #include "ash/public/cpp/window_properties.h" #include "ash/screen_util.h" #include "ash/shell.h" @@ -30,6 +29,7 @@ #include "base/auto_reset.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "chromeos/ui/base/window_pin_type.h" #include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/base/window_state_type.h" #include "ui/aura/client/aura_constants.h" @@ -52,7 +52,10 @@ namespace ash { namespace { +using ::chromeos::kHideShelfWhenFullscreenKey; using ::chromeos::kImmersiveIsActive; +using ::chromeos::kWindowPinTypeKey; +using ::chromeos::WindowPinType; using ::chromeos::WindowStateType; bool IsTabletModeEnabled() { @@ -115,13 +118,13 @@ return WM_EVENT_NORMAL; } -WMEventType WMEventTypeFromWindowPinType(ash::WindowPinType type) { +WMEventType WMEventTypeFromWindowPinType(chromeos::WindowPinType type) { switch (type) { - case ash::WindowPinType::kNone: + case chromeos::WindowPinType::kNone: return WM_EVENT_NORMAL; - case ash::WindowPinType::kPinned: + case chromeos::WindowPinType::kPinned: return WM_EVENT_PIN; - case ash::WindowPinType::kTrustedPinned: + case chromeos::WindowPinType::kTrustedPinned: return WM_EVENT_TRUSTED_PIN; } NOTREACHED() << "No WMEvent defined for the window pin type:" << type;
diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h index 8e8075bc..a1df5057 100644 --- a/ash/wm/window_state.h +++ b/ash/wm/window_state.h
@@ -21,6 +21,7 @@ #include "ui/gfx/animation/tween.h" namespace chromeos { +enum class WindowPinType; enum class WindowStateType; } @@ -32,7 +33,6 @@ class ClientControlledState; class LockWindowState; class TabletModeWindowState; -enum class WindowPinType; class WindowState; class WindowStateDelegate; class WindowStateObserver; @@ -395,7 +395,7 @@ ui::WindowShowState GetShowState() const; // Return the window's current pin type. - WindowPinType GetPinType() const; + chromeos::WindowPinType GetPinType() const; // Sets the window's bounds in screen coordinates. void SetBoundsInScreen(const gfx::Rect& bounds_in_screen);
diff --git a/base/allocator/partition_allocator/partition_alloc.cc b/base/allocator/partition_allocator/partition_alloc.cc index 5fce1b5..3a06ecc 100644 --- a/base/allocator/partition_allocator/partition_alloc.cc +++ b/base/allocator/partition_allocator/partition_alloc.cc
@@ -631,7 +631,7 @@ #endif } - slot_span->freelist_head = head; + slot_span->SetFreelistHead(head); if (back) back->next = internal::PartitionFreelistEntry::Encode(nullptr);
diff --git a/base/allocator/partition_allocator/partition_alloc.h b/base/allocator/partition_allocator/partition_alloc.h index 90c948f2..1a905b46 100644 --- a/base/allocator/partition_allocator/partition_alloc.h +++ b/base/allocator/partition_allocator/partition_alloc.h
@@ -423,7 +423,7 @@ internal::PartitionFreelistEntry* new_head = internal::EncodedPartitionFreelistEntry::Decode( slot_span->freelist_head->next); - slot_span->freelist_head = new_head; + slot_span->SetFreelistHead(new_head); slot_span->num_allocated_slots++; PA_DCHECK(slot_span->bucket == bucket);
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc index 1b8e704..a5c2a45 100644 --- a/base/allocator/partition_allocator/partition_alloc_unittest.cc +++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -617,40 +617,29 @@ EXPECT_TRUE(bucket->empty_slot_spans_head); } -// TODO(bartekn): Clean up page/slot-span confusion below here. - // Test a large series of allocations that cross more than one underlying -// 64KB super page allocation. +// super page. TEST_F(PartitionAllocTest, MultiPageAllocs) { - // Need to consider the number of slot span per 1 Super Page. - // The number of pages needed should be calculated by using the number. - // Because if the number of left partition pages is smaller than - // the number of pages per slot span, a new super page will be allocated. size_t num_pages_per_slot_span = GetNumPagesPerSlotSpan(kTestAllocSize); - // 1 SuperPage has 2 guard PartitionPages. - size_t num_slot_span_needed = + // 1 super page has 2 guard partition pages. + size_t num_slot_spans_needed = (NumPartitionPagesPerSuperPage() - NumPartitionPagesPerTagBitmap() - 2) / num_pages_per_slot_span; - // This is guaranteed to cross a super page boundary because the first - // partition page "slot" will be taken up by a guard page. - size_t num_pages_needed = num_slot_span_needed * num_pages_per_slot_span; + // We need one more slot span in order to cross super page boundary. + ++num_slot_spans_needed; - // The super page should begin and end in a guard so we one less page in - // order to allocate a single page in the new super page. - ++num_pages_needed; - - EXPECT_GT(num_pages_needed, 1u); - auto pages = std::make_unique<SlotSpan*[]>(num_pages_needed); + EXPECT_GT(num_slot_spans_needed, 1u); + auto slot_spans = std::make_unique<SlotSpan*[]>(num_slot_spans_needed); uintptr_t first_super_page_base = 0; size_t i; - for (i = 0; i < num_pages_needed; ++i) { - pages[i] = GetFullSlotSpan(kTestAllocSize); - void* storage_ptr = SlotSpan::ToPointer(pages[i]); + for (i = 0; i < num_slot_spans_needed; ++i) { + slot_spans[i] = GetFullSlotSpan(kTestAllocSize); + void* storage_ptr = SlotSpan::ToPointer(slot_spans[i]); if (!i) first_super_page_base = reinterpret_cast<uintptr_t>(storage_ptr) & kSuperPageBaseMask; - if (i == num_pages_needed - 1) { + if (i == num_slot_spans_needed - 1) { uintptr_t second_super_page_base = reinterpret_cast<uintptr_t>(storage_ptr) & kSuperPageBaseMask; uintptr_t second_super_page_offset = @@ -661,8 +650,8 @@ second_super_page_offset); } } - for (i = 0; i < num_pages_needed; ++i) - FreeFullSlotSpan(allocator.root(), pages[i]); + for (i = 0; i < num_slot_spans_needed; ++i) + FreeFullSlotSpan(allocator.root(), slot_spans[i]); } // Test the generic allocation functions that can handle arbitrary sizes and @@ -807,7 +796,7 @@ allocator.root()->Free(ptr4); #if DCHECK_IS_ON() - // |PartitionPage::Free| must poison the slot's contents with |kFreedByte|. + // |SlotSpanMetadata::Free| must poison the slot's contents with |kFreedByte|. EXPECT_EQ(kFreedByte, *(reinterpret_cast<unsigned char*>(new_ptr) + (size - 1))); #endif @@ -1033,7 +1022,7 @@ allocator.root()->Free(ptr2); } -// Tests the handing out of freelists for partial pages. +// Tests the handing out of freelists for partial slot spans. TEST_F(PartitionAllocTest, PartialPageFreelists) { size_t big_size = SystemPageSize() - kExtraAllocSize; size_t bucket_index = SizeToIndex(big_size + kExtraAllocSize); @@ -1082,7 +1071,7 @@ SlotSpan::FromPointer(PartitionPointerAdjustSubtract(true, ptr5)); EXPECT_EQ(1, slot_span2->num_allocated_slots); - // Churn things a little whilst there's a partial page freelist. + // Churn things a little whilst there's a partial slot span freelist. allocator.root()->Free(ptr); ptr = allocator.root()->Alloc(big_size, type_name); void* ptr6 = allocator.root()->Alloc(big_size, type_name); @@ -1112,9 +1101,11 @@ total_slots = (slot_span->bucket->num_system_pages_per_slot_span * SystemPageSize()) / (medium_size + kExtraAllocSize); - size_t first_page_slots = SystemPageSize() / (medium_size + kExtraAllocSize); - EXPECT_EQ(2u, first_page_slots); - EXPECT_EQ(total_slots - first_page_slots, slot_span->num_unprovisioned_slots); + size_t first_slot_span_slots = + SystemPageSize() / (medium_size + kExtraAllocSize); + EXPECT_EQ(2u, first_slot_span_slots); + EXPECT_EQ(total_slots - first_slot_span_slots, + slot_span->num_unprovisioned_slots); allocator.root()->Free(ptr); @@ -1130,8 +1121,9 @@ total_slots = (slot_span->bucket->num_system_pages_per_slot_span * SystemPageSize()) / (small_size + kExtraAllocSize); - first_page_slots = SystemPageSize() / (small_size + kExtraAllocSize); - EXPECT_EQ(total_slots - first_page_slots, slot_span->num_unprovisioned_slots); + first_slot_span_slots = SystemPageSize() / (small_size + kExtraAllocSize); + EXPECT_EQ(total_slots - first_slot_span_slots, + slot_span->num_unprovisioned_slots); allocator.root()->Free(ptr); EXPECT_TRUE(slot_span->freelist_head); @@ -1149,10 +1141,11 @@ total_slots = (slot_span->bucket->num_system_pages_per_slot_span * SystemPageSize()) / (very_small_size + kExtraAllocSize); - first_page_slots = + first_slot_span_slots = (SystemPageSize() + very_small_size + kExtraAllocSize - 1) / (very_small_size + kExtraAllocSize); - EXPECT_EQ(total_slots - first_page_slots, slot_span->num_unprovisioned_slots); + EXPECT_EQ(total_slots - first_slot_span_slots, + slot_span->num_unprovisioned_slots); allocator.root()->Free(ptr); EXPECT_TRUE(slot_span->freelist_head); @@ -1174,25 +1167,25 @@ allocator.root()->Free(ptr); // And then make sure than exactly the page size only faults one page. - size_t pageSize = SystemPageSize() - kExtraAllocSize; - ptr = allocator.root()->Alloc(pageSize, type_name); + size_t page_size = SystemPageSize() - kExtraAllocSize; + ptr = allocator.root()->Alloc(page_size, type_name); EXPECT_TRUE(ptr); slot_span = SlotSpan::FromPointer(PartitionPointerAdjustSubtract(true, ptr)); EXPECT_EQ(1, slot_span->num_allocated_slots); EXPECT_TRUE(slot_span->freelist_head); total_slots = (slot_span->bucket->num_system_pages_per_slot_span * SystemPageSize()) / - (pageSize + kExtraAllocSize); + (page_size + kExtraAllocSize); EXPECT_EQ(total_slots - 2, slot_span->num_unprovisioned_slots); allocator.root()->Free(ptr); } // Test some of the fragmentation-resistant properties of the allocator. -TEST_F(PartitionAllocTest, PageRefilling) { +TEST_F(PartitionAllocTest, SlotSpanRefilling) { PartitionRoot<ThreadSafe>::Bucket* bucket = &allocator.root()->buckets[test_bucket_index_]; - // Grab two full pages and a non-full page. + // Grab two full slot spans and a non-full slot span. auto* slot_span1 = GetFullSlotSpan(kTestAllocSize); auto* slot_span2 = GetFullSlotSpan(kTestAllocSize); void* ptr = allocator.root()->Alloc(kTestAllocSize, type_name); @@ -1213,7 +1206,7 @@ allocator.root()->Free(ptr2); // If we perform two allocations from the same bucket now, we expect to - // refill both the nearly full pages. + // refill both the nearly full slot spans. (void)allocator.root()->Alloc(kTestAllocSize, type_name); (void)allocator.root()->Alloc(kTestAllocSize, type_name); EXPECT_EQ(1, slot_span->num_allocated_slots); @@ -1337,7 +1330,8 @@ } } -// Tests that pages in the free page cache do get freed as appropriate. +// Tests that slot spans in the free slot span cache do get freed as +// appropriate. TEST_F(PartitionAllocTest, FreeCache) { EXPECT_EQ(0U, allocator.root()->total_size_of_committed_pages_for_testing()); @@ -1362,7 +1356,7 @@ CycleFreeCache(kTestAllocSize); - // Flushing the cache should have really freed the unused page. + // Flushing the cache should have really freed the unused slot spans. EXPECT_FALSE(slot_span->freelist_head); EXPECT_EQ(-1, slot_span->empty_cache_index); EXPECT_EQ(0, slot_span->num_allocated_slots); @@ -1374,13 +1368,13 @@ EXPECT_EQ(expected_size, allocator.root()->total_size_of_committed_pages_for_testing()); - // Check that an allocation works ok whilst in this state (a free'd page - // as the active pages head). + // Check that an allocation works ok whilst in this state (a free'd slot span + // as the active slot spans head). ptr = allocator.root()->Alloc(big_size, type_name); EXPECT_FALSE(bucket->empty_slot_spans_head); allocator.root()->Free(ptr); - // Also check that a page that is bouncing immediately between empty and + // Also check that a slot span that is bouncing immediately between empty and // used does not get freed. for (size_t i = 0; i < kMaxFreeableSpans * 2; ++i) { ptr = allocator.root()->Alloc(big_size, type_name); @@ -1392,8 +1386,8 @@ allocator.root()->total_size_of_committed_pages_for_testing()); } -// Tests for a bug we had with losing references to free pages. -TEST_F(PartitionAllocTest, LostFreePagesBug) { +// Tests for a bug we had with losing references to free slot spans. +TEST_F(PartitionAllocTest, LostFreeSlotSpansBug) { size_t size = PartitionPageSize() - kExtraAllocSize; void* ptr = allocator.root()->Alloc(size, type_name); @@ -1448,8 +1442,8 @@ CycleFreeCache(kTestAllocSize); // We're now set up to trigger a historical bug by scanning over the active - // pages list. The current code gets into a different state, but we'll keep - // the test as being an interesting corner case. + // slot spans list. The current code gets into a different state, but we'll + // keep the test as being an interesting corner case. ptr = allocator.root()->Alloc(size, type_name); EXPECT_TRUE(ptr); allocator.root()->Free(ptr); @@ -1558,8 +1552,8 @@ allocator.root()->Free(ptr); allocator.root()->Free(ptr2); // This is not an immediate double-free so our immediate detection won't - // fire. However, it does take the "refcount" of the partition page to -1, - // which is illegal and should be trapped. + // fire. However, it does take the "refcount" of the to -1, which is illegal + // and should be trapped. EXPECT_DEATH(allocator.root()->Free(ptr), ""); } @@ -1682,7 +1676,7 @@ } } - // This test checks for correct empty page list accounting. + // This test checks for correct empty slot span list accounting. { size_t size = PartitionPageSize() - kExtraAllocSize; void* ptr1 = allocator.root()->Alloc(size, type_name); @@ -1935,22 +1929,22 @@ EXPECT_EQ(slot_span3, bucket->active_slot_spans_head); // Free up the 2nd slot in each slot span. - // This leaves the active list containing 3 pages, each with 1 used and 1 - // free slot. The active page will be the one containing ptr1. + // This leaves the active list containing 3 slot spans, each with 1 used and 1 + // free slot. The active slot span will be the one containing ptr1. allocator.root()->Free(ptr6); allocator.root()->Free(ptr4); allocator.root()->Free(ptr2); EXPECT_EQ(slot_span1, bucket->active_slot_spans_head); - // Empty the middle page in the active list. + // Empty the middle slot span in the active list. allocator.root()->Free(ptr3); EXPECT_EQ(slot_span1, bucket->active_slot_spans_head); - // Empty the first page in the active list -- also the current page. + // Empty the first slot span in the active list -- also the current slot span. allocator.root()->Free(ptr1); - // A good choice here is to re-fill the third page since the first two are - // empty. We used to fail that. + // A good choice here is to re-fill the third slot span since the first two + // are empty. We used to fail that. void* ptr7 = allocator.root()->Alloc(size, type_name); EXPECT_EQ(ptr6, ptr7); EXPECT_EQ(slot_span3, bucket->active_slot_spans_head); @@ -2322,7 +2316,7 @@ TEST_F(PartitionAllocTest, Bug_897585) { // Need sizes big enough to be direct mapped and a delta small enough to - // allow re-use of the page when cookied. These numbers fall out of the + // allow re-use of the slot span when cookied. These numbers fall out of the // test case in the indicated bug. size_t kInitialSize = 983040; size_t kDesiredSize = 983100;
diff --git a/base/allocator/partition_allocator/partition_bucket.cc b/base/allocator/partition_allocator/partition_bucket.cc index c749f47..069ebae 100644 --- a/base/allocator/partition_allocator/partition_bucket.cc +++ b/base/allocator/partition_allocator/partition_bucket.cc
@@ -92,8 +92,8 @@ PA_DCHECK(!page->slot_span_metadata.num_unprovisioned_slots); PA_DCHECK(!page->slot_span_metadata.empty_cache_index); page->slot_span_metadata.bucket = &metadata->bucket; - page->slot_span_metadata.freelist_head = - reinterpret_cast<PartitionFreelistEntry*>(slot); + page->slot_span_metadata.SetFreelistHead( + reinterpret_cast<PartitionFreelistEntry*>(slot)); auto* next_entry = reinterpret_cast<PartitionFreelistEntry*>(slot); next_entry->next = PartitionFreelistEntry::Encode(nullptr); @@ -116,7 +116,7 @@ map_extent->prev_extent = nullptr; root->direct_map_list = map_extent; - return reinterpret_cast<SlotSpanMetadata<thread_safe>*>(page); + return &page->slot_span_metadata; } } // namespace @@ -471,7 +471,7 @@ if (LIKELY(num_new_freelist_entries)) { char* freelist_pointer = first_freelist_pointer; auto* entry = reinterpret_cast<PartitionFreelistEntry*>(freelist_pointer); - slot_span->freelist_head = entry; + slot_span->SetFreelistHead(entry); while (--num_new_freelist_entries) { freelist_pointer += size; auto* next_entry = @@ -481,7 +481,7 @@ } entry->next = PartitionFreelistEntry::Encode(nullptr); } else { - slot_span->freelist_head = nullptr; + slot_span->SetFreelistHead(nullptr); } return return_object; } @@ -673,7 +673,7 @@ PartitionFreelistEntry* entry = new_slot_span->freelist_head; PartitionFreelistEntry* new_head = EncodedPartitionFreelistEntry::Decode(entry->next); - new_slot_span->freelist_head = new_head; + new_slot_span->SetFreelistHead(new_head); new_slot_span->num_allocated_slots++; return entry; }
diff --git a/base/allocator/partition_allocator/partition_page.cc b/base/allocator/partition_allocator/partition_page.cc index e6eb3ef..f87fa30f 100644 --- a/base/allocator/partition_allocator/partition_page.cc +++ b/base/allocator/partition_allocator/partition_page.cc
@@ -175,7 +175,7 @@ // Pulling this trick enables us to use a singly-linked list for all // cases, which is critical in keeping the slot span metadata structure down // to 32 bytes in size. - freelist_head = nullptr; + SetFreelistHead(nullptr); num_unprovisioned_slots = 0; PA_DCHECK(is_decommitted()); PA_DCHECK(bucket);
diff --git a/base/allocator/partition_allocator/partition_page.h b/base/allocator/partition_allocator/partition_page.h index da6b03f..ad66db6 100644 --- a/base/allocator/partition_allocator/partition_page.h +++ b/base/allocator/partition_allocator/partition_page.h
@@ -119,6 +119,8 @@ ALWAYS_INLINE void SetRawSize(size_t raw_size); ALWAYS_INLINE size_t GetRawSize() const; + ALWAYS_INLINE void SetFreelistHead(PartitionFreelistEntry* new_head); + // Returns size of the region used within a slot. The used region comprises // of actual allocated data, extras and possibly empty space. ALWAYS_INLINE size_t GetUtilizedSlotSize() const { @@ -256,8 +258,8 @@ template <bool thread_safe> ALWAYS_INLINE SlotSpanMetadata<thread_safe>* SlotSpanMetadata<thread_safe>::FromPointerNoAlignmentCheck(void* ptr) { - return reinterpret_cast<SlotSpanMetadata*>( - PartitionPage<thread_safe>::FromPointerNoAlignmentCheck(ptr)); + return &PartitionPage<thread_safe>::FromPointerNoAlignmentCheck(ptr) + ->slot_span_metadata; } // See the comment for |FromPointer|. @@ -361,6 +363,15 @@ } template <bool thread_safe> +ALWAYS_INLINE void SlotSpanMetadata<thread_safe>::SetFreelistHead( + PartitionFreelistEntry* new_head) { + PA_DCHECK(!new_head || + (reinterpret_cast<uintptr_t>(this) & kSuperPageBaseMask) == + (reinterpret_cast<uintptr_t>(new_head) & kSuperPageBaseMask)); + freelist_head = new_head; +} + +template <bool thread_safe> ALWAYS_INLINE DeferredUnmap SlotSpanMetadata<thread_safe>::Free(void* ptr) { #if DCHECK_IS_ON() auto* root = PartitionRoot<thread_safe>::FromSlotSpan(this); @@ -375,7 +386,7 @@ ptr != EncodedPartitionFreelistEntry::Decode(freelist_head->next)); auto* entry = static_cast<internal::PartitionFreelistEntry*>(ptr); entry->next = internal::PartitionFreelistEntry::Encode(freelist_head); - freelist_head = entry; + SetFreelistHead(entry); --num_allocated_slots; if (UNLIKELY(num_allocated_slots <= 0)) { return FreeSlowPath();
diff --git a/base/callback_list.h b/base/callback_list.h index 78bea71..1778541 100644 --- a/base/callback_list.h +++ b/base/callback_list.h
@@ -5,7 +5,6 @@ #ifndef BASE_CALLBACK_LIST_H_ #define BASE_CALLBACK_LIST_H_ -#include <algorithm> #include <list> #include <memory> #include <utility> @@ -17,6 +16,7 @@ #include "base/check.h" #include "base/compiler_specific.h" #include "base/memory/weak_ptr.h" +#include "base/ranges/algorithm.h" #include "base/stl_util.h" // OVERVIEW: @@ -163,8 +163,8 @@ // Returns whether the list of registered callbacks is empty (from an external // perspective -- meaning no remaining callbacks are live). bool empty() const { - return std::all_of(callbacks_.cbegin(), callbacks_.cend(), - [](const auto& callback) { return callback.is_null(); }); + return ranges::all_of( + callbacks_, [](const auto& callback) { return callback.is_null(); }); } // Calls all registered callbacks that are not canceled beforehand. If any
diff --git a/base/command_line.cc b/base/command_line.cc index 440484b..6f0a3471 100644 --- a/base/command_line.cc +++ b/base/command_line.cc
@@ -4,13 +4,13 @@ #include "base/command_line.h" -#include <algorithm> #include <ostream> #include "base/containers/span.h" #include "base/files/file_path.h" #include "base/logging.h" #include "base/notreached.h" +#include "base/ranges/algorithm.h" #include "base/stl_util.h" #include "base/strings/strcat.h" #include "base/strings/string_split.h" @@ -411,8 +411,7 @@ // Gather all arguments after the last switch (may include kSwitchTerminator). StringVector args(argv_.begin() + begin_args_, argv_.end()); // Erase only the first kSwitchTerminator (maybe "--" is a legitimate page?) - auto switch_terminator = - std::find(args.begin(), args.end(), kSwitchTerminator); + auto switch_terminator = ranges::find(args, kSwitchTerminator); if (switch_terminator != args.end()) args.erase(switch_terminator); return args;
diff --git a/base/containers/checked_range_unittest.cc b/base/containers/checked_range_unittest.cc index 28e813b..a84496d 100644 --- a/base/containers/checked_range_unittest.cc +++ b/base/containers/checked_range_unittest.cc
@@ -8,6 +8,7 @@ #include <initializer_list> #include <type_traits> +#include "base/ranges/algorithm.h" #include "base/strings/string_piece.h" #include "testing/gtest/include/gtest/gtest.h" @@ -151,9 +152,9 @@ std::vector<int> vector = {3, 1, 4, 2, 5}; CheckedContiguousRange<std::vector<int>> range(vector); - EXPECT_FALSE(std::is_sorted(vector.begin(), vector.end())); + EXPECT_FALSE(ranges::is_sorted(vector)); std::sort(range.data(), range.data() + range.size()); - EXPECT_TRUE(std::is_sorted(vector.begin(), vector.end())); + EXPECT_TRUE(ranges::is_sorted(vector)); } TEST(CheckedContiguousRange, DataSizeEmpty_Constexpr) {
diff --git a/base/containers/circular_deque.h b/base/containers/circular_deque.h index 4fc61c2..e8782a7 100644 --- a/base/containers/circular_deque.h +++ b/base/containers/circular_deque.h
@@ -14,6 +14,7 @@ #include "base/check_op.h" #include "base/containers/vector_buffer.h" #include "base/macros.h" +#include "base/ranges/algorithm.h" #include "base/stl_util.h" #include "base/template_util.h" @@ -1097,7 +1098,7 @@ // Implementations of base::Erase[If] (see base/stl_util.h). template <class T, class Value> size_t Erase(circular_deque<T>& container, const Value& value) { - auto it = std::remove(container.begin(), container.end(), value); + auto it = ranges::remove(container, value); size_t removed = std::distance(it, container.end()); container.erase(it, container.end()); return removed; @@ -1105,7 +1106,7 @@ template <class T, class Predicate> size_t EraseIf(circular_deque<T>& container, Predicate pred) { - auto it = std::remove_if(container.begin(), container.end(), pred); + auto it = ranges::remove_if(container, pred); size_t removed = std::distance(it, container.end()); container.erase(it, container.end()); return removed;
diff --git a/base/containers/flat_map_unittest.cc b/base/containers/flat_map_unittest.cc index 3512528..3cf18cd 100644 --- a/base/containers/flat_map_unittest.cc +++ b/base/containers/flat_map_unittest.cc
@@ -8,6 +8,7 @@ #include <vector> #include "base/macros.h" +#include "base/ranges/algorithm.h" #include "base/strings/string_piece.h" #include "base/test/move_only_int.h" #include "testing/gmock/include/gmock/gmock.h" @@ -214,7 +215,7 @@ base::flat_map<MoveOnlyInt, int> map; for (int i : {3, 1, 5, 6, 8, 7, 0, 9, 4, 2}) { map.insert_or_assign(MoveOnlyInt(i), i); - EXPECT_TRUE(std::is_sorted(map.begin(), map.end())); + EXPECT_TRUE(ranges::is_sorted(map)); } } @@ -249,7 +250,7 @@ base::flat_map<MoveOnlyInt, int> map; for (int i : {3, 1, 5, 6, 8, 7, 0, 9, 4, 2}) { map.insert_or_assign(map.end(), MoveOnlyInt(i), i); - EXPECT_TRUE(std::is_sorted(map.begin(), map.end())); + EXPECT_TRUE(ranges::is_sorted(map)); } } @@ -294,7 +295,7 @@ base::flat_map<MoveOnlyInt, int> map; for (int i : {3, 1, 5, 6, 8, 7, 0, 9, 4, 2}) { map.try_emplace(MoveOnlyInt(i), i); - EXPECT_TRUE(std::is_sorted(map.begin(), map.end())); + EXPECT_TRUE(ranges::is_sorted(map)); } } @@ -340,7 +341,7 @@ base::flat_map<MoveOnlyInt, int> map; for (int i : {3, 1, 5, 6, 8, 7, 0, 9, 4, 2}) { map.try_emplace(map.end(), MoveOnlyInt(i), i); - EXPECT_TRUE(std::is_sorted(map.begin(), map.end())); + EXPECT_TRUE(ranges::is_sorted(map)); } }
diff --git a/base/containers/flat_tree.h b/base/containers/flat_tree.h index 1d779f2c..cee0a3b 100644 --- a/base/containers/flat_tree.h +++ b/base/containers/flat_tree.h
@@ -11,6 +11,7 @@ #include <utility> #include <vector> +#include "base/ranges/algorithm.h" #include "base/stl_util.h" #include "base/template_util.h" @@ -756,11 +757,10 @@ void flat_tree<Key, Value, GetKeyFromValue, KeyCompare>::replace( underlying_type&& body) { // Ensure that |body| is sorted and has no repeated elements. - DCHECK(std::is_sorted(body.begin(), body.end(), value_comp())); - DCHECK(std::adjacent_find(body.begin(), body.end(), - [this](const auto& lhs, const auto& rhs) { - return !value_comp()(lhs, rhs); - }) == body.end()); + DCHECK(ranges::is_sorted(body, value_comp())); + DCHECK(ranges::adjacent_find(body, [this](const auto& lhs, const auto& rhs) { + return !value_comp()(lhs, rhs); + }) == body.end()); impl_.body_ = std::move(body); } @@ -886,7 +886,7 @@ const KeyTypeOrK<K>& key_ref = key; KeyValueCompare key_value(impl_.get_key_comp()); - return std::lower_bound(begin(), end(), key_ref, key_value); + return ranges::lower_bound(*this, key_ref, key_value); } template <class Key, class Value, class GetKeyFromValue, class KeyCompare> @@ -907,7 +907,7 @@ const KeyTypeOrK<K>& key_ref = key; KeyValueCompare key_value(impl_.get_key_comp()); - return std::upper_bound(begin(), end(), key_ref, key_value); + return ranges::upper_bound(*this, key_ref, key_value); } // ---------------------------------------------------------------------------- @@ -981,7 +981,7 @@ base::internal::flat_tree<Key, Value, GetKeyFromValue, KeyCompare>& container, Predicate pred) { - auto it = std::remove_if(container.begin(), container.end(), pred); + auto it = ranges::remove_if(container, pred); size_t removed = std::distance(it, container.end()); container.erase(it, container.end()); return removed;
diff --git a/base/containers/flat_tree_unittest.cc b/base/containers/flat_tree_unittest.cc index 8eab5b6..24b0895 100644 --- a/base/containers/flat_tree_unittest.cc +++ b/base/containers/flat_tree_unittest.cc
@@ -35,6 +35,7 @@ #include <string> #include <vector> +#include "base/ranges/algorithm.h" #include "base/template_util.h" #include "base/test/move_only_int.h" #include "testing/gmock/include/gmock/gmock.h" @@ -218,8 +219,8 @@ Tree cont({{0, 0}, {1, 0}, {0, 1}, {2, 0}, {0, 2}, {1, 1}}); auto AllOfSecondsAreZero = [&cont] { - return std::all_of(cont.begin(), cont.end(), - [](const Pair& elem) { return elem.second == 0; }); + return ranges::all_of(cont, + [](const Pair& elem) { return elem.second == 0; }); }; EXPECT_TRUE(AllOfSecondsAreZero()) << "constructor should be stable"; @@ -975,11 +976,11 @@ TEST(FlatTree, KeyComp) { ReversedTree cont({1, 2, 3, 4, 5}); - EXPECT_TRUE(std::is_sorted(cont.begin(), cont.end(), cont.key_comp())); + EXPECT_TRUE(ranges::is_sorted(cont, cont.key_comp())); int new_elements[] = {6, 7, 8, 9, 10}; std::copy(std::begin(new_elements), std::end(new_elements), std::inserter(cont, cont.end())); - EXPECT_TRUE(std::is_sorted(cont.begin(), cont.end(), cont.key_comp())); + EXPECT_TRUE(ranges::is_sorted(cont, cont.key_comp())); } // value_compare value_comp() const @@ -987,11 +988,11 @@ TEST(FlatTree, ValueComp) { ReversedTree cont({1, 2, 3, 4, 5}); - EXPECT_TRUE(std::is_sorted(cont.begin(), cont.end(), cont.value_comp())); + EXPECT_TRUE(ranges::is_sorted(cont, cont.value_comp())); int new_elements[] = {6, 7, 8, 9, 10}; std::copy(std::begin(new_elements), std::end(new_elements), std::inserter(cont, cont.end())); - EXPECT_TRUE(std::is_sorted(cont.begin(), cont.end(), cont.value_comp())); + EXPECT_TRUE(ranges::is_sorted(cont, cont.value_comp())); } // ----------------------------------------------------------------------------
diff --git a/base/containers/span_unittest.cc b/base/containers/span_unittest.cc index 58f4eaf..f75dc6a0 100644 --- a/base/containers/span_unittest.cc +++ b/base/containers/span_unittest.cc
@@ -6,7 +6,6 @@ #include <stdint.h> -#include <algorithm> #include <iterator> #include <memory> #include <string> @@ -14,6 +13,7 @@ #include <vector> #include "base/containers/checked_iterators.h" +#include "base/ranges/algorithm.h" #include "base/stl_util.h" #include "base/strings/string_piece.h" #include "testing/gmock/include/gmock/gmock.h" @@ -1407,7 +1407,7 @@ int array[] = {5, 4, 3, 2, 1}; span<int> dynamic_span = array; - std::sort(dynamic_span.begin(), dynamic_span.end()); + ranges::sort(dynamic_span); EXPECT_THAT(array, ElementsAre(1, 2, 3, 4, 5)); std::sort(dynamic_span.rbegin(), dynamic_span.rend()); EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1)); @@ -1415,7 +1415,7 @@ span<int, 5> static_span = array; std::sort(static_span.rbegin(), static_span.rend(), std::greater<>()); EXPECT_THAT(array, ElementsAre(1, 2, 3, 4, 5)); - std::sort(static_span.begin(), static_span.end(), std::greater<>()); + ranges::sort(static_span, std::greater<>()); EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1)); }
diff --git a/base/containers/unique_ptr_adapters_unittest.cc b/base/containers/unique_ptr_adapters_unittest.cc index 8a107f32..da2d719 100644 --- a/base/containers/unique_ptr_adapters_unittest.cc +++ b/base/containers/unique_ptr_adapters_unittest.cc
@@ -4,10 +4,10 @@ #include "base/containers/unique_ptr_adapters.h" -#include <algorithm> #include <memory> #include <vector> +#include "base/ranges/algorithm.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { @@ -76,19 +76,19 @@ v.push_back(std::move(foo_ptr2)); { - auto iter = std::find_if(v.begin(), v.end(), UniquePtrMatcher<Foo>(foo1)); + auto iter = ranges::find_if(v, UniquePtrMatcher<Foo>(foo1)); ASSERT_TRUE(iter != v.end()); EXPECT_EQ(foo1, iter->get()); } { - auto iter = std::find_if(v.begin(), v.end(), UniquePtrMatcher<Foo>(foo2)); + auto iter = ranges::find_if(v, UniquePtrMatcher<Foo>(foo2)); ASSERT_TRUE(iter != v.end()); EXPECT_EQ(foo2, iter->get()); } { - auto iter = std::find_if(v.begin(), v.end(), MatchesUniquePtr(foo2)); + auto iter = ranges::find_if(v, MatchesUniquePtr(foo2)); ASSERT_TRUE(iter != v.end()); EXPECT_EQ(foo2, iter->get()); } @@ -110,22 +110,19 @@ v.push_back(std::move(foo_ptr2)); { - auto iter = std::find_if(v.begin(), v.end(), - UniquePtrMatcher<Foo, TestDeleter>(foo1)); + auto iter = ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(foo1)); ASSERT_TRUE(iter != v.end()); EXPECT_EQ(foo1, iter->get()); } { - auto iter = std::find_if(v.begin(), v.end(), - UniquePtrMatcher<Foo, TestDeleter>(foo2)); + auto iter = ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(foo2)); ASSERT_TRUE(iter != v.end()); EXPECT_EQ(foo2, iter->get()); } { - auto iter = std::find_if(v.begin(), v.end(), - MatchesUniquePtr<Foo, TestDeleter>(foo2)); + auto iter = ranges::find_if(v, MatchesUniquePtr<Foo, TestDeleter>(foo2)); ASSERT_TRUE(iter != v.end()); EXPECT_EQ(foo2, iter->get()); }
diff --git a/base/debug/activity_analyzer.cc b/base/debug/activity_analyzer.cc index 143174a..c7c2dec 100644 --- a/base/debug/activity_analyzer.cc +++ b/base/debug/activity_analyzer.cc
@@ -4,7 +4,6 @@ #include "base/debug/activity_analyzer.h" -#include <algorithm> #include <utility> #include "base/check_op.h" @@ -14,6 +13,7 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/no_destructor.h" +#include "base/ranges/algorithm.h" #include "base/stl_util.h" #include "base/strings/string_util.h" @@ -398,7 +398,7 @@ } // Reverse the list of PIDs so that they get popped in the order found. - std::reverse(process_ids_.begin(), process_ids_.end()); + ranges::reverse(process_ids_); } } // namespace debug
diff --git a/base/debug/task_trace.cc b/base/debug/task_trace.cc index bea5f1b..08f32d2 100644 --- a/base/debug/task_trace.cc +++ b/base/debug/task_trace.cc
@@ -4,13 +4,13 @@ #include "base/debug/task_trace.h" +#include "base/ranges/algorithm.h" #include "build/build_config.h" #if defined(OS_ANDROID) #include <android/log.h> #endif // OS_ANDROID -#include <algorithm> #include <iostream> #include <sstream> @@ -55,8 +55,7 @@ return; std::array<const void*, PendingTask::kTaskBacktraceLength + 1> task_trace; task_trace[0] = current_task->posted_from.program_counter(); - std::copy(current_task->task_backtrace.begin(), - current_task->task_backtrace.end(), task_trace.begin() + 1); + ranges::copy(current_task->task_backtrace, task_trace.begin() + 1); size_t length = 0; while (length < task_trace.size() && task_trace[length]) ++length;
diff --git a/base/feature_list_unittest.cc b/base/feature_list_unittest.cc index c687e65..1cef7f4 100644 --- a/base/feature_list_unittest.cc +++ b/base/feature_list_unittest.cc
@@ -6,7 +6,6 @@ #include <stddef.h> -#include <algorithm> #include <utility> #include <vector> @@ -14,6 +13,7 @@ #include "base/memory/read_only_shared_memory_region.h" #include "base/metrics/field_trial.h" #include "base/metrics/persistent_memory_allocator.h" +#include "base/ranges/algorithm.h" #include "base/stl_util.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" @@ -39,7 +39,7 @@ std::string SortFeatureListString(const std::string& feature_list) { std::vector<base::StringPiece> features = FeatureList::SplitFeatureListString(feature_list); - std::sort(features.begin(), features.end()); + ranges::sort(features); return JoinString(features, ","); }
diff --git a/base/hash/sha1_perftest.cc b/base/hash/sha1_perftest.cc index 547cd58..72d46cb1 100644 --- a/base/hash/sha1_perftest.cc +++ b/base/hash/sha1_perftest.cc
@@ -6,11 +6,11 @@ #include <stddef.h> #include <stdint.h> -#include <algorithm> #include <string> #include <vector> #include "base/rand_util.h" +#include "base/ranges/algorithm.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/time/time.h" @@ -48,7 +48,7 @@ utime[i] = TimeTicks::Now() - start; total_test_time += utime[i]; } - std::sort(utime.begin(), utime.end()); + ranges::sort(utime); } reporter.AddResult(kMetricRuntime, total_test_time.InMicrosecondsF()); @@ -67,8 +67,8 @@ // Convert to a comma-separated string so we can report every data point. std::vector<std::string> rate_strings(utime.size()); - std::transform(utime.cbegin(), utime.cend(), rate_strings.begin(), - [rate](const auto& t) { return NumberToString(rate(t)); }); + ranges::transform(utime, rate_strings.begin(), + [rate](const auto& t) { return NumberToString(rate(t)); }); reporter.AddResultList(kMetricThroughput, JoinString(rate_strings, ",")); }
diff --git a/base/i18n/break_iterator_unittest.cc b/base/i18n/break_iterator_unittest.cc index f7c3e8e..0501424b 100644 --- a/base/i18n/break_iterator_unittest.cc +++ b/base/i18n/break_iterator_unittest.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include <vector> +#include "base/ranges/algorithm.h" #include "base/stl_util.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" @@ -414,8 +415,7 @@ sentence_breaks.push_back(24); sentence_breaks.push_back(42); for (size_t i = 0; i < str.size(); i++) { - if (std::find(sentence_breaks.begin(), sentence_breaks.end(), i) != - sentence_breaks.end()) { + if (ranges::find(sentence_breaks, i) != sentence_breaks.end()) { EXPECT_TRUE(iter.IsSentenceBoundary(i)) << " at index=" << i; } else { EXPECT_FALSE(iter.IsSentenceBoundary(i)) << " at index=" << i;
diff --git a/base/immediate_crash_unittest.cc b/base/immediate_crash_unittest.cc index 6b20278..b27c78e 100644 --- a/base/immediate_crash_unittest.cc +++ b/base/immediate_crash_unittest.cc
@@ -13,6 +13,7 @@ #include "base/files/file_path.h" #include "base/optional.h" #include "base/path_service.h" +#include "base/ranges/algorithm.h" #include "base/scoped_native_library.h" #include "base/strings/string_number_conversions.h" #include "build/build_config.h" @@ -207,7 +208,7 @@ ASSERT_NO_FATAL_FAILURE(GetTestFunctionInstructions(&body)); SCOPED_TRACE(HexEncode(body.data(), body.size() * sizeof(Instruction))); - auto it = std::find(body.begin(), body.end(), kRet); + auto it = ranges::find(body, kRet); ASSERT_NE(body.end(), it) << "Failed to find return opcode"; it++;
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc index fcb479c..5724ecaf 100644 --- a/base/json/json_parser.cc +++ b/base/json/json_parser.cc
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/notreached.h" #include "base/numerics/safe_conversions.h" +#include "base/ranges/algorithm.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" @@ -441,7 +442,7 @@ ConsumeChar(); // Closing '}'. // Reverse |dict_storage| to keep the last of elements with the same key in // the input. - std::reverse(dict_storage.begin(), dict_storage.end()); + ranges::reverse(dict_storage); return Value(Value::DictStorage(std::move(dict_storage))); }
diff --git a/base/memory/platform_shared_memory_region_unittest.cc b/base/memory/platform_shared_memory_region_unittest.cc index 928ef8c..8588f9d 100644 --- a/base/memory/platform_shared_memory_region_unittest.cc +++ b/base/memory/platform_shared_memory_region_unittest.cc
@@ -7,6 +7,7 @@ #include "base/check.h" #include "base/memory/shared_memory_mapping.h" #include "base/process/process_metrics.h" +#include "base/ranges/algorithm.h" #include "base/system/sys_info.h" #include "base/test/gtest_util.h" #include "base/test/test_shared_memory_util.h" @@ -250,11 +251,10 @@ ASSERT_TRUE(base::debug::ReadProcMaps(&proc_maps)); std::vector<base::debug::MappedMemoryRegion> regions; ASSERT_TRUE(base::debug::ParseProcMaps(proc_maps, ®ions)); - auto it = - std::find_if(regions.begin(), regions.end(), - [addr](const base::debug::MappedMemoryRegion& region) { - return region.start == reinterpret_cast<uintptr_t>(addr); - }); + auto it = ranges::find_if( + regions, [addr](const base::debug::MappedMemoryRegion& region) { + return region.start == reinterpret_cast<uintptr_t>(addr); + }); ASSERT_TRUE(it != regions.end()); // PROT_READ may imply PROT_EXEC on some architectures, so just check that // permissions don't contain PROT_WRITE bit.
diff --git a/base/memory/shared_memory_mapping_unittest.cc b/base/memory/shared_memory_mapping_unittest.cc index 48fba74..796e869 100644 --- a/base/memory/shared_memory_mapping_unittest.cc +++ b/base/memory/shared_memory_mapping_unittest.cc
@@ -6,12 +6,12 @@ #include <stdint.h> -#include <algorithm> #include <limits> #include "base/containers/span.h" #include "base/memory/read_only_shared_memory_region.h" #include "base/memory/writable_shared_memory_region.h" +#include "base/ranges/algorithm.h" #include "base/test/metrics/histogram_tester.h" #include "build/build_config.h" #include "testing/gmock/include/gmock/gmock.h" @@ -67,7 +67,7 @@ span<const uint32_t> read_span = read_mapping_.GetMemoryAsSpan<uint32_t>(); ASSERT_EQ(2u, read_span.size()); - std::fill(write_span.begin(), write_span.end(), 0); + ranges::fill(write_span, 0); EXPECT_EQ(0u, read_span[0]); EXPECT_EQ(0u, read_span[1]); @@ -92,7 +92,7 @@ span<const uint32_t> read_span_2 = read_mapping_.GetMemoryAsSpan<uint32_t>(1); ASSERT_EQ(1u, read_span_2.size()); - std::fill(write_span.begin(), write_span.end(), 0); + ranges::fill(write_span, 0); EXPECT_EQ(0u, read_span[0]); EXPECT_EQ(0u, read_span[1]); EXPECT_EQ(0u, read_span_2[0]); @@ -103,7 +103,7 @@ EXPECT_EQ(0x08070605u, read_span[1]); EXPECT_EQ(0x04030201u, read_span_2[0]); - std::fill(write_span_2.begin(), write_span_2.end(), 0); + ranges::fill(write_span_2, 0); EXPECT_EQ(0u, read_span[0]); EXPECT_EQ(0x08070605u, read_span[1]); EXPECT_EQ(0u, read_span_2[0]);
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc index 6ae1afd..99524406 100644 --- a/base/metrics/histogram.cc +++ b/base/metrics/histogram.cc
@@ -13,7 +13,6 @@ #include <limits.h> #include <math.h> -#include <algorithm> #include <string> #include <utility> @@ -29,6 +28,7 @@ #include "base/metrics/sample_vector.h" #include "base/metrics/statistics_recorder.h" #include "base/pickle.h" +#include "base/ranges/algorithm.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -1245,8 +1245,8 @@ std::vector<int> ranges = *custom_ranges_; ranges.push_back(0); // Ensure we have a zero value. ranges.push_back(HistogramBase::kSampleType_MAX); - std::sort(ranges.begin(), ranges.end()); - ranges.erase(std::unique(ranges.begin(), ranges.end()), ranges.end()); + ranges::sort(ranges); + ranges.erase(ranges::unique(ranges), ranges.end()); BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); for (uint32_t i = 0; i < ranges.size(); i++) {
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc index 58a442d..b8cacab8 100644 --- a/base/metrics/statistics_recorder.cc +++ b/base/metrics/statistics_recorder.cc
@@ -16,6 +16,7 @@ #include "base/metrics/metrics_hashes.h" #include "base/metrics/persistent_histogram_allocator.h" #include "base/metrics/record_histogram_checker.h" +#include "base/ranges/algorithm.h" #include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "base/values.h" @@ -366,7 +367,7 @@ // static StatisticsRecorder::Histograms StatisticsRecorder::Sort(Histograms histograms) { - std::sort(histograms.begin(), histograms.end(), &HistogramNameLesser); + ranges::sort(histograms, &HistogramNameLesser); return histograms; } @@ -376,12 +377,12 @@ const std::string& query) { // Need a C-string query for comparisons against C-string histogram name. const char* const query_string = query.c_str(); - histograms.erase(std::remove_if(histograms.begin(), histograms.end(), - [query_string](const HistogramBase* const h) { - return !strstr(h->histogram_name(), - query_string); - }), - histograms.end()); + histograms.erase( + ranges::remove_if(histograms, + [query_string](const HistogramBase* const h) { + return !strstr(h->histogram_name(), query_string); + }), + histograms.end()); return histograms; } @@ -389,10 +390,11 @@ StatisticsRecorder::Histograms StatisticsRecorder::NonPersistent( Histograms histograms) { histograms.erase( - std::remove_if(histograms.begin(), histograms.end(), - [](const HistogramBase* const h) { - return (h->flags() & HistogramBase::kIsPersistent) != 0; - }), + ranges::remove_if(histograms, + [](const HistogramBase* const h) { + return (h->flags() & HistogramBase::kIsPersistent) != + 0; + }), histograms.end()); return histograms; }
diff --git a/base/observer_list.h b/base/observer_list.h index 28369a25..834ee64e 100644 --- a/base/observer_list.h +++ b/base/observer_list.h
@@ -17,6 +17,7 @@ #include "base/gtest_prod_util.h" #include "base/notreached.h" #include "base/observer_list_internal.h" +#include "base/ranges/algorithm.h" #include "base/sequence_checker.h" #include "base/stl_util.h" @@ -279,9 +280,8 @@ // not in this list. void RemoveObserver(const ObserverType* obs) { DCHECK(obs); - const auto it = - std::find_if(observers_.begin(), observers_.end(), - [obs](const auto& o) { return o.IsEqual(obs); }); + const auto it = ranges::find_if( + observers_, [obs](const auto& o) { return o.IsEqual(obs); }); if (it == observers_.end()) return; @@ -300,9 +300,9 @@ // probably DCHECK, but some client code currently does pass null. if (obs == nullptr) return false; - return std::find_if(observers_.begin(), observers_.end(), - [obs](const auto& o) { return o.IsEqual(obs); }) != - observers_.end(); + return ranges::find_if(observers_, [obs](const auto& o) { + return o.IsEqual(obs); + }) != observers_.end(); } // Removes all the observers from this list.
diff --git a/base/process/process_metrics_unittest.cc b/base/process/process_metrics_unittest.cc index a50f09b..70898d3 100644 --- a/base/process/process_metrics_unittest.cc +++ b/base/process/process_metrics_unittest.cc
@@ -19,6 +19,7 @@ #include "base/macros.h" #include "base/memory/shared_memory_mapping.h" #include "base/memory/writable_shared_memory_region.h" +#include "base/ranges/algorithm.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -787,13 +788,13 @@ // Should have at least the test runner thread and the thread spawned above. EXPECT_GE(prev_thread_times.size(), 2u); - EXPECT_TRUE(std::any_of( - prev_thread_times.begin(), prev_thread_times.end(), + EXPECT_TRUE(ranges::any_of( + prev_thread_times, [&thread1](const std::pair<PlatformThreadId, base::TimeDelta>& entry) { return entry.first == thread1.GetThreadId(); })); - EXPECT_TRUE(std::any_of( - prev_thread_times.begin(), prev_thread_times.end(), + EXPECT_TRUE(ranges::any_of( + prev_thread_times, [](const std::pair<PlatformThreadId, base::TimeDelta>& entry) { return entry.first == base::PlatformThread::CurrentId(); })); @@ -809,16 +810,16 @@ // The stopped thread may still be reported until the kernel cleans it up. EXPECT_GE(prev_thread_times.size(), 1u); - EXPECT_TRUE(std::any_of( - current_thread_times.begin(), current_thread_times.end(), + EXPECT_TRUE(ranges::any_of( + current_thread_times, [](const std::pair<PlatformThreadId, base::TimeDelta>& entry) { return entry.first == base::PlatformThread::CurrentId(); })); // Reported times should not decrease. for (const auto& entry : current_thread_times) { - auto prev_it = std::find_if( - prev_thread_times.begin(), prev_thread_times.end(), + auto prev_it = ranges::find_if( + prev_thread_times, [&entry]( const std::pair<PlatformThreadId, base::TimeDelta>& prev_entry) { return entry.first == prev_entry.first; @@ -868,8 +869,8 @@ // Reported times should not decrease. for (const auto& entry : current_thread_times) { - auto prev_it = std::find_if( - prev_thread_times.begin(), prev_thread_times.end(), + auto prev_it = ranges::find_if( + prev_thread_times, [&entry](const ProcessMetrics::ThreadTimeInState& prev_entry) { return entry.thread_id == prev_entry.thread_id && entry.core_type == prev_entry.core_type &&
diff --git a/base/profiler/arm_cfi_table.cc b/base/profiler/arm_cfi_table.cc index a9593b4..04f9737 100644 --- a/base/profiler/arm_cfi_table.cc +++ b/base/profiler/arm_cfi_table.cc
@@ -4,7 +4,7 @@ #include "base/profiler/arm_cfi_table.h" -#include <algorithm> +#include "base/ranges/algorithm.h" namespace base { @@ -91,8 +91,7 @@ // Find the required function address in UNW_INDEX as the last function lower // or equal to |address| (the value right before the result of upper_bound(), // if any). - auto func_it = std::upper_bound(function_addresses_.begin(), - function_addresses_.end(), address); + auto func_it = ranges::upper_bound(function_addresses_, address); // If no function comes before |address|, no CFI entry is returned. if (func_it == function_addresses_.begin()) return nullopt; @@ -157,4 +156,4 @@ return last_frame_entry; } -} // namespace base \ No newline at end of file +} // namespace base
diff --git a/base/profiler/metadata_recorder_unittest.cc b/base/profiler/metadata_recorder_unittest.cc index 4aff812..33332c1 100644 --- a/base/profiler/metadata_recorder_unittest.cc +++ b/base/profiler/metadata_recorder_unittest.cc
@@ -4,6 +4,7 @@ #include "base/profiler/metadata_recorder.h" +#include "base/ranges/algorithm.h" #include "base/test/gtest_util.h" #include "base/test/metrics/histogram_tester.h" #include "testing/gmock/include/gmock/gmock.h" @@ -213,7 +214,7 @@ } MetadataRecorder::ItemArray items_arr; - std::copy(items_set.begin(), items_set.end(), items_arr.begin()); + ranges::copy(items_set, items_arr.begin()); MetadataRecorder::ItemArray recorder_items; size_t recorder_item_count =
diff --git a/base/profiler/module_cache.cc b/base/profiler/module_cache.cc index 9c72296..b36ba46 100644 --- a/base/profiler/module_cache.cc +++ b/base/profiler/module_cache.cc
@@ -4,10 +4,11 @@ #include "base/profiler/module_cache.h" -#include <algorithm> #include <iterator> #include <utility> +#include "base/ranges/algorithm.h" + namespace base { namespace { @@ -69,8 +70,8 @@ // // stable_partition is O(m*log(r)) where m is the number of current modules // and r is the number of modules to remove. insert and erase are both O(r). - auto first_module_defunct_modules = std::stable_partition( - non_native_modules_.begin(), non_native_modules_.end(), + auto first_module_defunct_modules = ranges::stable_partition( + non_native_modules_, [&defunct_modules_set](const std::unique_ptr<const Module>& module) { return defunct_modules_set.find(module.get()) == defunct_modules_set.end();
diff --git a/base/profiler/stack_sampler_impl.cc b/base/profiler/stack_sampler_impl.cc index a05b10e..dd58645 100644 --- a/base/profiler/stack_sampler_impl.cc +++ b/base/profiler/stack_sampler_impl.cc
@@ -16,6 +16,7 @@ #include "base/profiler/stack_copier.h" #include "base/profiler/suspendable_thread_delegate.h" #include "base/profiler/unwinder.h" +#include "base/ranges/algorithm.h" #include "build/build_config.h" // IMPORTANT NOTE: Some functions within this implementation are invoked while @@ -169,11 +170,10 @@ do { // Choose an authoritative unwinder for the current module. Use the first // unwinder that thinks it can unwind from the current frame. - auto unwinder = - std::find_if(unwinders.begin(), unwinders.end(), - [&stack](const std::unique_ptr<Unwinder>& unwinder) { - return unwinder->CanUnwindFrom(stack.back()); - }); + auto unwinder = ranges::find_if( + unwinders, [&stack](const std::unique_ptr<Unwinder>& unwinder) { + return unwinder->CanUnwindFrom(stack.back()); + }); if (unwinder == unwinders.end()) return stack;
diff --git a/base/profiler/stack_sampling_profiler_unittest.cc b/base/profiler/stack_sampling_profiler_unittest.cc index 7951dfe..7ed7e4d 100644 --- a/base/profiler/stack_sampling_profiler_unittest.cc +++ b/base/profiler/stack_sampling_profiler_unittest.cc
@@ -5,7 +5,6 @@ #include <stddef.h> #include <stdint.h> -#include <algorithm> #include <cstdlib> #include <memory> #include <set> @@ -26,6 +25,7 @@ #include "base/profiler/stack_sampling_profiler.h" #include "base/profiler/stack_sampling_profiler_test_util.h" #include "base/profiler/unwinder.h" +#include "base/ranges/algorithm.h" #include "base/run_loop.h" #include "base/scoped_native_library.h" #include "base/stl_util.h" @@ -270,10 +270,10 @@ const std::vector<std::unique_ptr<TestProfilerInfo>>& infos) { // Map unique_ptrs to something that WaitMany can accept. std::vector<WaitableEvent*> sampling_completed_rawptrs(infos.size()); - std::transform(infos.begin(), infos.end(), sampling_completed_rawptrs.begin(), - [](const std::unique_ptr<TestProfilerInfo>& info) { - return &info.get()->completed; - }); + ranges::transform(infos, sampling_completed_rawptrs.begin(), + [](const std::unique_ptr<TestProfilerInfo>& info) { + return &info.get()->completed; + }); // Wait for one profiler to finish. return WaitableEvent::WaitMany(sampling_completed_rawptrs.data(), sampling_completed_rawptrs.size());
diff --git a/base/sampling_heap_profiler/poisson_allocation_sampler.cc b/base/sampling_heap_profiler/poisson_allocation_sampler.cc index 0cae9f7..ea7ff8d3 100644 --- a/base/sampling_heap_profiler/poisson_allocation_sampler.cc +++ b/base/sampling_heap_profiler/poisson_allocation_sampler.cc
@@ -4,7 +4,6 @@ #include "base/sampling_heap_profiler/poisson_allocation_sampler.h" -#include <algorithm> #include <atomic> #include <cmath> #include <memory> @@ -17,6 +16,7 @@ #include "base/no_destructor.h" #include "base/partition_alloc_buildflags.h" #include "base/rand_util.h" +#include "base/ranges/algorithm.h" #include "build/build_config.h" #if defined(OS_APPLE) || defined(OS_ANDROID) @@ -571,8 +571,7 @@ void PoissonAllocationSampler::AddSamplesObserver(SamplesObserver* observer) { ScopedMuteThreadSamples no_reentrancy_scope; AutoLock lock(mutex_); - DCHECK(std::find(observers_.begin(), observers_.end(), observer) == - observers_.end()); + DCHECK(ranges::find(observers_, observer) == observers_.end()); observers_.push_back(observer); InstallAllocatorHooksOnce(); g_running = !observers_.empty(); @@ -582,7 +581,7 @@ SamplesObserver* observer) { ScopedMuteThreadSamples no_reentrancy_scope; AutoLock lock(mutex_); - auto it = std::find(observers_.begin(), observers_.end(), observer); + auto it = ranges::find(observers_, observer); DCHECK(it != observers_.end()); observers_.erase(it); g_running = !observers_.empty();
diff --git a/base/scoped_observer.h b/base/scoped_observer.h index 0e3a107e..f97265f 100644 --- a/base/scoped_observer.h +++ b/base/scoped_observer.h
@@ -7,10 +7,10 @@ #include <stddef.h> -#include <algorithm> #include <vector> #include "base/check.h" +#include "base/ranges/algorithm.h" #include "base/stl_util.h" // ScopedObserver is used to keep track of the set of sources an object has @@ -56,7 +56,7 @@ // Remove the object passed to the constructor as an observer from |source|. void Remove(Source* source) { - auto it = std::find(sources_.begin(), sources_.end(), source); + auto it = base::ranges::find(sources_, source); DCHECK(it != sources_.end()); sources_.erase(it); (source->*RemoveObsFn)(observer_);
diff --git a/base/strings/abseil_string_conversions.cc b/base/strings/abseil_string_conversions.cc index 7e594efa..9933b5f 100644 --- a/base/strings/abseil_string_conversions.cc +++ b/base/strings/abseil_string_conversions.cc
@@ -4,10 +4,10 @@ #include "base/strings/abseil_string_conversions.h" -#include <algorithm> #include <vector> #include "base/containers/span.h" +#include "base/ranges/algorithm.h" #include "base/strings/string_piece.h" #include "third_party/abseil-cpp/absl/strings/string_view.h" @@ -16,16 +16,14 @@ std::vector<absl::string_view> StringPiecesToStringViews( span<const StringPiece> pieces) { std::vector<absl::string_view> views(pieces.size()); - std::transform(pieces.begin(), pieces.end(), views.begin(), - &StringPieceToStringView); + ranges::transform(pieces, views.begin(), &StringPieceToStringView); return views; } std::vector<StringPiece> StringViewsToStringPieces( span<const absl::string_view> views) { std::vector<StringPiece> pieces(views.size()); - std::transform(views.begin(), views.end(), pieces.begin(), - &StringViewToStringPiece); + ranges::transform(views, pieces.begin(), &StringViewToStringPiece); return pieces; }
diff --git a/base/strings/string_util_internal.h b/base/strings/string_util_internal.h index 3ec97a7a..7229524c 100644 --- a/base/strings/string_util_internal.h +++ b/base/strings/string_util_internal.h
@@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/notreached.h" +#include "base/ranges/algorithm.h" #include "base/strings/string_piece.h" #include "base/third_party/icu/icu_utf.h" @@ -580,8 +581,7 @@ ReplacementOffset r_offset(index, static_cast<int>(formatted.size())); r_offsets.insert( - std::upper_bound(r_offsets.begin(), r_offsets.end(), r_offset, - &CompareParameter), + ranges::upper_bound(r_offsets, r_offset, &CompareParameter), r_offset); } if (index < substitutions)
diff --git a/base/synchronization/waitable_event_posix.cc b/base/synchronization/waitable_event_posix.cc index ab36f8d..adf6411 100644 --- a/base/synchronization/waitable_event_posix.cc +++ b/base/synchronization/waitable_event_posix.cc
@@ -4,13 +4,13 @@ #include <stddef.h> -#include <algorithm> #include <limits> #include <vector> #include "base/check_op.h" #include "base/debug/activity_tracker.h" #include "base/optional.h" +#include "base/ranges/algorithm.h" #include "base/synchronization/condition_variable.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" @@ -265,7 +265,7 @@ DCHECK_EQ(count, waitables.size()); - sort(waitables.begin(), waitables.end(), cmp_fst_addr); + ranges::sort(waitables, cmp_fst_addr); // The set of waitables must be distinct. Since we have just sorted by // address, we can check this cheaply by comparing pairs of consecutive
diff --git a/base/task/common/checked_lock_impl.cc b/base/task/common/checked_lock_impl.cc index 8b41e95c..cef737a 100644 --- a/base/task/common/checked_lock_impl.cc +++ b/base/task/common/checked_lock_impl.cc
@@ -4,12 +4,12 @@ #include "base/task/common/checked_lock_impl.h" -#include <algorithm> #include <unordered_map> #include <vector> #include "base/check_op.h" #include "base/lazy_instance.h" +#include "base/ranges/algorithm.h" #include "base/synchronization/condition_variable.h" #include "base/task/common/checked_lock.h" #include "base/threading/platform_thread.h" @@ -44,8 +44,7 @@ void RecordRelease(const CheckedLockImpl* const lock) { LockVector* acquired_locks = GetAcquiredLocksOnCurrentThread(); - const auto iter_at_lock = - std::find(acquired_locks->begin(), acquired_locks->end(), lock); + const auto iter_at_lock = ranges::find(*acquired_locks, lock); DCHECK(iter_at_lock != acquired_locks->end()); acquired_locks->erase(iter_at_lock); }
diff --git a/base/task/common/operations_controller_unittest.cc b/base/task/common/operations_controller_unittest.cc index 0e110ed1..e7174252 100644 --- a/base/task/common/operations_controller_unittest.cc +++ b/base/task/common/operations_controller_unittest.cc
@@ -8,6 +8,7 @@ #include <cstdint> #include <utility> +#include "base/ranges/algorithm.h" #include "base/threading/platform_thread.h" #include "base/threading/simple_thread.h" #include "testing/gtest/include/gtest/gtest.h" @@ -124,8 +125,7 @@ } if (!was_started) continue; - if (std::any_of(tokens.begin(), tokens.end(), - [](const auto& token) { return !token; })) { + if (ranges::any_of(tokens, [](const auto& token) { return !token; })) { break; } }
diff --git a/base/task/common/task_annotator.cc b/base/task/common/task_annotator.cc index fe3c1e8..528105d 100644 --- a/base/task/common/task_annotator.cc +++ b/base/task/common/task_annotator.cc
@@ -11,6 +11,7 @@ #include "base/debug/alias.h" #include "base/hash/md5.h" #include "base/no_destructor.h" +#include "base/ranges/algorithm.h" #include "base/sys_byteorder.h" #include "base/threading/thread_local.h" #include "base/trace_event/base_tracing.h" @@ -148,8 +149,7 @@ task_backtrace.back() = reinterpret_cast<void*>(0x0d00d1d1d178119); task_backtrace[1] = pending_task->posted_from.program_counter(); - std::copy(pending_task->task_backtrace.begin(), - pending_task->task_backtrace.end(), task_backtrace.begin() + 2); + ranges::copy(pending_task->task_backtrace, task_backtrace.begin() + 2); task_backtrace[kStackTaskTraceSnapshotSize - 2] = reinterpret_cast<void*>(pending_task->ipc_hash); debug::Alias(&task_backtrace);
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc index d16889c..71bb0cf 100644 --- a/base/task/sequence_manager/sequence_manager_impl.cc +++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -18,6 +18,7 @@ #include "base/no_destructor.h" #include "base/optional.h" #include "base/rand_util.h" +#include "base/ranges/algorithm.h" #include "base/task/sequence_manager/real_time_domain.h" #include "base/task/sequence_manager/task_time_observer.h" #include "base/task/sequence_manager/thread_controller_impl.h" @@ -542,8 +543,7 @@ case Settings::TaskLogging::kEnabledWithBacktrace: { std::array<const void*, PendingTask::kTaskBacktraceLength + 1> task_trace; task_trace[0] = task->posted_from.program_counter(); - std::copy(task->task_backtrace.begin(), task->task_backtrace.end(), - task_trace.begin() + 1); + ranges::copy(task->task_backtrace, task_trace.begin() + 1); size_t length = 0; while (length < task_trace.size() && task_trace[length]) ++length;
diff --git a/base/task/sequence_manager/task_queue_impl.cc b/base/task/sequence_manager/task_queue_impl.cc index 7dc1149..b3a468c 100644 --- a/base/task/sequence_manager/task_queue_impl.cc +++ b/base/task/sequence_manager/task_queue_impl.cc
@@ -10,6 +10,7 @@ #include <utility> #include "base/logging.h" +#include "base/ranges/algorithm.h" #include "base/strings/stringprintf.h" #include "base/task/common/scoped_defer_task_posting.h" #include "base/task/sequence_manager/sequence_manager_impl.h" @@ -1418,7 +1419,7 @@ // If we deleted something, re-enforce the heap property. if (task_deleted) - std::make_heap(queue_.c.begin(), queue_.c.end(), queue_.comp); + ranges::make_heap(queue_.c, queue_.comp); } Value TaskQueueImpl::DelayedIncomingQueue::AsValue(TimeTicks now) const {
diff --git a/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc b/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc index 1e5d8ce..5f9f593 100644 --- a/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc +++ b/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc
@@ -4,7 +4,6 @@ #include "base/task/thread_pool/pooled_single_thread_task_runner_manager.h" -#include <algorithm> #include <memory> #include <string> #include <utility> @@ -12,6 +11,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/memory/ptr_util.h" +#include "base/ranges/algorithm.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" #include "base/strings/stringprintf.h" @@ -719,7 +719,7 @@ if (workers_.empty()) return; - auto worker_iter = std::find(workers_.begin(), workers_.end(), worker); + auto worker_iter = ranges::find(workers_, worker); DCHECK(worker_iter != workers_.end()); worker_to_destroy = std::move(*worker_iter); workers_.erase(worker_iter);
diff --git a/base/task/thread_pool/thread_group_impl.cc b/base/task/thread_pool/thread_group_impl.cc index c911c47..487f158 100644 --- a/base/task/thread_pool/thread_group_impl.cc +++ b/base/task/thread_pool/thread_group_impl.cc
@@ -22,6 +22,7 @@ #include "base/metrics/histogram.h" #include "base/numerics/clamped_math.h" #include "base/optional.h" +#include "base/ranges/algorithm.h" #include "base/sequence_token.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -82,10 +83,10 @@ // Only used in DCHECKs. bool ContainsWorker(const std::vector<scoped_refptr<WorkerThread>>& workers, const WorkerThread* worker) { - auto it = std::find_if(workers.begin(), workers.end(), - [worker](const scoped_refptr<WorkerThread>& i) { - return i.get() == worker; - }); + auto it = + ranges::find_if(workers, [worker](const scoped_refptr<WorkerThread>& i) { + return i.get() == worker; + }); return it != workers.end(); } @@ -720,8 +721,7 @@ outer_->idle_workers_stack_.Remove(worker); // Remove the worker from |workers_|. - auto worker_iter = - std::find(outer_->workers_.begin(), outer_->workers_.end(), worker); + auto worker_iter = ranges::find(outer_->workers_, worker); DCHECK(worker_iter != outer_->workers_.end()); outer_->workers_.erase(worker_iter); }
diff --git a/base/task/thread_pool/worker_thread_stack.cc b/base/task/thread_pool/worker_thread_stack.cc index 75bc5c6..824dfc0 100644 --- a/base/task/thread_pool/worker_thread_stack.cc +++ b/base/task/thread_pool/worker_thread_stack.cc
@@ -4,9 +4,8 @@ #include "base/task/thread_pool/worker_thread_stack.h" -#include <algorithm> - #include "base/check_op.h" +#include "base/ranges/algorithm.h" #include "base/stl_util.h" #include "base/task/thread_pool/worker_thread.h" @@ -47,7 +46,7 @@ void WorkerThreadStack::Remove(const WorkerThread* worker) { DCHECK(!IsEmpty()); DCHECK_NE(worker, stack_.back()); - auto it = std::find(stack_.begin(), stack_.end(), worker); + auto it = ranges::find(stack_, worker); DCHECK(it != stack_.end()); DCHECK_NE(TimeTicks(), (*it)->GetLastUsedTime()); stack_.erase(it);
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index a62b35b..1985601 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -30,6 +30,7 @@ #include "base/numerics/safe_conversions.h" #include "base/process/kill.h" #include "base/process/launch.h" +#include "base/ranges/algorithm.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/strings/pattern.h" @@ -695,7 +696,7 @@ CHECK_GT(runner_count_, 0u); tests_to_run_ = test_names; // Reverse test order to avoid coping the whole vector when removing tests. - std::reverse(tests_to_run_.begin(), tests_to_run_.end()); + ranges::reverse(tests_to_run_); runners_done_ = 0; task_runners_.clear(); for (size_t i = 0; i < runner_count_; i++) { @@ -1591,7 +1592,7 @@ std::mt19937 randomizer; randomizer.seed(shuffle_seed); - std::shuffle(tests_.begin(), tests_.end(), randomizer); + ranges::shuffle(tests_, randomizer); fprintf(stdout, "Randomizing with seed %u\n", shuffle_seed); fflush(stdout);
diff --git a/base/test/scoped_feature_list.cc b/base/test/scoped_feature_list.cc index e6fec8d..7ada1d5 100644 --- a/base/test/scoped_feature_list.cc +++ b/base/test/scoped_feature_list.cc
@@ -4,12 +4,12 @@ #include "base/test/scoped_feature_list.h" -#include <algorithm> #include <utility> #include <vector> #include "base/memory/ptr_util.h" #include "base/metrics/field_trial_param_associator.h" +#include "base/ranges/algorithm.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" @@ -71,10 +71,10 @@ // with GetFeatureName() and also could be without parameters. bool ContainsFeature(const std::vector<StringPiece>& feature_vector, StringPiece feature_name) { - auto iter = std::find_if(feature_vector.begin(), feature_vector.end(), - [&feature_name](const StringPiece& a) { - return GetFeatureName(a) == feature_name; - }); + auto iter = + ranges::find_if(feature_vector, [&feature_name](const StringPiece& a) { + return GetFeatureName(a) == feature_name; + }); return iter != feature_vector.end(); }
diff --git a/base/test/trace_event_analyzer.cc b/base/test/trace_event_analyzer.cc index 13af95dd..f59c7aaa 100644 --- a/base/test/trace_event_analyzer.cc +++ b/base/test/trace_event_analyzer.cc
@@ -14,6 +14,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted_memory.h" +#include "base/ranges/algorithm.h" #include "base/run_loop.h" #include "base/strings/pattern.h" #include "base/trace_event/trace_buffer.h" @@ -775,7 +776,7 @@ raw_events_.clear(); if (!ParseEventsFromJson(json_events, &raw_events_)) return false; - std::stable_sort(raw_events_.begin(), raw_events_.end()); + base::ranges::stable_sort(raw_events_); ParseMetadata(); return true; } @@ -964,7 +965,7 @@ deltas.push_back(delta); } - std::sort(deltas.begin(), deltas.end()); + base::ranges::sort(deltas); if (options) { if (options->trim_min + options->trim_max > events.size() - kMinEvents) { @@ -980,8 +981,8 @@ for (size_t i = 0; i < num_deltas; ++i) delta_sum += deltas[i]; - stats->min_us = *std::min_element(deltas.begin(), deltas.end()); - stats->max_us = *std::max_element(deltas.begin(), deltas.end()); + stats->min_us = *base::ranges::min_element(deltas); + stats->max_us = *base::ranges::max_element(deltas); stats->mean_us = delta_sum / static_cast<double>(num_deltas); double sum_mean_offsets_squared = 0.0;
diff --git a/base/threading/hang_watcher.cc b/base/threading/hang_watcher.cc index a84299b..03413dd 100644 --- a/base/threading/hang_watcher.cc +++ b/base/threading/hang_watcher.cc
@@ -4,7 +4,6 @@ #include "base/threading/hang_watcher.h" -#include <algorithm> #include <atomic> #include <utility> @@ -16,6 +15,7 @@ #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" #include "base/no_destructor.h" +#include "base/ranges/algorithm.h" #include "base/strings/string_number_conversions.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" @@ -413,10 +413,10 @@ // Sort |hung_watch_state_copies_| by order of decreasing hang severity so the // most severe hang is first in the list. - std::sort(hung_watch_state_copies_.begin(), hung_watch_state_copies_.end(), - [](const WatchStateCopy& lhs, const WatchStateCopy& rhs) { - return lhs.deadline < rhs.deadline; - }); + ranges::sort(hung_watch_state_copies_, + [](const WatchStateCopy& lhs, const WatchStateCopy& rhs) { + return lhs.deadline < rhs.deadline; + }); } HangWatcher::WatchStateSnapShot::WatchStateSnapShot( @@ -476,8 +476,8 @@ // atomically. This is fine. Detecting a hang is generally best effort and // if a thread resumes from hang in the time it takes to move on to // capturing then its ID will be absent from the crash keys. - bool any_thread_hung = std::any_of( - watch_states_.cbegin(), watch_states_.cend(), + bool any_thread_hung = ranges::any_of( + watch_states_, [this, now](const std::unique_ptr<internal::HangWatchState>& state) { uint64_t flags; base::TimeTicks deadline; @@ -595,12 +595,12 @@ internal::HangWatchState* current_hang_watch_state = internal::HangWatchState::GetHangWatchStateForCurrentThread()->Get(); - auto it = - std::find_if(watch_states_.cbegin(), watch_states_.cend(), - [current_hang_watch_state]( - const std::unique_ptr<internal::HangWatchState>& state) { - return state.get() == current_hang_watch_state; - }); + auto it = ranges::find_if( + watch_states_, + [current_hang_watch_state]( + const std::unique_ptr<internal::HangWatchState>& state) { + return state.get() == current_hang_watch_state; + }); // Thread should be registered to get unregistered. DCHECK(it != watch_states_.end());
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc index b7728b9..8244eb7 100644 --- a/base/trace_event/trace_log.cc +++ b/base/trace_event/trace_log.cc
@@ -4,7 +4,6 @@ #include "base/trace_event/trace_log.h" -#include <algorithm> #include <cmath> #include <limits> #include <memory> @@ -22,6 +21,7 @@ #include "base/no_destructor.h" #include "base/process/process.h" #include "base/process/process_metrics.h" +#include "base/ranges/algorithm.h" #include "base/stl_util.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h" @@ -778,8 +778,7 @@ void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) { AutoLock lock(observers_lock_); enabled_state_observers_.erase( - std::remove(enabled_state_observers_.begin(), - enabled_state_observers_.end(), listener), + ranges::remove(enabled_state_observers_, listener), enabled_state_observers_.end()); }
diff --git a/base/values.cc b/base/values.cc index 2f82767b..d8d0357f 100644 --- a/base/values.cc +++ b/base/values.cc
@@ -6,7 +6,6 @@ #include <string.h> -#include <algorithm> #include <cmath> #include <new> #include <ostream> @@ -18,6 +17,7 @@ #include "base/json/json_writer.h" #include "base/memory/ptr_util.h" #include "base/notreached.h" +#include "base/ranges/algorithm.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -1554,7 +1554,7 @@ } bool ListValue::Remove(const Value& value, size_t* index) { - auto it = std::find(list().begin(), list().end(), value); + auto it = ranges::find(list(), value); if (it == list().end()) return false; @@ -1626,7 +1626,7 @@ } ListValue::const_iterator ListValue::Find(const Value& value) const { - return std::find(GetList().begin(), GetList().end(), value); + return ranges::find(GetList(), value); } void ListValue::Swap(ListValue* other) {
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index a3a6fbc..a6d7a75d 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20201017.2.1 +0.20201018.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index a3a6fbc..a6d7a75d 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20201017.2.1 +0.20201018.3.1
diff --git a/build/print_python_deps.py b/build/print_python_deps.py index fd29c09..ab00d0c 100755 --- a/build/print_python_deps.py +++ b/build/print_python_deps.py
@@ -12,6 +12,7 @@ """ import argparse +import fnmatch import os import pipes import sys @@ -63,12 +64,13 @@ return ' '.join(pipes.quote(x) for x in args) -def _FindPythonInDirectory(directory): +def _FindPythonInDirectory(directory, allow_test): """Returns an iterable of all non-test python files in the given directory.""" files = [] for root, _dirnames, filenames in os.walk(directory): for filename in filenames: - if filename.endswith('.py') and not filename.endswith('_test.py'): + if filename.endswith('.py') and (allow_test + or not filename.endswith('_test.py')): yield os.path.join(root, filename) @@ -99,6 +101,8 @@ def _ImportModuleByPath(module_path): """Imports a module by its source file.""" + # Replace the path entry for print_python_deps.py with the one for the given + # module. sys.path[0] = os.path.dirname(module_path) if sys.version_info[0] == 2: import imp # Python 2 only, since it's deprecated in Python 3. @@ -146,8 +150,17 @@ options.output = options.module + 'deps' options.root = os.path.dirname(options.module) - target_version = _GetTargetPythonVersion(options.module) + modules = [options.module] + if os.path.isdir(options.module): + modules = list(_FindPythonInDirectory(options.module, allow_test=True)) + if not modules: + parser.error('Input directory does not contain any python files!') + + target_versions = [_GetTargetPythonVersion(m) for m in modules] + target_version = target_versions[0] assert target_version in [2, 3] + assert all(v == target_version for v in target_versions) + current_version = sys.version_info[0] # Trybots run with vpython as default Python, but with a different config @@ -167,10 +180,11 @@ vpython_to_use = {2: 'vpython', 3: 'vpython3'}[target_version] os.execvp(vpython_to_use, [vpython_to_use] + sys.argv + ['--did-relaunch']) - # Replace the path entry for print_python_deps.py with the one for the given - # module. + paths_set = set() try: - _ImportModuleByPath(options.module) + for module in modules: + _ImportModuleByPath(module) + paths_set.update(ComputePythonDependencies()) except Exception: # Output extra diagnostics when loading the script fails. sys.stderr.write('Error running print_python_deps.py.\n') @@ -179,9 +193,10 @@ sys.stderr.write('python={}\n'.format(sys.executable)) raise - paths_set = ComputePythonDependencies() for path in options.whitelists: - paths_set.update(os.path.abspath(p) for p in _FindPythonInDirectory(path)) + paths_set.update( + os.path.abspath(p) + for p in _FindPythonInDirectory(path, allow_test=False)) paths = [os.path.relpath(p, options.root) for p in paths_set]
diff --git a/chrome/VERSION b/chrome/VERSION index d9eb55b..d740630c 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=88 MINOR=0 -BUILD=4296 +BUILD=4297 PATCH=0
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 3126777..cf0d5f51 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -297,6 +297,7 @@ "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerHost.java", "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutProvider.java", "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutRenderHost.java", + "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutStateProvider.java", "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutUpdateHost.java", "java/src/org/chromium/chrome/browser/compositor/layouts/OverviewModeBehavior.java", "java/src/org/chromium/chrome/browser/compositor/layouts/OverviewModeController.java",
diff --git a/chrome/android/features/autofill_assistant/BUILD.gn b/chrome/android/features/autofill_assistant/BUILD.gn index 6972de7..81ae043f 100644 --- a/chrome/android/features/autofill_assistant/BUILD.gn +++ b/chrome/android/features/autofill_assistant/BUILD.gn
@@ -269,6 +269,7 @@ "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantGenericUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantHeaderUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java", + "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInputActionIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantKeyboardIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantNavigationIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java",
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInputActionIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInputActionIntegrationTest.java new file mode 100644 index 0000000..26aaa82 --- /dev/null +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInputActionIntegrationTest.java
@@ -0,0 +1,334 @@ +package org.chromium.chrome.browser.autofill_assistant; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withText; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.checkElementExists; +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.getElementValue; +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.startAutofillAssistant; +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntil; +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewMatchesCondition; + +import android.support.test.InstrumentationRegistry; + +import androidx.test.filters.MediumTest; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto; +import org.chromium.chrome.browser.autofill_assistant.proto.ChipProto; +import org.chromium.chrome.browser.autofill_assistant.proto.ChipType; +import org.chromium.chrome.browser.autofill_assistant.proto.ClickProto; +import org.chromium.chrome.browser.autofill_assistant.proto.ClickType; +import org.chromium.chrome.browser.autofill_assistant.proto.DropdownSelectStrategy; +import org.chromium.chrome.browser.autofill_assistant.proto.KeyboardValueFillStrategy; +import org.chromium.chrome.browser.autofill_assistant.proto.PromptProto; +import org.chromium.chrome.browser.autofill_assistant.proto.PromptProto.Choice; +import org.chromium.chrome.browser.autofill_assistant.proto.SelectOptionProto; +import org.chromium.chrome.browser.autofill_assistant.proto.SelectorProto; +import org.chromium.chrome.browser.autofill_assistant.proto.SelectorProto.Filter; +import org.chromium.chrome.browser.autofill_assistant.proto.SetFormFieldValueProto; +import org.chromium.chrome.browser.autofill_assistant.proto.SetFormFieldValueProto.KeyPress; +import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto; +import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto.PresentationProto; +import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; +import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils; +import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * Tests autofill assistant's input actions such as keyboard and clicking. + */ +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@RunWith(ChromeJUnit4ClassRunner.class) +public class AutofillAssistantInputActionIntegrationTest { + @Rule + public CustomTabActivityTestRule mTestRule = new CustomTabActivityTestRule(); + + private static final String TEST_PAGE = "/components/test/data/autofill_assistant/html/" + + "autofill_assistant_target_website.html"; + + @Before + public void setUp() throws Exception { + AutofillAssistantPreferencesUtil.setInitialPreferences(true); + mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent( + InstrumentationRegistry.getTargetContext(), + mTestRule.getTestServer().getURL(TEST_PAGE))); + } + + @Test + @MediumTest + public void fillFormFieldWithText() throws Exception { + ArrayList<ActionProto> list = new ArrayList<>(); + + SelectorProto element_set_value = + (SelectorProto) SelectorProto.newBuilder() + .addFilters(Filter.newBuilder().setCssSelector("#input1")) + .build(); + list.add((ActionProto) ActionProto.newBuilder() + .setSetFormValue( + SetFormFieldValueProto.newBuilder() + .setElement(element_set_value) + .addValue(KeyPress.newBuilder().setText("Set Value")) + .setFillStrategy(KeyboardValueFillStrategy.SET_VALUE)) + .build()); + SelectorProto element_keystrokes = + (SelectorProto) SelectorProto.newBuilder() + .addFilters(Filter.newBuilder().setCssSelector("#input2")) + .build(); + list.add((ActionProto) ActionProto.newBuilder() + .setSetFormValue( + SetFormFieldValueProto.newBuilder() + .setElement(element_keystrokes) + .addValue(KeyPress.newBuilder().setText("Keystrokes")) + .setFillStrategy( + KeyboardValueFillStrategy.SIMULATE_KEY_PRESSES)) + .build()); + SelectorProto element_keystrokes_select = + (SelectorProto) SelectorProto.newBuilder() + .addFilters(Filter.newBuilder().setCssSelector("#input3")) + .build(); + list.add((ActionProto) ActionProto.newBuilder() + .setSetFormValue( + SetFormFieldValueProto.newBuilder() + .setElement(element_keystrokes_select) + .addValue( + KeyPress.newBuilder().setText("Keystrokes Select")) + .setFillStrategy( + KeyboardValueFillStrategy + .SIMULATE_KEY_PRESSES_SELECT_VALUE)) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder() + .setMessage("Finished") + .addChoices(Choice.newBuilder())) + .build()); + + AutofillAssistantTestScript script = new AutofillAssistantTestScript( + (SupportedScriptProto) SupportedScriptProto.newBuilder() + .setPath(TEST_PAGE) + .setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip( + ChipProto.newBuilder().setText("Done"))) + .build(), + list); + + runScript(script); + + waitUntilViewMatchesCondition(withText("Finished"), isCompletelyDisplayed()); + assertThat(getElementValue(mTestRule.getWebContents(), "input1"), is("Set Value")); + assertThat(getElementValue(mTestRule.getWebContents(), "input2"), is("Keystrokes")); + assertThat(getElementValue(mTestRule.getWebContents(), "input3"), is("Keystrokes Select")); + } + + @Test + @MediumTest + public void clearFormFieldFromText() throws Exception { + ArrayList<ActionProto> list = new ArrayList<>(); + + SelectorProto element_set_value = + (SelectorProto) SelectorProto.newBuilder() + .addFilters(Filter.newBuilder().setCssSelector("#input1")) + .build(); + list.add((ActionProto) ActionProto.newBuilder() + .setSetFormValue( + SetFormFieldValueProto.newBuilder() + .setElement(element_set_value) + .addValue(KeyPress.newBuilder().setText("")) + .setFillStrategy(KeyboardValueFillStrategy.SET_VALUE)) + .build()); + SelectorProto element_keystrokes = + (SelectorProto) SelectorProto.newBuilder() + .addFilters(Filter.newBuilder().setCssSelector("#input2")) + .build(); + list.add((ActionProto) ActionProto.newBuilder() + .setSetFormValue( + SetFormFieldValueProto.newBuilder() + .setElement(element_keystrokes) + .addValue(KeyPress.newBuilder().setText("")) + .setFillStrategy( + KeyboardValueFillStrategy.SIMULATE_KEY_PRESSES)) + .build()); + SelectorProto element_keystrokes_select = + (SelectorProto) SelectorProto.newBuilder() + .addFilters(Filter.newBuilder().setCssSelector("#input3")) + .build(); + list.add((ActionProto) ActionProto.newBuilder() + .setSetFormValue( + SetFormFieldValueProto.newBuilder() + .setElement(element_keystrokes_select) + .addValue(KeyPress.newBuilder().setText("")) + .setFillStrategy( + KeyboardValueFillStrategy + .SIMULATE_KEY_PRESSES_SELECT_VALUE)) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder() + .setMessage("Finished") + .addChoices(Choice.newBuilder())) + .build()); + + AutofillAssistantTestScript script = new AutofillAssistantTestScript( + (SupportedScriptProto) SupportedScriptProto.newBuilder() + .setPath(TEST_PAGE) + .setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip( + ChipProto.newBuilder().setText("Done"))) + .build(), + list); + + assertThat(getElementValue(mTestRule.getWebContents(), "input1"), is("helloworld1")); + assertThat(getElementValue(mTestRule.getWebContents(), "input2"), is("helloworld2")); + assertThat(getElementValue(mTestRule.getWebContents(), "input3"), is("helloworld3")); + + runScript(script); + + waitUntilViewMatchesCondition(withText("Finished"), isCompletelyDisplayed()); + assertThat(getElementValue(mTestRule.getWebContents(), "input1"), is("")); + assertThat(getElementValue(mTestRule.getWebContents(), "input2"), is("")); + assertThat(getElementValue(mTestRule.getWebContents(), "input3"), is("")); + } + + @Test + @MediumTest + public void selectOptionFromDropdown() throws Exception { + ArrayList<ActionProto> list = new ArrayList<>(); + + SelectorProto element = (SelectorProto) SelectorProto.newBuilder() + .addFilters(Filter.newBuilder().setCssSelector("#select")) + .build(); + list.add((ActionProto) ActionProto.newBuilder() + .setSelectOption( + SelectOptionProto.newBuilder() + .setElement(element) + .setSelectedOption("one") + .setSelectStrategy(DropdownSelectStrategy.VALUE_MATCH)) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder() + .setMessage("Value Match") + .addChoices(Choice.newBuilder().setChip( + ChipProto.newBuilder() + .setType(ChipType.HIGHLIGHTED_ACTION) + .setText("Continue")))) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setSelectOption( + SelectOptionProto.newBuilder() + .setElement(element) + .setSelectedOption("Three") + .setSelectStrategy(DropdownSelectStrategy.LABEL_MATCH)) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder() + .setMessage("Label Match") + .addChoices(Choice.newBuilder().setChip( + ChipProto.newBuilder() + .setType(ChipType.HIGHLIGHTED_ACTION) + .setText("Continue")))) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setSelectOption(SelectOptionProto.newBuilder() + .setElement(element) + .setSelectedOption("Zürich") + .setSelectStrategy( + DropdownSelectStrategy.LABEL_STARTS_WITH)) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder() + .setMessage("Label Starts With") + .addChoices(Choice.newBuilder())) + .build()); + + AutofillAssistantTestScript script = new AutofillAssistantTestScript( + (SupportedScriptProto) SupportedScriptProto.newBuilder() + .setPath(TEST_PAGE) + .setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip( + ChipProto.newBuilder().setText("Done"))) + .build(), + list); + + runScript(script); + + waitUntilViewMatchesCondition(withText("Value Match"), isCompletelyDisplayed()); + assertThat(getElementValue(mTestRule.getWebContents(), "select"), is("one")); + onView(withText("Continue")).perform(click()); + + waitUntilViewMatchesCondition(withText("Label Match"), isCompletelyDisplayed()); + assertThat(getElementValue(mTestRule.getWebContents(), "select"), is("three")); + onView(withText("Continue")).perform(click()); + + waitUntilViewMatchesCondition(withText("Label Starts With"), isCompletelyDisplayed()); + assertThat(getElementValue(mTestRule.getWebContents(), "select"), is("two")); + } + + @Test + @MediumTest + public void clickingOnElementToHide() { + ArrayList<ActionProto> list = new ArrayList<>(); + + SelectorProto element_click = + (SelectorProto) SelectorProto.newBuilder() + .addFilters(Filter.newBuilder().setCssSelector("#touch_area_one")) + .build(); + list.add((ActionProto) ActionProto.newBuilder() + .setClick(ClickProto.newBuilder() + .setElementToClick(element_click) + .setClickType(ClickType.CLICK)) + .build()); + SelectorProto element_tap = + (SelectorProto) SelectorProto.newBuilder() + .addFilters(Filter.newBuilder().setCssSelector("#touch_area_five")) + .build(); + list.add((ActionProto) ActionProto.newBuilder() + .setClick(ClickProto.newBuilder() + .setElementToClick(element_tap) + .setClickType(ClickType.TAP)) + .build()); + SelectorProto element_js = + (SelectorProto) SelectorProto.newBuilder() + .addFilters(Filter.newBuilder().setCssSelector("#touch_area_six")) + .build(); + list.add((ActionProto) ActionProto.newBuilder() + .setClick(ClickProto.newBuilder() + .setElementToClick(element_js) + .setClickType(ClickType.JAVASCRIPT)) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder() + .setMessage("Finished") + .addChoices(Choice.newBuilder())) + .build()); + + AutofillAssistantTestScript script = new AutofillAssistantTestScript( + (SupportedScriptProto) SupportedScriptProto.newBuilder() + .setPath(TEST_PAGE) + .setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip( + ChipProto.newBuilder().setText("Done"))) + .build(), + list); + + runScript(script); + + waitUntilViewMatchesCondition(withText("Finished"), isCompletelyDisplayed()); + waitUntil(() -> !checkElementExists(mTestRule.getWebContents(), "touch_area_one")); + waitUntil(() -> !checkElementExists(mTestRule.getWebContents(), "touch_area_five")); + waitUntil(() -> !checkElementExists(mTestRule.getWebContents(), "touch_area_six")); + } + + private void runScript(AutofillAssistantTestScript script) { + AutofillAssistantTestService testService = + new AutofillAssistantTestService(Collections.singletonList(script)); + startAutofillAssistant(mTestRule.getActivity(), testService); + } +} \ No newline at end of file
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java index 2aa29a70..61b926f 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java
@@ -158,6 +158,11 @@ public void addOnInitializedCallback(Callback<Boolean> callback) { assert false : "Implement addOnInitializedCallback if you need it."; } + + @Override + public void injectTracker(Tracker tracker) { + assert false : "This should only be called on a production tracker"; + } } @Before
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 3d17a880..c9179a6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -64,6 +64,7 @@ import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromePhone; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromeTablet; +import org.chromium.chrome.browser.compositor.layouts.LayoutStateProvider; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.OverviewModeController; import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout; @@ -286,6 +287,9 @@ private NextTabPolicySupplier mNextTabPolicySupplier; + private final OneshotSupplierImpl<LayoutStateProvider> mLayoutStateProviderOneshotSupplier = + new OneshotSupplierImpl<>(); + // TODO(crbug.com/1108496): Removed after all usages has been migrated to LayoutStateProvider. private final OneshotSupplierImpl<OverviewModeBehavior> mOverviewModeBehaviorSupplier = new OneshotSupplierImpl<>(); private OverviewModeController mOverviewModeController; @@ -565,7 +569,7 @@ } mLayoutManager = new LayoutManagerChromePhone(compositorViewHolder, mContentContainer, mStartSurfaceSupplier.get(), getTabContentManagerSupplier(), - mOverviewModeBehaviorSupplier); + mOverviewModeBehaviorSupplier, mLayoutStateProviderOneshotSupplier); mOverviewModeController = mLayoutManager; } } @@ -575,9 +579,9 @@ try (TraceEvent e = TraceEvent.scoped( "ChromeTabbedActivity.setupCompositorContentPreNativeForTablet")) { - mLayoutManager = - new LayoutManagerChromeTablet(getCompositorViewHolder(), mContentContainer, - getTabContentManagerSupplier(), mOverviewModeBehaviorSupplier); + mLayoutManager = new LayoutManagerChromeTablet(getCompositorViewHolder(), + mContentContainer, getTabContentManagerSupplier(), + mOverviewModeBehaviorSupplier, mLayoutStateProviderOneshotSupplier); mOverviewModeController = mLayoutManager; } } @@ -615,7 +619,7 @@ } Layout activeLayout = mLayoutManager.getActiveLayout(); - if (activeLayout instanceof StackLayout && !activeLayout.isHiding()) { + if (activeLayout instanceof StackLayout && !activeLayout.isStartingToHide()) { RecordUserAction.record("MobileToolbarStackViewButtonInStackView"); } else if (!isInOverviewMode()) { RecordUserAction.record("MobileToolbarStackViewButtonInBrowsingView");
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java index 7142f40..eb59c8e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.incognito.IncognitoUtils; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabLaunchType; @@ -127,9 +128,7 @@ */ public void requestOpenSheet(String url, String title, boolean isIncognito) { mUrl = url; - Profile profile = isIncognito ? Profile.getLastUsedRegularProfile().getOffTheRecordProfile() - : Profile.getLastUsedRegularProfile(); - + Profile profile = getProfile(isIncognito); if (mMediator == null) { float topControlsHeight = mContext.getResources().getDimensionPixelSize(R.dimen.toolbar_height_no_shadow) @@ -139,7 +138,7 @@ } if (mWebContents == null) { assert mSheetContent == null; - createWebContents(isIncognito); + createWebContents(profile); mSheetObserver = new EmptyBottomSheetObserver() { private int mCloseReason; @@ -208,11 +207,18 @@ if (tracker.isInitialized()) tracker.notifyEvent(EventConstants.EPHEMERAL_TAB_USED); } - private void createWebContents(boolean incognito) { + private Profile getProfile(boolean isIncognito) { + if (!isIncognito) return Profile.getLastUsedRegularProfile(); + Profile otrProfile = IncognitoUtils.getNonPrimaryOTRProfileFromWindowAndroid(mWindow); + return (otrProfile == null) ? Profile.getLastUsedRegularProfile().getPrimaryOTRProfile() + : otrProfile; + } + + private void createWebContents(Profile profile) { assert mWebContents == null; // Creates an initially hidden WebContents which gets shown when the panel is opened. - mWebContents = WebContentsFactory.createWebContents(incognito, true); + mWebContents = WebContentsFactory.createWebContents(profile, true); mContentView = ContentView.createContentView( mContext, null /* eventOffsetHandler */, mWebContents);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java index 504b63c..361325cc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
@@ -114,7 +114,10 @@ protected LayoutTab[] mLayoutTabs; // True means that the layout is going to hide as soon as the animation finishes. - private boolean mIsHiding; + private boolean mIsStartingToHide; + + // True means that the layout is going to show as soon as the animation finishes. + private boolean mIsStartingToShow; // The next id to show when the layout is hidden, or TabBase#INVALID_TAB_ID if no change. protected int mNextTabId = Tab.INVALID_TAB_ID; @@ -416,15 +419,22 @@ */ public void startHiding(int nextTabId, boolean hintAtTabSelection) { mUpdateHost.startHiding(nextTabId, hintAtTabSelection); - mIsHiding = true; + mIsStartingToHide = true; mNextTabId = nextTabId; } /** * @return True is the layout is in the process of hiding itself. */ - public boolean isHiding() { - return mIsHiding; + public boolean isStartingToHide() { + return mIsStartingToHide; + } + + /** + * @return True is the layout is in the process of showing itself. + */ + public boolean isStartingToShow() { + return mIsStartingToShow; } /** @@ -438,6 +448,7 @@ * To be called when the transition into the layout is done. */ public void doneShowing() { + mIsStartingToShow = false; mUpdateHost.doneShowing(); } @@ -446,7 +457,7 @@ * This is currently called by the renderer when all the animation are done while hiding. */ public void doneHiding() { - mIsHiding = false; + mIsStartingToHide = false; if (mNextTabId != Tab.INVALID_TAB_ID) { TabModel model = mTabModelSelector.getModelForTabId(mNextTabId); if (model != null) { @@ -477,7 +488,9 @@ * @param animate Whether to play an entry animation. */ public void show(long time, boolean animate) { - mIsHiding = false; + // TODO(crbug.com/1108496): Remove after LayoutManager explicitly hide the old layout. + mIsStartingToHide = false; + mIsStartingToShow = true; mNextTabId = Tab.INVALID_TAB_ID; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java index 85731fee..a1770db 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
@@ -20,6 +20,7 @@ import org.chromium.base.TraceEvent; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.browser_controls.BrowserControlsUtils; import org.chromium.chrome.browser.browser_controls.BrowserControlsVisibilityManager; @@ -80,7 +81,7 @@ * includes lifecycle managment like showing/hiding this {@link Layout}. */ public class LayoutManager implements LayoutUpdateHost, LayoutProvider, - TabModelSelector.CloseAllTabsDelegate { + TabModelSelector.CloseAllTabsDelegate, LayoutStateProvider { /** Sampling at 60 fps. */ private static final long FRAME_DELTA_TIME_MS = 16; @@ -118,6 +119,9 @@ private TabModelObserver mTabModelFilterObserver; // External Observers + private final ObserverList<LayoutStateObserver> mLayoutObservers = new ObserverList<>(); + // TODO(crbug.com/1108496): Remove after all SceneChangeObserver migrates to + // LayoutStateObserver. private final ObserverList<SceneChangeObserver> mSceneChangeObservers = new ObserverList<>(); // Current Layout State @@ -165,6 +169,9 @@ /** A map of {@link SceneOverlay} to its position relative to the others. */ private Map<Class, Integer> mOverlayOrderMap = new HashMap<>(); + /** The supplier used to supply the LayoutStateProvider. */ + private final OneshotSupplierImpl<LayoutStateProvider> mLayoutStateProviderOneshotSupplier; + /** * Protected class to handle {@link TabModelObserver} related tasks. Extending classes will * need to override any related calls to add new functionality */ @@ -241,14 +248,18 @@ * @param host A {@link LayoutManagerHost} instance. * @param contentContainer A {@link ViewGroup} for Android views to be bound to. * @param tabContentManagerSupplier Supplier of the {@link TabContentManager} instance. + * @param layoutStateProviderOneshotSupplier Supplier used to supply the {@link + * LayoutStateProvider}. */ public LayoutManager(LayoutManagerHost host, ViewGroup contentContainer, - ObservableSupplier<TabContentManager> tabContentManagerSupplier) { + ObservableSupplier<TabContentManager> tabContentManagerSupplier, + OneshotSupplierImpl<LayoutStateProvider> layoutStateProviderOneshotSupplier) { mHost = host; mPxToDp = 1.f / mHost.getContext().getResources().getDisplayMetrics().density; mAndroidViewShownSupplier = new ObservableSupplierImpl<>(); mAndroidViewShownSupplier.set(true); mTabContentManagerSupplier = tabContentManagerSupplier; + mLayoutStateProviderOneshotSupplier = layoutStateProviderOneshotSupplier; mContext = host.getContext(); LayoutRenderHost renderHost = host.getLayoutRenderHost(); @@ -262,7 +273,7 @@ StripLayoutHelperManager.class, StatusIndicatorCoordinator.getSceneOverlayClass(), ContextualSearchPanel.class}; - // clang-format off + // clang-format on for (int i = 0; i < overlayOrder.length; i++) mOverlayOrderMap.put(overlayOrder[i], i); @@ -274,6 +285,8 @@ mOverlayPanelManager = new OverlayPanelManager(); mFrameRequestSupplier = new CompositorModelChangeProcessor.FrameRequestSupplier(this); + + mLayoutStateProviderOneshotSupplier.set(this); } /** @@ -418,9 +431,16 @@ // system. final Layout layout = getActiveLayout(); - if (layout != null && layout.onUpdate(timeMs, dtMs) && layout.isHiding() - && areAnimatorsComplete) { - layout.doneHiding(); + // TODO(crbug.com/1070281): Layout itself should decide when it's done hiding and done + // showing. + if (layout != null && layout.onUpdate(timeMs, dtMs) && areAnimatorsComplete) { + if (layout.isStartingToHide()) { + layout.doneHiding(); + } else if (layout.isStartingToShow()) { + // TODO(crbug.com/1108496): Call layout.doneShowing() here after all Layout have + // been consolidated into the new Layout System to avoid Layout tests become flaky, + // especially the StartSurfaceLayoutTest. + } } // TODO(1100332): Once overlays are MVC, this should no longer be needed. @@ -883,10 +903,18 @@ public void startHiding(int nextTabId, boolean hintAtTabSelection) { requestUpdate(); if (hintAtTabSelection) { + notifyObserversOnTabSelectionHinted(nextTabId); + + // TODO(crbug.com/1108496): Remove after migrates to LayoutStateObserver. for (SceneChangeObserver observer : mSceneChangeObservers) { observer.onTabSelectionHinted(nextTabId); } } + + Layout layoutBeingHidden = getActiveLayout(); + notifyObserversLayoutStartedHiding(layoutBeingHidden.getLayoutType(), + shouldShowToolbarAnimationOnHide(layoutBeingHidden, nextTabId), + shouldDelayHideAnimation(layoutBeingHidden)); } @Override @@ -894,11 +922,19 @@ // TODO: If next layout is default layout clear caches (should this be a sub layout thing?) assert mNextActiveLayout != null : "Need to have a next active layout."; - if (mNextActiveLayout != null) startShowing(mNextActiveLayout, true); + if (mNextActiveLayout != null) { + // Notify LayoutObservers the active layout is finished hiding. + notifyObserversLayoutFinishedHiding(getActiveLayout().getLayoutType()); + + startShowing(mNextActiveLayout, true); + } } @Override - public void doneShowing() {} + public void doneShowing() { + // Notify LayoutObservers the active layout is finished showing. + notifyObserversLayoutFinishedShowing(getActiveLayout().getLayoutType()); + } /** * Should be called by control logic to show a new {@link Layout}. @@ -920,6 +956,8 @@ if (oldLayout != null) { oldLayout.forceAnimationToFinish(); oldLayout.detachViews(); + + // TODO(crbug.com/1108496): hide oldLayout if it's not hidden. } layout.contextChanged(mHost.getContext()); layout.attachViews(mContentContainer); @@ -949,10 +987,14 @@ getActiveLayout().canHostBeFocusable()); mHost.requestRender(); + // TODO(crbug.com/1108496): Remove after migrates to LayoutStateObserver#onStartedShowing. // Notify observers about the new scene. for (SceneChangeObserver observer : mSceneChangeObservers) { observer.onSceneChange(getActiveLayout()); } + + notifyObserversLayoutStartedShowing( + layout.getLayoutType(), shouldShowToolbarAnimationOnShow(animate)); } /** @@ -1068,4 +1110,74 @@ protected void switchToTab(Tab tab, int lastTabId) { tabSelected(tab.getId(), lastTabId, tab.isIncognito()); } + + // LayoutStateProvider implementation. + @Override + public boolean isLayoutVisible(int layoutType) { + return getActiveLayout().getLayoutType() == layoutType; + } + + @Override + public void addObserver(LayoutStateObserver listener) { + mLayoutObservers.addObserver(listener); + } + + @Override + public void removeObserver(LayoutStateObserver listener) { + mLayoutObservers.removeObserver(listener); + } + + protected final void notifyObserversLayoutStartedShowing( + @Layout.LayoutType int layoutType, boolean showToolbar) { + mLayoutStateProviderOneshotSupplier.onAvailable((unused) -> { + for (LayoutStateObserver observer : mLayoutObservers) { + observer.onStartedShowing(layoutType, showToolbar); + } + }); + } + + protected final void notifyObserversLayoutFinishedShowing(@Layout.LayoutType int layoutType) { + mLayoutStateProviderOneshotSupplier.onAvailable((unused) -> { + for (LayoutStateObserver observer : mLayoutObservers) { + observer.onFinishedShowing(layoutType); + } + }); + } + + protected final void notifyObserversLayoutStartedHiding( + @Layout.LayoutType int layoutType, boolean showToolbar, boolean delayAnimation) { + mLayoutStateProviderOneshotSupplier.onAvailable((unused) -> { + for (LayoutStateObserver observer : mLayoutObservers) { + observer.onStartedHiding(layoutType, showToolbar, delayAnimation); + } + }); + } + + protected final void notifyObserversLayoutFinishedHiding(@Layout.LayoutType int layoutType) { + mLayoutStateProviderOneshotSupplier.onAvailable((unused) -> { + for (LayoutStateObserver observer : mLayoutObservers) { + observer.onFinishedHiding(layoutType); + } + }); + } + + protected final void notifyObserversOnTabSelectionHinted(int tabId) { + mLayoutStateProviderOneshotSupplier.onAvailable((unused) -> { + for (LayoutStateObserver observer : mLayoutObservers) { + observer.onTabSelectionHinted(tabId); + } + }); + } + + protected boolean shouldShowToolbarAnimationOnShow(boolean isAnimate) { + return false; + } + + protected boolean shouldShowToolbarAnimationOnHide(Layout layoutBeingHidden, int nextTabId) { + return false; + } + + protected boolean shouldDelayHideAnimation(Layout layoutBeingHidden) { + return false; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java index 8238e9b..305773d4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -88,8 +88,10 @@ public LayoutManagerChrome(LayoutManagerHost host, ViewGroup contentContainer, boolean createOverviewLayout, @Nullable StartSurface startSurface, ObservableSupplier<TabContentManager> tabContentManagerSupplier, - OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier) { - super(host, contentContainer, tabContentManagerSupplier); + OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier, + OneshotSupplierImpl<LayoutStateProvider> layoutStateProviderOneshotSupplier) { + super(host, contentContainer, tabContentManagerSupplier, + layoutStateProviderOneshotSupplier); Context context = host.getContext(); LayoutRenderHost renderHost = host.getLayoutRenderHost(); @@ -259,6 +261,7 @@ Layout layoutBeingShown = getActiveLayout(); + // TODO(crbug.com/1108496): Remove after migrates to LayoutStateObserver. // Check if we should notify OverviewModeObservers. if (isOverviewLayout(layoutBeingShown)) { boolean showToolbar = animate && (!mEnableAnimations @@ -271,6 +274,7 @@ public void startHiding(int nextTabId, boolean hintAtTabSelection) { super.startHiding(nextTabId, hintAtTabSelection); + // TODO(crbug.com/1108496): Remove after migrates to LayoutStateObserver. Layout layoutBeingHidden = getActiveLayout(); if (isOverviewLayout(layoutBeingHidden)) { boolean showToolbar = true; @@ -289,6 +293,7 @@ public void doneShowing() { super.doneShowing(); + // TODO(crbug.com/1108496): Remove after migrates to LayoutStateObserver. if (isOverviewLayout(getActiveLayout())) { notifyObserversFinishedShowing(); } @@ -305,12 +310,34 @@ super.doneHiding(); + // TODO(crbug.com/1108496): Remove after migrates to Observer. if (isOverviewLayout(layoutBeingHidden)) { notifyObserversFinishedHiding(); } } @Override + protected boolean shouldDelayHideAnimation(Layout layoutBeingHidden) { + return mEnableAnimations && layoutBeingHidden == mOverviewLayout && mCreatingNtp; + } + + @Override + protected boolean shouldShowToolbarAnimationOnShow(boolean isAnimate) { + return isAnimate + && (!mEnableAnimations || getTabModelSelector().getCurrentModel().getCount() <= 0); + } + + @Override + protected boolean shouldShowToolbarAnimationOnHide(Layout layoutBeingHidden, int nextTabId) { + boolean showAnimation = true; + if (mEnableAnimations && layoutBeingHidden == mOverviewLayout) { + final LayoutTab tab = layoutBeingHidden.getLayoutTab(nextTabId); + showAnimation = tab == null || !tab.showToolbar(); + } + return showAnimation; + } + + @Override protected void tabCreated(int id, int sourceId, @TabLaunchType int launchType, boolean incognito, boolean willBeSelected, float originX, float originY) { Tab newTab = TabModelUtils.getTabById(getTabModelSelector().getModel(incognito), id); @@ -394,7 +421,7 @@ @Override public void hideOverview(boolean animate) { Layout activeLayout = getActiveLayout(); - if (activeLayout != null && !activeLayout.isHiding()) { + if (activeLayout != null && !activeLayout.isStartingToHide()) { if (animate) { activeLayout.onTabSelecting(time(), Tab.INVALID_TAB_ID); } else { @@ -423,7 +450,7 @@ @Override public boolean overviewVisible() { Layout activeLayout = getActiveLayout(); - return isOverviewLayout(activeLayout) && !activeLayout.isHiding(); + return isOverviewLayout(activeLayout) && !activeLayout.isStartingToHide(); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java index 43f9d355..7dbb7eb7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java
@@ -41,9 +41,10 @@ public LayoutManagerChromePhone(LayoutManagerHost host, ViewGroup contentContainer, StartSurface startSurface, ObservableSupplier<TabContentManager> tabContentManagerSupplier, - OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier) { + OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier, + OneshotSupplierImpl<LayoutStateProvider> layoutStateProviderOneshotSupplier) { super(host, contentContainer, true, startSurface, tabContentManagerSupplier, - overviewModeBehaviorSupplier); + overviewModeBehaviorSupplier, layoutStateProviderOneshotSupplier); } @Override @@ -130,7 +131,7 @@ @Override protected void tabCreating(int sourceId, String url, boolean isIncognito) { - if (!getActiveLayout().isHiding() && overlaysHandleTabCreating() + if (!getActiveLayout().isStartingToHide() && overlaysHandleTabCreating() && getActiveLayout().handlesTabCreating()) { // If the current layout in the foreground, let it handle the tab creation animation. // This check allows us to switch from the StackLayout to the SimpleAnimationLayout @@ -138,7 +139,7 @@ getActiveLayout().onTabCreating(sourceId); } else if (animationsEnabled()) { if (!overviewVisible()) { - if (getActiveLayout() != null && getActiveLayout().isHiding()) { + if (getActiveLayout() != null && getActiveLayout().isStartingToHide()) { setNextLayout(mSimpleAnimationLayout); // The method Layout#doneHiding() will automatically show the next layout. getActiveLayout().doneHiding();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java index a0f4ff5..8f24eee4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
@@ -37,9 +37,10 @@ */ public LayoutManagerChromeTablet(LayoutManagerHost host, ViewGroup contentContainer, ObservableSupplier<TabContentManager> tabContentManagerSupplier, - OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier) { + OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier, + OneshotSupplierImpl<LayoutStateProvider> layoutStateProviderOneshotSupplier) { super(host, contentContainer, false, null, tabContentManagerSupplier, - overviewModeBehaviorSupplier); + overviewModeBehaviorSupplier, layoutStateProviderOneshotSupplier); mTabStripLayoutHelperManager = new StripLayoutHelperManager( host.getContext(), this, mHost.getLayoutRenderHost(), () -> mTitleCache);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutStateProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutStateProvider.java new file mode 100644 index 0000000..bb1fcf32 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutStateProvider.java
@@ -0,0 +1,71 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.compositor.layouts; + +/** + * Exposes the current {@link Layout} state as well as a way to listen to {@link Layout} state + * changes. + */ +public interface LayoutStateProvider { + /** + * An observer that is notified when the {@link Layout} state changes. + */ + interface LayoutStateObserver { + // TODO(crbug.com/1108496): Reiterate to see whether the showToolbar param is needed. + /** + * Called when Layout starts showing. + * @param layoutType LayoutType of the started showing Layout. + * @param showToolbar Whether or not to show the normal toolbar when animating into the + */ + default void onStartedShowing(@Layout.LayoutType int layoutType, boolean showToolbar) {} + + /** + * Called when Layout finishes showing. + * @param layoutType LayoutType of the finished showing Layout. + */ + default void onFinishedShowing(@Layout.LayoutType int layoutType) {} + + // TODO(crbug.com/1108496): Reiterate to see whether the showToolbar and delayAnimation + // param is needed. + /** + * Called when Layout starts hiding. + * @param layoutType LayoutType of the started hiding Layout. + * @param showToolbar Whether or not to show the normal toolbar when animating out of + * showing Layout. + * @param delayAnimation Whether or not to delay any related animations until after Layout + */ + default void onStartedHiding( + @Layout.LayoutType int layoutType, boolean showToolbar, boolean delayAnimation) {} + + /** + * Called when Layout finishes hiding. + * @param layoutType LayoutType of the finished hiding Layout. + */ + default void onFinishedHiding(@Layout.LayoutType int layoutType) {} + + /** + * Called when a layout wants to hint that a new tab might be selected soon. This is not + * called every time a tab is selected. + * @param tabId The id of the tab that might be selected soon. + */ + default void onTabSelectionHinted(int tabId) {} + } + + /** + * @return Whether or not the {@link Layout} is visible. + * @param layoutType whether the {@link Layout} give {@link Layout.LayoutType} is visible. + */ + boolean isLayoutVisible(@Layout.LayoutType int layoutType); + + /** + * @param listener Registers {@code listener} for all layout status changes. + */ + void addObserver(LayoutStateObserver listener); + + /** + * @param listener Unregisters {@code listener} for all layout status changes. + */ + void removeObserver(LayoutStateObserver listener); +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java index 234227a7..841faaa2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java
@@ -1727,7 +1727,7 @@ mStackTabs = new StackTab[count]; final boolean isIncognito = mTabList.isIncognito(); - final boolean needTitle = !mLayout.isHiding(); + final boolean needTitle = !mLayout.isStartingToHide(); for (int i = 0; i < count; ++i) { Tab tab = mTabList.getTabAt(i); int tabId = tab != null ? tab.getId() : Tab.INVALID_TAB_ID;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabCompositorContentInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabCompositorContentInitializer.java index 8d8f1ba..4561f996 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabCompositorContentInitializer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabCompositorContentInitializer.java
@@ -9,6 +9,7 @@ import org.chromium.base.Callback; import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.layouts.LayoutManager; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; @@ -67,8 +68,8 @@ @Override public void onFinishNativeInitialization() { ViewGroup contentContainer = mActivity.findViewById(android.R.id.content); - LayoutManager layoutDriver = new LayoutManager( - mCompositorViewHolder.get(), contentContainer, mTabContentManagerSupplier); + LayoutManager layoutDriver = new LayoutManager(mCompositorViewHolder.get(), + contentContainer, mTabContentManagerSupplier, new OneshotSupplierImpl<>()); mCompositorViewHolderInitializer.initializeCompositorContent(layoutDriver, mActivity.findViewById(org.chromium.chrome.R.id.url_bar), contentContainer,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java index e1e9fbd..7220633 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java
@@ -413,7 +413,8 @@ // request.show() is called. mPaymentUiService.calculateWhetherShouldSkipShowingPaymentRequestUi(mIsUserGestureShow, mURLPaymentMethodIdentifiersSupported, - mPaymentRequestService.skipUiForNonUrlPaymentMethodIdentifiers()); + mPaymentRequestService.skipUiForNonUrlPaymentMethodIdentifiers(), + mPaymentOptions); if (!buildUI(chromeActivity)) return; if (!mPaymentUiService.shouldSkipShowingPaymentRequestUi() && mSkipToGPayHelper == null) { @@ -1570,7 +1571,8 @@ assert mIsFinishedQueryingPaymentApps; mPaymentUiService.calculateWhetherShouldSkipShowingPaymentRequestUi(mIsUserGestureShow, mURLPaymentMethodIdentifiersSupported, - mPaymentRequestService.skipUiForNonUrlPaymentMethodIdentifiers()); + mPaymentRequestService.skipUiForNonUrlPaymentMethodIdentifiers(), + mPaymentOptions); if (!buildUI(chromeActivity)) return; if (!mPaymentUiService.shouldSkipShowingPaymentRequestUi() && mSkipToGPayHelper == null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java index ab2f297..1c758e9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerMediator.java
@@ -270,6 +270,7 @@ // Implement WebContentsObserver: @Override public void didFailLoad(boolean isMainFrame, int errorCode, String failingUrl) { + if (!isMainFrame) return; mHandler.post(() -> { mCloseReason = CloseReason.FAIL_LOAD; mHider.run();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentUiService.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentUiService.java index e5cba31..3d416d1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentUiService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentUiService.java
@@ -1385,14 +1385,14 @@ } /** + * @param options The payment options specified in the payment request. * @return true when there is exactly one available payment app which can provide all requested * information including shipping address and payer's contact information whenever needed. */ - public boolean onlySingleAppCanProvideAllRequiredInformation() { + public boolean onlySingleAppCanProvideAllRequiredInformation(PaymentOptions options) { assert mPaymentMethodsSection != null; - if (mParams.hasClosed()) return false; - if (!PaymentOptionsUtils.requestAnyInformation(mParams.getPaymentOptions())) { + if (!PaymentOptionsUtils.requestAnyInformation(options)) { return mPaymentMethodsSection.getSize() == 1 && !((PaymentApp) mPaymentMethodsSection.getItem(0)).isAutofillInstrument(); } @@ -1401,11 +1401,10 @@ int sectionSize = mPaymentMethodsSection.getSize(); for (int i = 0; i < sectionSize; i++) { PaymentApp app = (PaymentApp) mPaymentMethodsSection.getItem(i); - if ((!mParams.getPaymentOptions().requestShipping || app.handlesShippingAddress()) - && (!mParams.getPaymentOptions().requestPayerName || app.handlesPayerName()) - && (!mParams.getPaymentOptions().requestPayerPhone || app.handlesPayerPhone()) - && (!mParams.getPaymentOptions().requestPayerEmail - || app.handlesPayerEmail())) { + if ((!options.requestShipping || app.handlesShippingAddress()) + && (!options.requestPayerName || app.handlesPayerName()) + && (!options.requestPayerPhone || app.handlesPayerPhone()) + && (!options.requestPayerEmail || app.handlesPayerEmail())) { // There is more than one available app that can provide all merchant requested // information information. if (anAppCanProvideAllInfo) return false; @@ -1448,10 +1447,11 @@ * identifier is specified in payment request. * @param skipUiForNonUrlPaymentMethodIdentifiers True when skip UI is available for non-url * based payment method identifiers (e.g., basic-card). + * @param options The payment options specified in the payment request. */ public void calculateWhetherShouldSkipShowingPaymentRequestUi(boolean isUserGestureShow, boolean urlPaymentMethodIdentifiersSupported, - boolean skipUiForNonUrlPaymentMethodIdentifiers) { + boolean skipUiForNonUrlPaymentMethodIdentifiers, PaymentOptions options) { assert mPaymentMethodsSection != null; PaymentApp selectedApp = (PaymentApp) mPaymentMethodsSection.getSelectedItem(); @@ -1465,7 +1465,7 @@ // the payment request UI, thus can't be skipped. && (urlPaymentMethodIdentifiersSupported || skipUiForNonUrlPaymentMethodIdentifiers) && mPaymentMethodsSection.getSize() >= 1 - && onlySingleAppCanProvideAllRequiredInformation() + && onlySingleAppCanProvideAllRequiredInformation(options) // Skip to payment app only if it can be pre-selected. && selectedApp != null // Skip to payment app only if user gesture is provided when it is required to
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java index 16e95ab..c53d58a1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -4,6 +4,17 @@ package org.chromium.chrome.browser.banners; +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.matcher.ViewMatchers.assertThat; +import static androidx.test.espresso.matcher.ViewMatchers.isRoot; +import static androidx.test.espresso.matcher.ViewMatchers.withText; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; + +import static org.chromium.chrome.test.util.ViewUtils.waitForView; + import android.app.Activity; import android.app.Instrumentation; import android.app.Instrumentation.ActivityMonitor; @@ -18,9 +29,12 @@ import android.support.test.uiautomator.UiSelector; import android.view.View; +import androidx.test.espresso.ViewInteraction; +import androidx.test.espresso.matcher.RootMatchers; import androidx.test.filters.MediumTest; import androidx.test.filters.SmallTest; +import org.hamcrest.Matcher; import org.hamcrest.Matchers; import org.junit.After; import org.junit.Assert; @@ -36,6 +50,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.task.PostTask; +import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; @@ -46,6 +61,7 @@ import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils; import org.chromium.chrome.browser.engagement.SiteEngagementService; +import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.infobar.InfoBarContainer; @@ -53,6 +69,8 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabUtils; +import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator; +import org.chromium.chrome.browser.ui.appmenu.AppMenuTestSupport; import org.chromium.chrome.browser.webapps.WebappDataStorage; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -61,6 +79,9 @@ import org.chromium.chrome.test.util.browser.TabLoadObserver; import org.chromium.chrome.test.util.browser.TabTitleObserver; import org.chromium.chrome.test.util.browser.webapps.WebappTestPage; +import org.chromium.components.feature_engagement.CppWrappedTestTracker; +import org.chromium.components.feature_engagement.EventConstants; +import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.components.infobars.InfoBar; import org.chromium.components.infobars.InfoBarAnimationListener; import org.chromium.components.infobars.InfoBarUiItem; @@ -82,7 +103,7 @@ * Tests the app banners. */ @RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, "use-java-proxy-tracker"}) public class AppBannerManagerTest { @Rule public ChromeTabbedActivityTestRule mTabbedActivityTestRule = @@ -94,6 +115,12 @@ @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); + // A callback that fires when the IPH system sends an event. + private final CallbackHelper mOnEventCallback = new CallbackHelper(); + + // The ID of the last event received. + private String mLastNotifyEvent; + private static final String NATIVE_APP_MANIFEST_WITH_ID = "/chrome/test/data/banners/play_app_manifest.json"; @@ -183,6 +210,7 @@ private PackageManager mPackageManager; private EmbeddedTestServer mTestServer; private UiDevice mUiDevice; + private CppWrappedTestTracker mTracker; @Before public void setUp() throws Exception { @@ -198,8 +226,20 @@ mTabbedActivityTestRule.startMainActivityOnBlankPage(); // Must be set after native has loaded. mDetailsDelegate = new MockAppDetailsDelegate(); - ThreadUtils.runOnUiThreadBlocking( - () -> { AppBannerManager.setAppDetailsDelegate(mDetailsDelegate); }); + mTracker = new CppWrappedTestTracker(FeatureConstants.PWA_INSTALL_AVAILABLE_FEATURE) { + @Override + public void notifyEvent(String event) { + super.notifyEvent(event); + mOnEventCallback.notifyCalled(); + } + }; + + ThreadUtils.runOnUiThreadBlocking(() -> { + AppBannerManager.setAppDetailsDelegate(mDetailsDelegate); + + Profile profile = Profile.getLastUsedRegularProfile(); + TrackerFactory.getTrackerForProfile(profile).injectTracker(mTracker); + }); AppBannerManager.ignoreChromeChannelForTesting(); AppBannerManager.setTotalEngagementForTesting(10); @@ -209,7 +249,9 @@ @After public void tearDown() { - mTestServer.stopAndDestroyServer(); + if (mTestServer != null) { + mTestServer.stopAndDestroyServer(); + } } private void resetEngagementForUrl(final String url, final double engagement) { @@ -656,4 +698,43 @@ WEB_APP_MANIFEST_WITH_UNSUPPORTED_PLATFORM, "call_stashed_prompt_on_click"), false); } + + @Test + @MediumTest + @Feature({"AppBanners"}) + @CommandLineFlags.Add("enable-features=" + ChromeFeatureList.INSTALLABLE_AMBIENT_BADGE_INFOBAR) + public void testInProductHelp() throws Exception { + // Visit a site that is a PWA. The ambient badge should show. + String webBannerUrl = WebappTestPage.getServiceWorkerUrl(mTestServer); + resetEngagementForUrl(webBannerUrl, 10); + + InfoBarContainer container = mTabbedActivityTestRule.getInfoBarContainer(); + final InfobarListener listener = new InfobarListener(); + container.addAnimationListener(listener); + + Tab tab = mTabbedActivityTestRule.getActivity().getActivityTab(); + new TabLoadObserver(tab).fullyLoadUrl(webBannerUrl); + waitUntilAmbientBadgeInfoBarAppears(mTabbedActivityTestRule); + + waitForHelpBubble(withText(R.string.iph_pwa_install_available_text)).perform(click()); + assertThat(mTracker.wasDismissed(), is(true)); + + int callCount = mOnEventCallback.getCallCount(); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + AppMenuCoordinator coordinator = mTabbedActivityTestRule.getAppMenuCoordinator(); + AppMenuTestSupport.showAppMenu(coordinator, null, false); + AppMenuTestSupport.callOnItemClick(coordinator, R.id.add_to_homescreen_id); + }); + mOnEventCallback.waitForCallback(callCount, 1); + + assertThat(mTracker.getLastEvent(), is(EventConstants.PWA_INSTALL_MENU_SELECTED)); + } + + private ViewInteraction waitForHelpBubble(Matcher<View> matcher) { + View mainDecorView = mTabbedActivityTestRule.getActivity().getWindow().getDecorView(); + return onView(isRoot()) + .inRoot(RootMatchers.withDecorView(not(is(mainDecorView)))) + .check(waitForView(matcher)); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java index aa29d42b..9afeeca 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
@@ -10,7 +10,6 @@ import android.content.Context; import android.graphics.PointF; import android.support.test.InstrumentationRegistry; -import android.util.Log; import android.view.MotionEvent; import android.view.MotionEvent.PointerCoords; import android.view.MotionEvent.PointerProperties; @@ -28,10 +27,12 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.chromium.base.Log; import org.chromium.base.MathUtils; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.base.test.UiThreadTest; +import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; @@ -68,6 +69,8 @@ import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.UiRestriction; +import java.util.concurrent.TimeoutException; + /** * Unit tests for {@link org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome} */ @@ -92,6 +95,13 @@ private float mDpToPx; + private OneshotSupplierImpl<LayoutStateProvider> mLayoutStateProviderSupplier; + + class LayoutObserverCallbackHelper extends CallbackHelper { + @Layout.LayoutType + public int layoutType; + } + private void initializeMotionEvent() { mProperties[0] = new PointerProperties(); mProperties[0].id = 0; @@ -172,8 +182,14 @@ new ObservableSupplierImpl<>(); OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier = new OneshotSupplierImpl<>(); + + if (mLayoutStateProviderSupplier == null) { + mLayoutStateProviderSupplier = new OneshotSupplierImpl<>(); + } + mManagerPhone = new LayoutManagerChromePhone(layoutManagerHost, container, null, - tabContentManagerSupplier, overviewModeBehaviorSupplier); + tabContentManagerSupplier, overviewModeBehaviorSupplier, + mLayoutStateProviderSupplier); tabContentManagerSupplier.set(tabContentManager); mManager = mManagerPhone; CompositorAnimationHandler.setTestingMode(true); @@ -641,6 +657,207 @@ verifyStartSurfaceLayoutEnable(TabListCoordinator.TabListMode.LIST); } + @Test + @MediumTest + public void testLayoutObserverNotification_ShowAndHide_ToolbarSwipe() throws TimeoutException { + LayoutObserverCallbackHelper startedShowingCallback = new LayoutObserverCallbackHelper(); + LayoutObserverCallbackHelper finishedShowingCallback = new LayoutObserverCallbackHelper(); + LayoutObserverCallbackHelper startedHidingCallback = new LayoutObserverCallbackHelper(); + LayoutObserverCallbackHelper finishedHidingCallback = new LayoutObserverCallbackHelper(); + + setUpShowAndHideLayoutObserverNotification(startedShowingCallback, finishedShowingCallback, + startedHidingCallback, finishedHidingCallback); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + performToolbarSideSwipe(ScrollDirection.RIGHT); + Assert.assertEquals( + Layout.LayoutType.TOOLBAR_SWIPE, mManager.getActiveLayout().getLayoutType()); + Assert.assertTrue(mLayoutStateProviderSupplier.get().isLayoutVisible( + Layout.LayoutType.TOOLBAR_SWIPE)); + }); + + // The |startedShowingCallback| callCount 0 is reserved for the default layout during + // initialization. Because LayoutManager does not explicitly hide the old layout when a new + // layout is forced to show, the callCount for |finishedShowingCallback|, + // |startedHidingCallback|, and |finishedHidingCallback| are still 0. + // TODO(crbug.com/1108496): update the callCount when LayoutManager explicitly hide the old + // layout. + startedShowingCallback.waitForCallback(1); + Assert.assertEquals(Layout.LayoutType.TOOLBAR_SWIPE, startedShowingCallback.layoutType); + + // TODO(crbug.com/1108496): Enable the following two lines after layout.doneShowing() is + // always call when trying to show a Layout. + // finishedShowingCallback.waitForCallback(0); + // Assert.assertEquals(Layout.LayoutType.TOOLBAR_SWIPE, finishedShowingCallback.layoutType); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + finishToolbarSideSwipe(); + Assert.assertEquals( + Layout.LayoutType.BROWSING, mManager.getActiveLayout().getLayoutType()); + Assert.assertTrue( + mLayoutStateProviderSupplier.get().isLayoutVisible(Layout.LayoutType.BROWSING)); + }); + + startedHidingCallback.waitForCallback(0); + Assert.assertEquals(Layout.LayoutType.TOOLBAR_SWIPE, startedHidingCallback.layoutType); + + finishedHidingCallback.waitForCallback(0); + Assert.assertEquals(Layout.LayoutType.TOOLBAR_SWIPE, finishedHidingCallback.layoutType); + + startedShowingCallback.waitForCallback(2); + Assert.assertEquals(Layout.LayoutType.BROWSING, startedShowingCallback.layoutType); + + // TODO(crbug.com/1108496): Enable the following two lines after layout.doneShowing() is + // always call when trying to show a Layout. + // finishedShowingCallback.waitForCallback(1); + // Assert.assertEquals(Layout.LayoutType.BROWSING, finishedShowingCallback.layoutType); + } + + @Test + @MediumTest + public void testLayoutObserverNotification_ShowAndHide_TabSwitcher() throws TimeoutException { + LayoutObserverCallbackHelper startedShowingCallback = new LayoutObserverCallbackHelper(); + LayoutObserverCallbackHelper finishedShowingCallback = new LayoutObserverCallbackHelper(); + LayoutObserverCallbackHelper startedHidingCallback = new LayoutObserverCallbackHelper(); + LayoutObserverCallbackHelper finishedHidingCallback = new LayoutObserverCallbackHelper(); + + setUpShowAndHideLayoutObserverNotification(startedShowingCallback, finishedShowingCallback, + startedHidingCallback, finishedHidingCallback); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + mManager.showOverview(true); + + Assert.assertTrue( + "layoutManager is way too long to end motion", simulateTime(mManager, 1000)); + Assert.assertEquals( + Layout.LayoutType.TAB_SWITCHER, mManager.getActiveLayout().getLayoutType()); + Assert.assertTrue(mLayoutStateProviderSupplier.get().isLayoutVisible( + Layout.LayoutType.TAB_SWITCHER)); + }); + + // The |startedShowingCallback| callCount 0 is reserved for the default layout during + // initialization. Because LayoutManager does not explicitly hide the old layout when a new + // layout is forced to show, the callCount for |finishedShowingCallback|, + // |startedHidingCallback|, and |finishedHidingCallback| are still 0. + // TODO(crbug.com/1108496): update the callCount when LayoutManager explicitly hide the old + // layout. + startedShowingCallback.waitForCallback(1); + Assert.assertEquals(Layout.LayoutType.TAB_SWITCHER, startedShowingCallback.layoutType); + + finishedShowingCallback.waitForCallback(0); + Assert.assertEquals(Layout.LayoutType.TAB_SWITCHER, finishedShowingCallback.layoutType); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + mManagerPhone.hideOverview(true); + Assert.assertTrue( + "layoutManager is way too long to end motion", simulateTime(mManager, 1000)); + + Assert.assertTrue( + mLayoutStateProviderSupplier.get().isLayoutVisible(Layout.LayoutType.BROWSING)); + }); + + startedHidingCallback.waitForCallback(0); + Assert.assertEquals(Layout.LayoutType.TAB_SWITCHER, startedHidingCallback.layoutType); + + finishedHidingCallback.waitForCallback(0); + Assert.assertEquals(Layout.LayoutType.TAB_SWITCHER, finishedHidingCallback.layoutType); + + startedShowingCallback.waitForCallback(2); + Assert.assertEquals(Layout.LayoutType.BROWSING, startedShowingCallback.layoutType); + + // TODO(crbug.com/1108496): Enable the following two lines after layout.doneShowing() is + // always call when trying to show a Layout. + // finishedShowingCallback.waitForCallback(1); + // Assert.assertEquals(Layout.LayoutType.BROWSING, finishedShowingCallback.layoutType); + } + + private void setUpShowAndHideLayoutObserverNotification( + LayoutObserverCallbackHelper startedShowingCallback, + LayoutObserverCallbackHelper finishedShowingCallback, + LayoutObserverCallbackHelper startedHidingCallback, + LayoutObserverCallbackHelper finishedHidingCallback) throws TimeoutException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mLayoutStateProviderSupplier = new OneshotSupplierImpl<>(); + + mLayoutStateProviderSupplier.onAvailable((layoutStateProvider) -> { + layoutStateProvider.addObserver(new LayoutStateProvider.LayoutStateObserver() { + @Override + public void onStartedShowing(int layoutType, boolean showToolbar) { + Log.d(TAG, "Started to show: " + layoutType); + startedShowingCallback.layoutType = layoutType; + startedShowingCallback.notifyCalled(); + } + + @Override + public void onFinishedShowing(int layoutType) { + Log.d(TAG, "finished to show: " + layoutType); + finishedShowingCallback.layoutType = layoutType; + finishedShowingCallback.notifyCalled(); + } + + @Override + public void onStartedHiding( + int layoutType, boolean showToolbar, boolean delayAnimation) { + Log.d(TAG, "Started to hide: " + layoutType); + startedHidingCallback.layoutType = layoutType; + startedHidingCallback.notifyCalled(); + } + + @Override + public void onFinishedHiding(int layoutType) { + Log.d(TAG, "finished to hide: " + layoutType); + finishedHidingCallback.layoutType = layoutType; + finishedHidingCallback.notifyCalled(); + } + }); + }); + + initializeLayoutManagerPhone(2, 0); + Assert.assertEquals( + Layout.LayoutType.BROWSING, mManager.getActiveLayout().getLayoutType()); + }); + + startedShowingCallback.waitForCallback(0); + Assert.assertEquals(Layout.LayoutType.BROWSING, startedShowingCallback.layoutType); + } + + @Test + @MediumTest + public void testLayoutObserverNotification_TabSelectionHinted() throws TimeoutException { + CallbackHelper tabSelectionHintedCallback = new CallbackHelper(); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + mLayoutStateProviderSupplier = new OneshotSupplierImpl<>(); + + mLayoutStateProviderSupplier.onAvailable((layoutStateProvider) -> { + layoutStateProvider.addObserver(new LayoutStateProvider.LayoutStateObserver() { + @Override + public void onTabSelectionHinted(int tabId) { + Log.d(TAG, "onTabSelectionHinted"); + tabSelectionHintedCallback.notifyCalled(); + } + }); + }); + + initializeLayoutManagerPhone(2, 0); + mManager.showOverview(true); + + Assert.assertTrue( + "layoutManager is way too long to end motion", simulateTime(mManager, 1000)); + Assert.assertEquals( + Layout.LayoutType.TAB_SWITCHER, mManager.getActiveLayout().getLayoutType()); + + mManagerPhone.hideOverview(true); + Assert.assertTrue( + "layoutManager is way too long to end motion", simulateTime(mManager, 1000)); + + Assert.assertEquals( + Layout.LayoutType.BROWSING, mManager.getActiveLayout().getLayoutType()); + }); + + tabSelectionHintedCallback.waitForCallback(0); + } + @Before public void setUp() { MockitoAnnotations.initMocks(this); @@ -721,6 +938,7 @@ final int finalId = model.getTabAt(finalIndex).getId(); performToolbarSideSwipe(direction); + finishToolbarSideSwipe(); Assert.assertEquals("Unexpected model change after side swipe", model.isIncognito(), mTabModelSelector.isIncognitoSelected()); @@ -751,14 +969,21 @@ // TODO(mdjones): Update implementation of EdgeSwipeHandler to work this way by default. eventHandler.swipeUpdated(deltaX, 0.f, deltaX, 0.f, deltaX, 0.f); eventHandler.swipeUpdated(deltaX, 0.f, deltaX, 0.f, deltaX, 0.f); - eventHandler.swipeFinished(); - Assert.assertTrue("LayoutManager#getActiveLayout() should be ToolbarSwipeLayout", mManager.getActiveLayout() instanceof ToolbarSwipeLayout); Assert.assertTrue("LayoutManager took too long to finish the animations", simulateTime(mManager, 1000)); } + private void finishToolbarSideSwipe() { + final EdgeSwipeHandler eventHandler = mManager.getToolbarSwipeHandler(); + Assert.assertNotNull("LayoutManager#getToolbarSwipeHandler() returned null", eventHandler); + + eventHandler.swipeFinished(); + Assert.assertTrue("LayoutManager took too long to finish the animations", + simulateTime(mManager, 1000)); + } + @Override public Tab createTab(int id, boolean incognito) { return MockTab.createAndInitialize(id, incognito);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetTest.java index b6a89b2ab..e59151a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetTest.java
@@ -223,6 +223,9 @@ @Test @MediumTest public void testDismissCollapsedSheetWithDismissButton() { + MetricsUtils.HistogramDelta accountConsistencyHistogram = + new HistogramDelta("Signin.AccountConsistencyPromoAction", + AccountConsistencyPromoAction.DISMISSED_BUTTON); buildAndShowCollapsedBottomSheet(); onView(withText(PROFILE_DATA1.getAccountName())).check(matches(isDisplayed())); BottomSheetController controller = getBottomSheetController(); @@ -232,6 +235,7 @@ Assert.assertFalse(controller.isSheetOpen()); verify(mAccountPickerDelegateMock).onDismiss(); Assert.assertEquals(0, mFakeProfileDataSource.getNumberOfObservers()); + Assert.assertEquals(1, accountConsistencyHistogram.getDelta()); } @Test @@ -386,6 +390,9 @@ @Test @MediumTest public void testSignInGeneralError() { + MetricsUtils.HistogramDelta accountConsistencyHistogram = + new HistogramDelta("Signin.AccountConsistencyPromoAction", + AccountConsistencyPromoAction.GENERIC_ERROR_SHOWN); // Throws a connection error during the sign-in action doAnswer(invocation -> { Callback<GoogleServiceAuthError> onSignInErrorCallback = invocation.getArgument(1); @@ -409,11 +416,15 @@ onView(withId(R.id.account_picker_selected_account)).check(matches(not(isDisplayed()))); onView(withId(R.id.account_picker_signin_spinner_view)).check(matches(not(isDisplayed()))); onView(withId(R.id.account_picker_dismiss_button)).check(matches(not(isDisplayed()))); + Assert.assertEquals(1, accountConsistencyHistogram.getDelta()); } @Test @MediumTest public void testSignInAuthError() { + MetricsUtils.HistogramDelta accountConsistencyHistogram = + new HistogramDelta("Signin.AccountConsistencyPromoAction", + AccountConsistencyPromoAction.AUTH_ERROR_SHOWN); CoreAccountInfo coreAccountInfo = mAccountManagerTestRule.toCoreAccountInfo(PROFILE_DATA1.getAccountName()); // Throws an auth error during the sign-in action @@ -437,6 +448,7 @@ onView(withId(R.id.account_picker_selected_account)).check(matches(not(isDisplayed()))); onView(withId(R.id.account_picker_signin_spinner_view)).check(matches(not(isDisplayed()))); onView(withId(R.id.account_picker_dismiss_button)).check(matches(not(isDisplayed()))); + Assert.assertEquals(1, accountConsistencyHistogram.getDelta()); } @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/SceneOverlayTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/SceneOverlayTest.java index efbbd4e9..e2d5e24 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/SceneOverlayTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/SceneOverlayTest.java
@@ -5,6 +5,8 @@ package org.chromium.chrome.browser.compositor.layouts; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.when; import android.content.Context; @@ -21,6 +23,7 @@ import org.robolectric.annotation.Config; import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanel; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; @@ -53,6 +56,9 @@ @Mock private ObservableSupplier<TabContentManager> mTabContentManagerSupplier; + @Mock + private OneshotSupplierImpl<LayoutStateProvider> mLayoutStateProviderOneshotSupplier; + private LayoutManager mLayoutManager; @Before @@ -62,9 +68,10 @@ when(mLayoutManagerHost.getContext()).thenReturn(mContext); when(mContext.getResources()).thenReturn(mResources); when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics); + doNothing().when(mLayoutStateProviderOneshotSupplier).set(any()); - mLayoutManager = - new LayoutManager(mLayoutManagerHost, mContainerView, mTabContentManagerSupplier); + mLayoutManager = new LayoutManager(mLayoutManagerHost, mContainerView, + mTabContentManagerSupplier, mLayoutStateProviderOneshotSupplier); } @Test
diff --git a/chrome/android/monochrome/BUILD.gn b/chrome/android/monochrome/BUILD.gn index a76b89db..0252d05 100644 --- a/chrome/android/monochrome/BUILD.gn +++ b/chrome/android/monochrome/BUILD.gn
@@ -2,22 +2,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/config/android/config.gni") +import("//build/config/python.gni") -group("monochrome_public_apk_checker") { +python_library("monochrome_public_apk_checker") { testonly = true + pydeps_file = + "//chrome/android/monochrome/scripts/monochrome_python_tests.pydeps" data_deps = [ "//android_webview:system_webview_apk", "//chrome/android:chrome_public_apk", "//chrome/android:monochrome_public_apk", ] - - data = [ - "scripts/", - "//testing/scripts/common.py", - "//testing/scripts/run_isolated_script_test.py", - "//third_party/catapult/devil/", - "//third_party/catapult/third_party/typ/", - "//testing/xvfb.py", - ] }
diff --git a/chrome/android/monochrome/scripts/monochrome_android_manifest_test.py b/chrome/android/monochrome/scripts/monochrome_android_manifest_test.py index dd9dcfbd..7f29074 100755 --- a/chrome/android/monochrome/scripts/monochrome_android_manifest_test.py +++ b/chrome/android/monochrome/scripts/monochrome_android_manifest_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python2.7 # # Copyright 2020 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be
diff --git a/chrome/android/monochrome/scripts/monochrome_dexdump_test.py b/chrome/android/monochrome/scripts/monochrome_dexdump_test.py index 91f4404..12aef8a9 100755 --- a/chrome/android/monochrome/scripts/monochrome_dexdump_test.py +++ b/chrome/android/monochrome/scripts/monochrome_dexdump_test.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python2.7 # # Copyright 2020 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be
diff --git a/chrome/android/monochrome/scripts/monochrome_python_tests.pydeps b/chrome/android/monochrome/scripts/monochrome_python_tests.pydeps new file mode 100644 index 0000000..1694d42 --- /dev/null +++ b/chrome/android/monochrome/scripts/monochrome_python_tests.pydeps
@@ -0,0 +1,61 @@ +# Generated by running: +# build/print_python_deps.py chrome/android/monochrome/scripts +build/android/devil_chromium.py +build/android/pylib/__init__.py +build/android/pylib/constants/__init__.py +build/android/pylib/constants/host_paths.py +chrome/android/monochrome/scripts/monochrome_android_manifest_test.py +chrome/android/monochrome/scripts/monochrome_apk_checker_test.py +chrome/android/monochrome/scripts/monochrome_dexdump_test.py +chrome/android/monochrome/scripts/monochrome_python_tests.py +third_party/catapult/common/py_utils/py_utils/__init__.py +third_party/catapult/common/py_utils/py_utils/cloud_storage.py +third_party/catapult/common/py_utils/py_utils/cloud_storage_global_lock.py +third_party/catapult/common/py_utils/py_utils/lock.py +third_party/catapult/dependency_manager/dependency_manager/__init__.py +third_party/catapult/dependency_manager/dependency_manager/archive_info.py +third_party/catapult/dependency_manager/dependency_manager/base_config.py +third_party/catapult/dependency_manager/dependency_manager/cloud_storage_info.py +third_party/catapult/dependency_manager/dependency_manager/dependency_info.py +third_party/catapult/dependency_manager/dependency_manager/dependency_manager_util.py +third_party/catapult/dependency_manager/dependency_manager/exceptions.py +third_party/catapult/dependency_manager/dependency_manager/local_path_info.py +third_party/catapult/dependency_manager/dependency_manager/manager.py +third_party/catapult/dependency_manager/dependency_manager/uploader.py +third_party/catapult/devil/devil/__init__.py +third_party/catapult/devil/devil/android/__init__.py +third_party/catapult/devil/devil/android/constants/__init__.py +third_party/catapult/devil/devil/android/constants/chrome.py +third_party/catapult/devil/devil/android/ndk/__init__.py +third_party/catapult/devil/devil/android/ndk/abis.py +third_party/catapult/devil/devil/android/sdk/__init__.py +third_party/catapult/devil/devil/android/sdk/build_tools.py +third_party/catapult/devil/devil/android/sdk/keyevent.py +third_party/catapult/devil/devil/android/sdk/version_codes.py +third_party/catapult/devil/devil/base_error.py +third_party/catapult/devil/devil/constants/__init__.py +third_party/catapult/devil/devil/constants/exit_codes.py +third_party/catapult/devil/devil/devil_env.py +third_party/catapult/devil/devil/utils/__init__.py +third_party/catapult/devil/devil/utils/cmd_helper.py +third_party/catapult/devil/devil/utils/lazy/__init__.py +third_party/catapult/devil/devil/utils/lazy/weak_constant.py +third_party/catapult/devil/devil/utils/reraiser_thread.py +third_party/catapult/devil/devil/utils/timeout_retry.py +third_party/catapult/devil/devil/utils/watchdog_timer.py +third_party/catapult/third_party/typ/typ/__init__.py +third_party/catapult/third_party/typ/typ/arg_parser.py +third_party/catapult/third_party/typ/typ/artifacts.py +third_party/catapult/third_party/typ/typ/expectations_parser.py +third_party/catapult/third_party/typ/typ/fakes/__init__.py +third_party/catapult/third_party/typ/typ/fakes/host_fake.py +third_party/catapult/third_party/typ/typ/host.py +third_party/catapult/third_party/typ/typ/json_results.py +third_party/catapult/third_party/typ/typ/pool.py +third_party/catapult/third_party/typ/typ/printer.py +third_party/catapult/third_party/typ/typ/python_2_3_compat.py +third_party/catapult/third_party/typ/typ/runner.py +third_party/catapult/third_party/typ/typ/stats.py +third_party/catapult/third_party/typ/typ/test_case.py +third_party/catapult/third_party/typ/typ/version.py +third_party/catapult/third_party/zipfile/zipfile_2_7_13.py
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 475a305d..e4a28ea 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -4351,6 +4351,7 @@ "//chromeos/services/secure_channel/public/mojom", "//chromeos/settings", "//chromeos/strings", + "//chromeos/ui/base", "//chromeos/ui/vector_icons", "//components/arc", "//components/arc:arc_base",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 0e94e95..cdfc5f7 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3787,6 +3787,15 @@ {"files-filters-in-recents", flag_descriptions::kFiltersInRecentsName, flag_descriptions::kFiltersInRecentsDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kFiltersInRecents)}, + {"files-js-modules", flag_descriptions::kFilesJsModulesName, + flag_descriptions::kFilesJsModulesDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kFilesJsModules)}, + {"audio-player-js-modules", flag_descriptions::kAudioPlayerJsModulesName, + flag_descriptions::kAudioPlayerJsModulesDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kAudioPlayerJsModules)}, + {"video-player-js-modules", flag_descriptions::kVideoPlayerJsModulesName, + flag_descriptions::kVideoPlayerJsModulesDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kVideoPlayerJsModules)}, {"files-ng", flag_descriptions::kFilesNGName, flag_descriptions::kFilesNGDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kFilesNG)},
diff --git a/chrome/browser/android/externalauth/BUILD.gn b/chrome/browser/android/externalauth/BUILD.gn new file mode 100644 index 0000000..d311a83 --- /dev/null +++ b/chrome/browser/android/externalauth/BUILD.gn
@@ -0,0 +1,11 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/android/rules.gni") + +# We can't use android_library here since gn doesn't allow those with empty +# sources. Use java_group until we have files in this module. +java_group("java") { + # Empty module for a three sided patch. +}
diff --git a/chrome/browser/android/externalauth/OWNERS b/chrome/browser/android/externalauth/OWNERS new file mode 100644 index 0000000..2df71ef --- /dev/null +++ b/chrome/browser/android/externalauth/OWNERS
@@ -0,0 +1,3 @@ +file://chrome/android/OWNERS + +peconn@chromium.org
diff --git a/chrome/browser/banners/app_banner_manager.cc b/chrome/browser/banners/app_banner_manager.cc index b3f3285..febd4d4 100644 --- a/chrome/browser/banners/app_banner_manager.cc +++ b/chrome/browser/banners/app_banner_manager.cc
@@ -253,14 +253,14 @@ return false; } -bool AppBannerManager::ShouldDeferToRelatedApplication() const { +bool AppBannerManager::ShouldDeferToRelatedNonWebApp() const { for (const auto& related_app : manifest_.related_applications) { if (manifest_.prefer_related_applications && - IsSupportedAppPlatform( + IsSupportedNonWebAppPlatform( related_app.platform.value_or(base::string16()))) { return true; } - if (IsRelatedAppInstalled(related_app)) + if (IsRelatedNonWebAppInstalled(related_app)) return true; } return false; @@ -397,7 +397,7 @@ return; } - if (ShouldDeferToRelatedApplication()) { + if (ShouldDeferToRelatedNonWebApp()) { SetInstallableWebAppCheckResult( InstallableWebAppCheckResult::kByUserRequest); Stop(PREFER_RELATED_APPLICATIONS);
diff --git a/chrome/browser/banners/app_banner_manager.h b/chrome/browser/banners/app_banner_manager.h index 853d6d1..007083d 100644 --- a/chrome/browser/banners/app_banner_manager.h +++ b/chrome/browser/banners/app_banner_manager.h
@@ -195,9 +195,9 @@ // GetAppIdentifier() must return a valid value for this method to work. bool CheckIfShouldShowBanner(); - // Returns whether the site would prefer a related application be installed - // instead of the PWA or a related application is already installed. - bool ShouldDeferToRelatedApplication() const; + // Returns whether the site would prefer a related non-web app be installed + // instead of the PWA or a related non-web app is already installed. + bool ShouldDeferToRelatedNonWebApp() const; // Return a string identifying this app for metrics. virtual std::string GetAppIdentifier(); @@ -219,11 +219,14 @@ bool ShouldBypassEngagementChecks() const; // Returns whether installation of apps from |platform| is supported on the - // current device. - virtual bool IsSupportedAppPlatform(const base::string16& platform) const = 0; + // current device and the platform delivers apps considered replacements for + // web apps. + virtual bool IsSupportedNonWebAppPlatform( + const base::string16& platform) const = 0; - // Returns whether |related_app| is already installed. - virtual bool IsRelatedAppInstalled( + // Returns whether |related_app| is already installed and considered a + // replacement for the manifest's web app. + virtual bool IsRelatedNonWebAppInstalled( const blink::Manifest::RelatedApplication& related_app) const = 0; // Returns whether the current page is already installed as a web app, or
diff --git a/chrome/browser/banners/app_banner_manager_android.cc b/chrome/browser/banners/app_banner_manager_android.cc index 7e04d1d2..ddf34a91 100644 --- a/chrome/browser/banners/app_banner_manager_android.cc +++ b/chrome/browser/banners/app_banner_manager_android.cc
@@ -551,13 +551,13 @@ infobar_service->RemoveInfoBar(ambient_badge_infobar); } -bool AppBannerManagerAndroid::IsSupportedAppPlatform( +bool AppBannerManagerAndroid::IsSupportedNonWebAppPlatform( const base::string16& platform) const { // TODO(https://crbug.com/949430): Implement for Android apps. return false; } -bool AppBannerManagerAndroid::IsRelatedAppInstalled( +bool AppBannerManagerAndroid::IsRelatedNonWebAppInstalled( const blink::Manifest::RelatedApplication& related_app) const { // TODO(https://crbug.com/949430): Implement for Android apps. return false;
diff --git a/chrome/browser/banners/app_banner_manager_android.h b/chrome/browser/banners/app_banner_manager_android.h index 03e5af9d..a4a3b3d 100644 --- a/chrome/browser/banners/app_banner_manager_android.h +++ b/chrome/browser/banners/app_banner_manager_android.h
@@ -97,8 +97,9 @@ void MaybeShowAmbientBadge() override; base::WeakPtr<AppBannerManager> GetWeakPtr() override; void InvalidateWeakPtrs() override; - bool IsSupportedAppPlatform(const base::string16& platform) const override; - bool IsRelatedAppInstalled( + bool IsSupportedNonWebAppPlatform( + const base::string16& platform) const override; + bool IsRelatedNonWebAppInstalled( const blink::Manifest::RelatedApplication& related_app) const override; private:
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc index 8cd83ac..69a21436 100644 --- a/chrome/browser/banners/app_banner_manager_browsertest.cc +++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -128,11 +128,12 @@ void InvalidateWeakPtrs() override { weak_factory_.InvalidateWeakPtrs(); } - bool IsSupportedAppPlatform(const base::string16& platform) const override { + bool IsSupportedNonWebAppPlatform( + const base::string16& platform) const override { return base::EqualsASCII(platform, "chrome_web_store"); } - bool IsRelatedAppInstalled( + bool IsRelatedNonWebAppInstalled( const blink::Manifest::RelatedApplication& related_app) const override { // Corresponds to the id listed in manifest_listing_related_chrome_app.json. return base::EqualsASCII(related_app.platform.value_or(base::string16()),
diff --git a/chrome/browser/banners/app_banner_manager_desktop.cc b/chrome/browser/banners/app_banner_manager_desktop.cc index 0aefdede..666fbed 100644 --- a/chrome/browser/banners/app_banner_manager_desktop.cc +++ b/chrome/browser/banners/app_banner_manager_desktop.cc
@@ -103,7 +103,7 @@ weak_factory_.InvalidateWeakPtrs(); } -bool AppBannerManagerDesktop::IsSupportedAppPlatform( +bool AppBannerManagerDesktop::IsSupportedNonWebAppPlatform( const base::string16& platform) const { if (base::EqualsASCII(platform, kPlatformChromeWebStore)) return true; @@ -119,7 +119,7 @@ return false; } -bool AppBannerManagerDesktop::IsRelatedAppInstalled( +bool AppBannerManagerDesktop::IsRelatedNonWebAppInstalled( const blink::Manifest::RelatedApplication& related_app) const { if (!related_app.id || related_app.id->empty() || !related_app.platform || related_app.platform->empty()) {
diff --git a/chrome/browser/banners/app_banner_manager_desktop.h b/chrome/browser/banners/app_banner_manager_desktop.h index fcb53e1c..0a05e0a 100644 --- a/chrome/browser/banners/app_banner_manager_desktop.h +++ b/chrome/browser/banners/app_banner_manager_desktop.h
@@ -57,8 +57,9 @@ // AppBannerManager overrides. base::WeakPtr<AppBannerManager> GetWeakPtr() override; void InvalidateWeakPtrs() override; - bool IsSupportedAppPlatform(const base::string16& platform) const override; - bool IsRelatedAppInstalled( + bool IsSupportedNonWebAppPlatform( + const base::string16& platform) const override; + bool IsRelatedNonWebAppInstalled( const blink::Manifest::RelatedApplication& related_app) const override; // Called when the web app install initiated by a banner has completed.
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index d986e54..c8273ee 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -853,6 +853,8 @@ "borealis/borealis_installer_factory.h", "borealis/borealis_installer_impl.cc", "borealis/borealis_installer_impl.h", + "borealis/borealis_launch_watcher.cc", + "borealis/borealis_launch_watcher.h", "borealis/borealis_prefs.cc", "borealis/borealis_prefs.h", "borealis/borealis_service.cc", @@ -3262,6 +3264,7 @@ "borealis/borealis_context_manager_unittest.cc", "borealis/borealis_features_unittest.cc", "borealis/borealis_installer_unittest.cc", + "borealis/borealis_launch_watcher_unittest.cc", "borealis/borealis_task_unittest.cc", "camera_mic/vm_camera_mic_manager_unittest.cc", "cert_provisioning/cert_provisioning_invalidator_unittest.cc",
diff --git a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.cc b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.cc index d2a2b48..c153095 100644 --- a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.cc +++ b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.cc
@@ -7,9 +7,9 @@ #include <memory> #include <string> -#include "ash/public/cpp/window_pin_type.h" -#include "ash/public/cpp/window_properties.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" #include "components/arc/arc_util.h" #include "components/arc/metrics/arc_metrics_constants.h" #include "ui/aura/env.h" @@ -82,8 +82,8 @@ return false; // Stop observing as target window is already found. StopObserving(); - window->SetProperty(ash::kWindowPinTypeKey, - ash::WindowPinType::kTrustedPinned); + window->SetProperty(chromeos::kWindowPinTypeKey, + chromeos::WindowPinType::kTrustedPinned); if (delegate_) delegate_->OnAppWindowLaunched(); return true;
diff --git a/chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.cc b/chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.cc index 8ff62f5..82fd671 100644 --- a/chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.cc +++ b/chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.cc
@@ -5,7 +5,6 @@ #include <chrome/browser/chromeos/app_mode/web_app/web_kiosk_app_launcher.h> #include <memory> -#include "ash/public/cpp/window_pin_type.h" #include "ash/public/cpp/window_properties.h" #include "base/bind.h" #include "base/logging.h" @@ -18,6 +17,7 @@ #include "chrome/browser/web_applications/components/web_app_data_retriever.h" #include "chrome/browser/web_applications/components/web_app_url_loader.h" #include "chrome/browser/web_applications/web_app_install_task.h" +#include "chromeos/ui/base/window_pin_type.h" #include "components/account_id/account_id.h" #include "ui/aura/window.h" #include "ui/base/page_transition_types.h"
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager.cc b/chrome/browser/chromeos/arc/session/arc_session_manager.cc index a3d7732b..d25ee76 100644 --- a/chrome/browser/chromeos/arc/session/arc_session_manager.cc +++ b/chrome/browser/chromeos/arc/session/arc_session_manager.cc
@@ -447,7 +447,7 @@ : arc_session_runner_(std::move(arc_session_runner)), adb_sideloading_availability_delegate_( std::move(adb_sideloading_availability_delegate)), - attempt_user_exit_callback_(base::Bind(chrome::AttemptUserExit)), + attempt_user_exit_callback_(base::BindRepeating(chrome::AttemptUserExit)), property_files_source_dir_(base::FilePath( IsArcVmEnabled() ? kPropertyFilesPathVm : kPropertyFilesPath)), property_files_dest_dir_( @@ -1208,8 +1208,8 @@ arc_session_runner_->RequestStartMiniInstance(); terms_of_service_negotiator_->StartNegotiation( - base::Bind(&ArcSessionManager::OnTermsOfServiceNegotiated, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&ArcSessionManager::OnTermsOfServiceNegotiated, + weak_ptr_factory_.GetWeakPtr())); } void ArcSessionManager::OnTermsOfServiceNegotiated(bool accepted) { @@ -1266,8 +1266,8 @@ android_management_checker_ = std::make_unique<ArcAndroidManagementChecker>( profile_, false /* retry_on_error */); android_management_checker_->StartCheck( - base::Bind(&ArcSessionManager::OnAndroidManagementChecked, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&ArcSessionManager::OnAndroidManagementChecked, + weak_ptr_factory_.GetWeakPtr())); } void ArcSessionManager::OnAndroidManagementChecked( @@ -1316,8 +1316,8 @@ android_management_checker_ = std::make_unique<ArcAndroidManagementChecker>( profile_, true /* retry_on_error */); android_management_checker_->StartCheck( - base::Bind(&ArcSessionManager::OnBackgroundAndroidManagementChecked, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&ArcSessionManager::OnBackgroundAndroidManagementChecked, + weak_ptr_factory_.GetWeakPtr())); } void ArcSessionManager::OnBackgroundAndroidManagementChecked( @@ -1546,7 +1546,7 @@ } void ArcSessionManager::SetAttemptUserExitCallbackForTesting( - const base::Closure& callback) { + const base::RepeatingClosure& callback) { DCHECK(!callback.is_null()); attempt_user_exit_callback_ = callback; }
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager.h b/chrome/browser/chromeos/arc/session/arc_session_manager.h index ff6fbf9..6000a15 100644 --- a/chrome/browser/chromeos/arc/session/arc_session_manager.h +++ b/chrome/browser/chromeos/arc/session/arc_session_manager.h
@@ -250,7 +250,8 @@ void SetArcSessionRunnerForTesting( std::unique_ptr<ArcSessionRunner> arc_session_runner); ArcSessionRunner* GetArcSessionRunnerForTesting(); - void SetAttemptUserExitCallbackForTesting(const base::Closure& callback); + void SetAttemptUserExitCallbackForTesting( + const base::RepeatingClosure& callback); // Returns whether the Play Store app is requested to be launched by this // class. Should be used only for tests. @@ -418,7 +419,7 @@ base::TimeTicks sign_in_start_time_; // The time when ARC was about to start. base::TimeTicks arc_start_time_; - base::Closure attempt_user_exit_callback_; + base::RepeatingClosure attempt_user_exit_callback_; ArcAppIdProviderImpl app_id_provider_;
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc b/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc index 94ebc39..ea246baf 100644 --- a/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc +++ b/chrome/browser/chromeos/arc/session/arc_session_manager_unittest.cc
@@ -1282,7 +1282,8 @@ // and not invoked then, including TearDown(). bool terminated = false; arc_session_manager()->SetAttemptUserExitCallbackForTesting( - base::Bind([](bool* terminated) { *terminated = true; }, &terminated)); + base::BindRepeating([](bool* terminated) { *terminated = true; }, + &terminated)); arc_session_manager()->OnProvisioningFinished( ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR, nullptr);
diff --git a/chrome/browser/chromeos/borealis/borealis_context.cc b/chrome/browser/chromeos/borealis/borealis_context.cc index ee0e4013c..b3c5397 100644 --- a/chrome/browser/chromeos/borealis/borealis_context.cc +++ b/chrome/browser/chromeos/borealis/borealis_context.cc
@@ -6,6 +6,7 @@ namespace borealis { +BorealisContext::~BorealisContext() = default; BorealisContext::BorealisContext() = default; BorealisContext::BorealisContext(Profile* profile) : profile_(profile) {}
diff --git a/chrome/browser/chromeos/borealis/borealis_context.h b/chrome/browser/chromeos/borealis/borealis_context.h index a1ccf05..51ee38b1 100644 --- a/chrome/browser/chromeos/borealis/borealis_context.h +++ b/chrome/browser/chromeos/borealis/borealis_context.h
@@ -19,7 +19,7 @@ public: BorealisContext(const BorealisContext&) = delete; BorealisContext& operator=(const BorealisContext&) = delete; - ~BorealisContext() = default; + ~BorealisContext(); static BorealisContext* CreateBorealisContextForTesting() { return new BorealisContext(); @@ -31,9 +31,14 @@ bool borealis_running() const { return borealis_running_; } void set_borealis_running(bool success) { borealis_running_ = success; } - const std::string& vm_name() { return vm_name_; } + const std::string& vm_name() const { return vm_name_; } void set_vm_name(std::string vm_name) { vm_name_ = std::move(vm_name); } + const std::string& container_name() const { return container_name_; } + void set_container_name(std::string container_name) { + container_name_ = std::move(container_name); + } + const std::string& root_path() const { return root_path_; } void set_root_path(std::string path) { root_path_ = std::move(path); } @@ -49,6 +54,7 @@ Profile* profile_ = nullptr; bool borealis_running_ = false; std::string vm_name_; + std::string container_name_; std::string root_path_; base::FilePath disk_path_; };
diff --git a/chrome/browser/chromeos/borealis/borealis_context_manager.cc b/chrome/browser/chromeos/borealis/borealis_context_manager.cc index 0b2f6391..d3b4492 100644 --- a/chrome/browser/chromeos/borealis/borealis_context_manager.cc +++ b/chrome/browser/chromeos/borealis/borealis_context_manager.cc
@@ -35,7 +35,7 @@ return failure_reason_; } -const BorealisContext& BorealisContextManager::Result::Success() { +const BorealisContext& BorealisContextManager::Result::Success() const { DCHECK(Ok()); return *ctx_; }
diff --git a/chrome/browser/chromeos/borealis/borealis_context_manager.h b/chrome/browser/chromeos/borealis/borealis_context_manager.h index 4d4e149..78313ded 100644 --- a/chrome/browser/chromeos/borealis/borealis_context_manager.h +++ b/chrome/browser/chromeos/borealis/borealis_context_manager.h
@@ -17,7 +17,12 @@ class BorealisContextManager : public KeyedService { public: // A list of possible outcomes for an attempt to startup borealis. - enum Status { kSuccess = 0, kMountFailed = 1 }; + enum Status { + kSuccess = 0, + kMountFailed = 1, + kDiskImageFailed = 2, + kStartVmFailed = 3, + }; // An attempt to launch borealis. If the launch succeeds, holds a reference to // the context created for that launch, otherwise holds an error. @@ -42,7 +47,7 @@ // In the event of a successful launch, returns a handle to the context // created for that launch. - const BorealisContext& Success(); + const BorealisContext& Success() const; private: Status status_;
diff --git a/chrome/browser/chromeos/borealis/borealis_context_manager_impl.cc b/chrome/browser/chromeos/borealis/borealis_context_manager_impl.cc index b4576476..f555519e 100644 --- a/chrome/browser/chromeos/borealis/borealis_context_manager_impl.cc +++ b/chrome/browser/chromeos/borealis/borealis_context_manager_impl.cc
@@ -4,10 +4,30 @@ #include "chrome/browser/chromeos/borealis/borealis_context_manager_impl.h" +#include <ostream> + #include "base/logging.h" #include "chrome/browser/chromeos/borealis/borealis_context_manager.h" #include "chrome/browser/chromeos/borealis/borealis_task.h" +namespace { + +std::ostream& operator<<(std::ostream& stream, + borealis::BorealisContextManager::Status status) { + switch (status) { + case borealis::BorealisContextManager::kSuccess: + return stream << "Success"; + case borealis::BorealisContextManager::kMountFailed: + return stream << "Mount Failed"; + case borealis::BorealisContextManager::kDiskImageFailed: + return stream << "Disk Image Failed"; + case borealis::BorealisContextManager::kStartVmFailed: + return stream << "Start VM Failed"; + } +} + +} // namespace + namespace borealis { BorealisContextManagerImpl::BorealisContextManagerImpl(Profile* profile) @@ -24,7 +44,7 @@ if (!is_borealis_starting_) { is_borealis_starting_ = true; task_queue_ = GetTasks(); - NextTask(/*should_continue=*/true); + NextTask(); } } @@ -34,6 +54,7 @@ task_queue.push(std::make_unique<MountDlc>()); task_queue.push(std::make_unique<CreateDiskImage>()); task_queue.push(std::make_unique<StartBorealisVm>()); + task_queue.push(std::make_unique<AwaitBorealisStartup>()); return task_queue; } @@ -41,17 +62,7 @@ callback_queue_.push(std::move(callback)); } -void BorealisContextManagerImpl::NextTask(bool should_continue) { - if (!should_continue) { - // TODO(b/168425531): Error handling should be expanded to give more - // information about which task failed, why it failed and what should happen - // as a result. - // For now just use some random error. - startup_status_ = kMountFailed; - startup_error_ = "A task failed when trying to start Borealis."; - OnQueueComplete(); - return; - } +void BorealisContextManagerImpl::NextTask() { if (task_queue_.empty()) { context_.set_borealis_running(true); is_borealis_running_ = true; @@ -62,10 +73,23 @@ current_task_ = std::move(task_queue_.front()); task_queue_.pop(); current_task_->Run(&context_, - base::BindOnce(&BorealisContextManagerImpl::NextTask, + base::BindOnce(&BorealisContextManagerImpl::TaskCallback, weak_factory_.GetWeakPtr())); } +void BorealisContextManagerImpl::TaskCallback(Status status, + std::string error) { + startup_status_ = status; + if (startup_status_ == kSuccess) { + NextTask(); + return; + } + startup_error_ = error; + LOG(ERROR) << "Startup failed: failure=" << startup_status_ + << " message=" << startup_error_; + OnQueueComplete(); +} + void BorealisContextManagerImpl::OnQueueComplete() { is_borealis_starting_ = false; while (!callback_queue_.empty()) {
diff --git a/chrome/browser/chromeos/borealis/borealis_context_manager_impl.h b/chrome/browser/chromeos/borealis/borealis_context_manager_impl.h index a57e826..2927bb4d 100644 --- a/chrome/browser/chromeos/borealis/borealis_context_manager_impl.h +++ b/chrome/browser/chromeos/borealis/borealis_context_manager_impl.h
@@ -33,7 +33,8 @@ private: void AddCallback(ResultCallback callback); - void NextTask(bool should_continue); + void NextTask(); + void TaskCallback(Status status, std::string error); void OnQueueComplete(); // Returns the result of the startup (i.e. the context if it succeeds, or an
diff --git a/chrome/browser/chromeos/borealis/borealis_context_manager_unittest.cc b/chrome/browser/chromeos/borealis/borealis_context_manager_unittest.cc index e2c6a67..0717f73 100644 --- a/chrome/browser/chromeos/borealis/borealis_context_manager_unittest.cc +++ b/chrome/browser/chromeos/borealis/borealis_context_manager_unittest.cc
@@ -21,19 +21,27 @@ namespace { MATCHER(IsSuccessResult, "") { - return arg.Ok(); + return arg.Ok() && arg.Success().vm_name() == "test_vm_name"; } MATCHER(IsFailureResult, "") { - return !arg.Ok(); + return !arg.Ok() && arg.Failure() == BorealisContextManager::kStartVmFailed && + arg.FailureReason() == "Something went wrong!"; } class MockTask : public BorealisTask { public: explicit MockTask(bool success) : success_(success) {} void Run(BorealisContext* context, - base::OnceCallback<void(bool)> callback) override { - std::move(callback).Run(/*should_continue=*/success_); + BorealisTask::CompletionStatusCallback callback) override { + if (success_) { + context->set_vm_name("test_vm_name"); + std::move(callback).Run(BorealisContextManager::kSuccess, ""); + } else { + // Just use a random error. + std::move(callback).Run(BorealisContextManager::kStartVmFailed, + "Something went wrong!"); + } } bool success_ = true; }; @@ -110,6 +118,18 @@ EXPECT_FALSE(tasks.empty()); } +TEST_F(BorealisContextManagerTest, NoTasksImpliesSuccess) { + testing::StrictMock<ResultCallbackHandler> callback_expectation; + + BorealisContextManagerImplForTesting context_manager( + profile_.get(), /*tasks=*/0, /*success=*/true); + EXPECT_CALL(callback_expectation, Callback(testing::_)) + .WillOnce(testing::Invoke( + [](BorealisContextManager::Result result) { result.Ok(); })); + context_manager.StartBorealis(callback_expectation.GetCallback()); + task_environment_.RunUntilIdle(); +} + TEST_F(BorealisContextManagerTest, StartupSucceedsForSuccessfulTask) { testing::StrictMock<ResultCallbackHandler> callback_expectation;
diff --git a/chrome/browser/chromeos/borealis/borealis_launch_watcher.cc b/chrome/browser/chromeos/borealis/borealis_launch_watcher.cc new file mode 100644 index 0000000..071fd05 --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_launch_watcher.cc
@@ -0,0 +1,59 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/borealis/borealis_launch_watcher.h" + +#include "base/threading/thread_task_runner_handle.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chromeos/dbus/dbus_thread_manager.h" + +namespace borealis { + +BorealisLaunchWatcher::BorealisLaunchWatcher(Profile* profile, + std::string vm_name) + : owner_id_(chromeos::ProfileHelper::GetUserIdHashFromProfile(profile)), + vm_name_(vm_name) { + chromeos::DBusThreadManager::Get()->GetCiceroneClient()->AddObserver(this); +} + +BorealisLaunchWatcher::~BorealisLaunchWatcher() { + chromeos::DBusThreadManager::Get()->GetCiceroneClient()->RemoveObserver(this); +} + +void BorealisLaunchWatcher::AwaitLaunch(OnLaunchCallback callback) { + if (container_started_signal_) { + std::move(callback).Run(container_started_signal_->container_name()); + } else { + if (callback_queue_.empty()) { + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&BorealisLaunchWatcher::TimeoutCallback, + weak_factory_.GetWeakPtr()), + timeout_); + } + callback_queue_.push(std::move(callback)); + } +} + +void BorealisLaunchWatcher::OnContainerStarted( + const vm_tools::cicerone::ContainerStartedSignal& signal) { + if (signal.owner_id() == owner_id_ && signal.vm_name() == vm_name_ && + !container_started_signal_) { + container_started_signal_ = signal; + while (!callback_queue_.empty()) { + std::move(callback_queue_.front()) + .Run(container_started_signal_->container_name()); + callback_queue_.pop(); + } + } +} + +void BorealisLaunchWatcher::TimeoutCallback() { + while (!callback_queue_.empty()) { + std::move(callback_queue_.front()).Run(base::nullopt); + callback_queue_.pop(); + } +} + +} // namespace borealis
diff --git a/chrome/browser/chromeos/borealis/borealis_launch_watcher.h b/chrome/browser/chromeos/borealis/borealis_launch_watcher.h new file mode 100644 index 0000000..ba19e75 --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_launch_watcher.h
@@ -0,0 +1,58 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_LAUNCH_WATCHER_H_ +#define CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_LAUNCH_WATCHER_H_ + +#include "base/callback.h" +#include "base/containers/queue.h" +#include "base/memory/weak_ptr.h" +#include "chromeos/dbus/cicerone_client.h" + +class Profile; + +namespace borealis { + +// Watches to see if a specified VM (from a given owner id and vm name) was +// started. +class BorealisLaunchWatcher : public chromeos::CiceroneClient::Observer { + public: + using OnLaunchCallback = + base::OnceCallback<void(base::Optional<std::string>)>; + + BorealisLaunchWatcher(Profile* profile, std::string vm_name); + BorealisLaunchWatcher(const BorealisLaunchWatcher&) = delete; + BorealisLaunchWatcher() = delete; + BorealisLaunchWatcher& operator=(const BorealisLaunchWatcher&) = delete; + ~BorealisLaunchWatcher() override; + + // Adds a callback to be run when the VM is launched, the callback will be run + // immediately if the VM has already been launched. If no event has been + // observed after |timeout_|, then the callback is run anyway. If successful + // the callback will be run with the name of the container that started, + // otherwise it will be run with nullopt. + void AwaitLaunch(OnLaunchCallback callback); + + void SetTimeoutForTesting(base::TimeDelta time) { timeout_ = time; } + + private: + void TimeoutCallback(); + + // CiceroneClient::Observer: + void OnContainerStarted( + const vm_tools::cicerone::ContainerStartedSignal& signal) override; + + std::string owner_id_; + std::string vm_name_; + base::TimeDelta timeout_ = base::TimeDelta::FromMilliseconds(5000); + base::Optional<vm_tools::cicerone::ContainerStartedSignal> + container_started_signal_; + base::queue<OnLaunchCallback> callback_queue_; + + base::WeakPtrFactory<BorealisLaunchWatcher> weak_factory_{this}; +}; + +} // namespace borealis + +#endif // CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_LAUNCH_WATCHER_H_
diff --git a/chrome/browser/chromeos/borealis/borealis_launch_watcher_unittest.cc b/chrome/browser/chromeos/borealis/borealis_launch_watcher_unittest.cc new file mode 100644 index 0000000..2b3dffe --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_launch_watcher_unittest.cc
@@ -0,0 +1,163 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/borealis/borealis_launch_watcher.h" + +#include <memory> + +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/test/base/testing_profile.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_cicerone_client.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace borealis { +namespace { + +class CallbackForTestingExpectation { + public: + base::OnceCallback<void(base::Optional<std::string>)> GetCallback() { + return base::BindOnce(&CallbackForTestingExpectation::Callback, + base::Unretained(this)); + } + MOCK_METHOD(void, Callback, (base::Optional<std::string>), ()); +}; + +class BorealisLaunchWatcherTest : public testing::Test { + public: + BorealisLaunchWatcherTest() = default; + BorealisLaunchWatcherTest(const BorealisLaunchWatcherTest&) = delete; + BorealisLaunchWatcherTest& operator=(const BorealisLaunchWatcherTest&) = + delete; + ~BorealisLaunchWatcherTest() override = default; + + protected: + void SetUp() override { + chromeos::DBusThreadManager::Initialize(); + fake_cicerone_client_ = static_cast<chromeos::FakeCiceroneClient*>( + chromeos::DBusThreadManager::Get()->GetCiceroneClient()); + } + + void TearDown() override { + chromeos::DBusThreadManager::Shutdown(); + profile_.reset(); + } + + // Owned by DBusThreadManager + chromeos::FakeCiceroneClient* fake_cicerone_client_ = nullptr; + + std::unique_ptr<TestingProfile> profile_; + content::BrowserTaskEnvironment task_environment_; + + private: + void CreateProfile() { + TestingProfile::Builder profile_builder; + profile_builder.SetProfileName("defaultprofile"); + profile_ = profile_builder.Build(); + } +}; + +TEST_F(BorealisLaunchWatcherTest, VmStartsCallbackRan) { + testing::StrictMock<CallbackForTestingExpectation> callback_expectation; + BorealisLaunchWatcher watcher(profile_.get(), "FooVm"); + vm_tools::cicerone::ContainerStartedSignal signal; + signal.set_owner_id( + chromeos::ProfileHelper::GetUserIdHashFromProfile(profile_.get())); + signal.set_vm_name("FooVm"); + signal.set_container_name("FooContainer"); + + EXPECT_CALL(callback_expectation, + Callback(base::Optional<std::string>("FooContainer"))); + watcher.AwaitLaunch(callback_expectation.GetCallback()); + fake_cicerone_client_->NotifyContainerStarted(std::move(signal)); + + task_environment_.RunUntilIdle(); +} + +TEST_F(BorealisLaunchWatcherTest, VmTimesOutCallbackRan) { + testing::StrictMock<CallbackForTestingExpectation> callback_expectation; + BorealisLaunchWatcher watcher(profile_.get(), "FooVm"); + watcher.SetTimeoutForTesting(base::TimeDelta::FromMilliseconds(0)); + + EXPECT_CALL(callback_expectation, + Callback(base::Optional<std::string>(base::nullopt))); + watcher.AwaitLaunch(callback_expectation.GetCallback()); + + task_environment_.RunUntilIdle(); +} + +TEST_F(BorealisLaunchWatcherTest, VmAlreadyStartedCallbackRan) { + testing::StrictMock<CallbackForTestingExpectation> callback_expectation; + BorealisLaunchWatcher watcher(profile_.get(), "FooVm"); + vm_tools::cicerone::ContainerStartedSignal signal; + signal.set_owner_id( + chromeos::ProfileHelper::GetUserIdHashFromProfile(profile_.get())); + signal.set_vm_name("FooVm"); + signal.set_container_name("FooContainer"); + + EXPECT_CALL(callback_expectation, + Callback(base::Optional<std::string>("FooContainer"))); + fake_cicerone_client_->NotifyContainerStarted(std::move(signal)); + watcher.AwaitLaunch(callback_expectation.GetCallback()); + + task_environment_.RunUntilIdle(); +} + +TEST_F(BorealisLaunchWatcherTest, VmStartsMultipleCallbacksRan) { + testing::StrictMock<CallbackForTestingExpectation> callback_expectation; + BorealisLaunchWatcher watcher(profile_.get(), "FooVm"); + vm_tools::cicerone::ContainerStartedSignal signal; + signal.set_owner_id( + chromeos::ProfileHelper::GetUserIdHashFromProfile(profile_.get())); + signal.set_vm_name("FooVm"); + signal.set_container_name("FooContainer"); + + EXPECT_CALL(callback_expectation, + Callback(base::Optional<std::string>("FooContainer"))) + .Times(2); + watcher.AwaitLaunch(callback_expectation.GetCallback()); + watcher.AwaitLaunch(callback_expectation.GetCallback()); + fake_cicerone_client_->NotifyContainerStarted(std::move(signal)); + + task_environment_.RunUntilIdle(); +} + +TEST_F(BorealisLaunchWatcherTest, VmTimesOutMultipleCallbacksRan) { + testing::StrictMock<CallbackForTestingExpectation> callback_expectation; + BorealisLaunchWatcher watcher(profile_.get(), "FooVm"); + watcher.SetTimeoutForTesting(base::TimeDelta::FromMilliseconds(0)); + + EXPECT_CALL(callback_expectation, + Callback(base::Optional<std::string>(base::nullopt))) + .Times(2); + watcher.AwaitLaunch(callback_expectation.GetCallback()); + watcher.AwaitLaunch(callback_expectation.GetCallback()); + + task_environment_.RunUntilIdle(); +} + +TEST_F(BorealisLaunchWatcherTest, OtherVmsStartBorealisTimesOutCallbackRan) { + testing::StrictMock<CallbackForTestingExpectation> callback_expectation; + BorealisLaunchWatcher watcher(profile_.get(), "FooVm"); + watcher.SetTimeoutForTesting(base::TimeDelta::FromMilliseconds(0)); + vm_tools::cicerone::ContainerStartedSignal signal1; + signal1.set_owner_id("not-the-owner"); + signal1.set_vm_name("FooVm"); + vm_tools::cicerone::ContainerStartedSignal signal2; + signal2.set_owner_id( + chromeos::ProfileHelper::GetUserIdHashFromProfile(profile_.get())); + signal2.set_vm_name("not-FooVm"); + + EXPECT_CALL(callback_expectation, + Callback(base::Optional<std::string>(base::nullopt))); + fake_cicerone_client_->NotifyContainerStarted(std::move(signal1)); + fake_cicerone_client_->NotifyContainerStarted(std::move(signal2)); + watcher.AwaitLaunch(callback_expectation.GetCallback()); + + task_environment_.RunUntilIdle(); +} + +} // namespace +} // namespace borealis
diff --git a/chrome/browser/chromeos/borealis/borealis_task.cc b/chrome/browser/chromeos/borealis/borealis_task.cc index 7aa848f3..14f5333 100644 --- a/chrome/browser/chromeos/borealis/borealis_task.cc +++ b/chrome/browser/chromeos/borealis/borealis_task.cc
@@ -3,13 +3,16 @@ // found in the LICENSE file. #include "chrome/browser/chromeos/borealis/borealis_task.h" +#include <string> #include "base/logging.h" +#include "base/strings/string_number_conversions.h" #include "chrome/browser/chromeos/borealis/borealis_context.h" #include "chrome/browser/chromeos/borealis/borealis_util.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chromeos/constants/chromeos_features.h" +#include "chromeos/dbus/concierge/concierge_service.pb.h" #include "chromeos/dbus/dbus_thread_manager.h" namespace borealis { @@ -31,12 +34,12 @@ CompletionStatusCallback callback, const chromeos::DlcserviceClient::InstallResult& install_result) { if (install_result.error != dlcservice::kErrorNone) { - LOG(ERROR) << "Mounting the DLC for Borealis failed: " - << install_result.error; - std::move(callback).Run(false); + std::move(callback).Run( + BorealisContextManager::kMountFailed, + "Mounting the DLC for Borealis failed: " + install_result.error); } else { context->set_root_path(install_result.root_path); - std::move(callback).Run(true); + std::move(callback).Run(BorealisContextManager::kSuccess, ""); } } @@ -67,22 +70,23 @@ CompletionStatusCallback callback, base::Optional<vm_tools::concierge::CreateDiskImageResponse> response) { if (!response) { - LOG(ERROR) << "Failed to create disk image for Borealis. Empty response."; context->set_disk_path(base::FilePath()); - std::move(callback).Run(false); + std::move(callback).Run( + BorealisContextManager::kDiskImageFailed, + "Failed to create disk image for Borealis: Empty response."); return; } if (response->status() != vm_tools::concierge::DISK_STATUS_EXISTS && response->status() != vm_tools::concierge::DISK_STATUS_CREATED) { - LOG(ERROR) << "Failed to create disk image for Borealis: " - << response->failure_reason(); context->set_disk_path(base::FilePath()); - std::move(callback).Run(false); + std::move(callback).Run(BorealisContextManager::kDiskImageFailed, + "Failed to create disk image for Borealis: " + + response->failure_reason()); return; } context->set_disk_path(base::FilePath(response->disk_path())); - std::move(callback).Run(true); + std::move(callback).Run(BorealisContextManager::kSuccess, ""); } StartBorealisVm::StartBorealisVm() = default; @@ -126,24 +130,29 @@ CompletionStatusCallback callback, base::Optional<vm_tools::concierge::StartVmResponse> response) { if (!response) { - LOG(ERROR) << "Failed to start Borealis VM. Empty response."; - std::move(callback).Run(false); + std::move(callback).Run(BorealisContextManager::kStartVmFailed, + "Failed to start Borealis VM: Empty response."); return; } - if (response->status() == vm_tools::concierge::VM_STATUS_RUNNING) { - std::move(callback).Run(true); + if (response->status() == vm_tools::concierge::VM_STATUS_RUNNING || + response->status() == vm_tools::concierge::VM_STATUS_STARTING) { + std::move(callback).Run(BorealisContextManager::kSuccess, ""); return; } - if (response->status() == vm_tools::concierge::VM_STATUS_FAILURE || - response->status() == vm_tools::concierge::VM_STATUS_UNKNOWN) { - LOG(ERROR) << "Failed to start Borealis VM: " << response->failure_reason(); - std::move(callback).Run(false); - return; - } - - DCHECK_EQ(response->status(), vm_tools::concierge::VM_STATUS_STARTING); - std::move(callback).Run(true); + std::move(callback).Run( + BorealisContextManager::kStartVmFailed, + "Failed to start Borealis VM: " + response->failure_reason() + " (code " + + base::NumberToString(response->status()) + ")"); } + +void AwaitBorealisStartup::Run(BorealisContext* context, + CompletionStatusCallback callback) { + // TODO(b/170696557): Refactor to use the LaunchWatcher which is not finished + // yet. In our case the name is hard-coded, so we can use that. + context->set_container_name("penguin"); + std::move(callback).Run(BorealisContextManager::kSuccess, ""); +} + } // namespace borealis
diff --git a/chrome/browser/chromeos/borealis/borealis_task.h b/chrome/browser/chromeos/borealis/borealis_task.h index 8be30e0..0287cd5 100644 --- a/chrome/browser/chromeos/borealis/borealis_task.h +++ b/chrome/browser/chromeos/borealis/borealis_task.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_TASK_H_ #include "base/memory/weak_ptr.h" +#include "chrome/browser/chromeos/borealis/borealis_context_manager.h" #include "chromeos/dbus/concierge_client.h" #include "chromeos/dbus/dlcservice/dlcservice_client.h" @@ -17,9 +18,11 @@ // Borealis Context Manager. class BorealisTask { public: - // Callback to be run when the task completes. The |bool| should reflect - // if the task succeeded (true) or failed (false). - using CompletionStatusCallback = base::OnceCallback<void(bool)>; + // Callback to be run when the task completes. The |status| should reflect + // if the task succeeded with kSuccess and an empty string. If it fails, a + // different status should be used, and an error string provided. + using CompletionStatusCallback = + base::OnceCallback<void(BorealisContextManager::Status, std::string)>; BorealisTask() = default; BorealisTask(const BorealisTask&) = delete; BorealisTask& operator=(const BorealisTask&) = delete; @@ -76,6 +79,13 @@ base::WeakPtrFactory<StartBorealisVm> weak_factory_{this}; }; +// Waits for the startup daemon to signal completion. +class AwaitBorealisStartup : public BorealisTask { + public: + void Run(BorealisContext* context, + CompletionStatusCallback callback) override; +}; + } // namespace borealis #endif // CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_TASK_H_
diff --git a/chrome/browser/chromeos/borealis/borealis_task_unittest.cc b/chrome/browser/chromeos/borealis/borealis_task_unittest.cc index 68b4c3d3..ebad5fe8 100644 --- a/chrome/browser/chromeos/borealis/borealis_task_unittest.cc +++ b/chrome/browser/chromeos/borealis/borealis_task_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include "chrome/browser/chromeos/borealis/borealis_context.h" +#include "chrome/browser/chromeos/borealis/borealis_context_manager.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dlcservice/fake_dlcservice_client.h" @@ -14,18 +15,24 @@ #include "content/public/test/browser_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" +using ::testing::_; +using ::testing::StrNe; + namespace borealis { namespace { class CallbackForTesting { public: - base::OnceCallback<void(bool)> GetCallback() { + BorealisTask::CompletionStatusCallback GetCallback() { return base::BindOnce(&CallbackForTesting::Callback, base::Unretained(this)); } - MOCK_METHOD(void, Callback, (bool), ()); + MOCK_METHOD(void, + Callback, + (BorealisContextManager::Status, std::string), + ()); }; class BorealisTasksTest : public testing::Test { @@ -33,6 +40,10 @@ BorealisTasksTest() = default; ~BorealisTasksTest() override = default; + // Disallow copy and assign. + BorealisTasksTest(const BorealisTasksTest&) = delete; + BorealisTasksTest& operator=(const BorealisTasksTest&) = delete; + protected: void SetUp() override { chromeos::DBusThreadManager::Initialize(); @@ -67,10 +78,6 @@ profile_builder.SetProfileName("defaultprofile"); profile_ = profile_builder.Build(); } - - // Disallow copy and assign. - BorealisTasksTest(const BorealisTasksTest&) = delete; - BorealisTasksTest& operator=(const BorealisTasksTest&) = delete; }; TEST_F(BorealisTasksTest, MountDlcSucceedsAndCallbackRanWithResults) { @@ -79,7 +86,7 @@ EXPECT_EQ(context_->root_path(), ""); testing::StrictMock<CallbackForTesting> callback; - EXPECT_CALL(callback, Callback(true)); + EXPECT_CALL(callback, Callback(BorealisContextManager::kSuccess, _)); MountDlc task; task.Run(context_, callback.GetCallback()); @@ -97,7 +104,7 @@ EXPECT_EQ(context_->disk_path(), base::FilePath()); testing::StrictMock<CallbackForTesting> callback; - EXPECT_CALL(callback, Callback(true)); + EXPECT_CALL(callback, Callback(BorealisContextManager::kSuccess, _)); CreateDiskImage task; task.Run(context_, callback.GetCallback()); @@ -117,7 +124,7 @@ EXPECT_EQ(context_->disk_path(), base::FilePath()); testing::StrictMock<CallbackForTesting> callback; - EXPECT_CALL(callback, Callback(true)); + EXPECT_CALL(callback, Callback(BorealisContextManager::kSuccess, _)); CreateDiskImage task; task.Run(context_, callback.GetCallback()); @@ -133,7 +140,7 @@ fake_concierge_client_->set_start_vm_response(std::move(response)); testing::StrictMock<CallbackForTesting> callback; - EXPECT_CALL(callback, Callback(true)); + EXPECT_CALL(callback, Callback(BorealisContextManager::kSuccess, _)); StartBorealisVm task; task.Run(context_, callback.GetCallback()); @@ -149,7 +156,7 @@ fake_concierge_client_->set_start_vm_response(std::move(response)); testing::StrictMock<CallbackForTesting> callback; - EXPECT_CALL(callback, Callback(true)); + EXPECT_CALL(callback, Callback(BorealisContextManager::kSuccess, _)); StartBorealisVm task; task.Run(context_, callback.GetCallback()); @@ -164,7 +171,8 @@ TEST_P(BorealisTasksTestDlc, MountDlcFailsAndCallbackRanWithResults) { fake_dlcservice_client_->set_install_error(GetParam()); testing::StrictMock<CallbackForTesting> callback; - EXPECT_CALL(callback, Callback(false)); + EXPECT_CALL(callback, + Callback(BorealisContextManager::kMountFailed, StrNe(""))); MountDlc task; task.Run(context_, callback.GetCallback()); @@ -192,7 +200,8 @@ EXPECT_EQ(context_->disk_path(), base::FilePath()); testing::StrictMock<CallbackForTesting> callback; - EXPECT_CALL(callback, Callback(false)); + EXPECT_CALL(callback, + Callback(BorealisContextManager::kDiskImageFailed, StrNe(""))); CreateDiskImage task; task.Run(context_, callback.GetCallback()); @@ -223,7 +232,8 @@ fake_concierge_client_->set_start_vm_response(std::move(response)); testing::StrictMock<CallbackForTesting> callback; - EXPECT_CALL(callback, Callback(false)); + EXPECT_CALL(callback, + Callback(BorealisContextManager::kStartVmFailed, StrNe(""))); StartBorealisVm task; task.Run(context_, callback.GetCallback());
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.h b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.h index edf9f82d..bf19a78 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.h +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.h
@@ -277,10 +277,6 @@ ResponseAction Run() override; void RestartCallback(crostini::CrostiniResult); - - private: - std::string source_path_; - std::string mount_label_; }; // Implements the chrome.fileManagerPrivate.importCrostiniImage method.
diff --git a/chrome/browser/chromeos/file_manager/devtools_listener.cc b/chrome/browser/chromeos/file_manager/devtools_listener.cc index 9f06b925..7c06f46 100644 --- a/chrome/browser/chromeos/file_manager/devtools_listener.cc +++ b/chrome/browser/chromeos/file_manager/devtools_listener.cc
@@ -247,6 +247,9 @@ if (!navigated_) return; + if (VLOG_IS_ON(2)) + VLOG(2) << SpanToStringPiece(message); + std::unique_ptr<base::DictionaryValue> value = base::DictionaryValue::From( base::JSONReader::ReadDeprecated(SpanToStringPiece(message))); CHECK(value);
diff --git a/chrome/browser/chromeos/file_manager/devtools_listener_browsertest.cc b/chrome/browser/chromeos/file_manager/devtools_listener_browsertest.cc index 464199f..816355d18 100644 --- a/chrome/browser/chromeos/file_manager/devtools_listener_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/devtools_listener_browsertest.cc
@@ -33,9 +33,6 @@ void SetUpOnMainThread() override { process_id_ = base::GetUniqueIdForProcess().GetUnsafeValue(); content::DevToolsAgentHost::AddObserver(this); - - base::ScopedAllowBlockingForTesting allow_blocking; - CHECK(tmp_dir_.CreateUniqueTempDir()); } bool ShouldForceDevToolsAgentHostCreation() override { return true; } @@ -62,9 +59,10 @@ LOG(FATAL) << "Host crashed: " << DevToolsListener::HostString(host); } - void CollectCodeCoverage() { + void CollectCodeCoverage(const std::string test_name) { base::ScopedAllowBlockingForTesting allow_blocking; + CHECK(tmp_dir_.CreateUniqueTempDir()); base::FilePath coverage_store = tmp_dir_.GetPath().AppendASCII("devtools_listener_browser_test"); CHECK(base::CreateDirectory(coverage_store)); @@ -72,7 +70,7 @@ for (auto& agent : devtools_agent_) { auto* host = agent.first; EXPECT_TRUE(agent.second->HasCoverage(host)); - agent.second->GetCoverage(host, coverage_store, "fake_test_name"); + agent.second->GetCoverage(host, coverage_store, test_name); agent.second->Detach(host); } @@ -81,10 +79,12 @@ private: base::ScopedTempDir tmp_dir_; + + using DevToolsAgentMap = // agent hosts: have a unique devtools listener + std::map<content::DevToolsAgentHost*, std::unique_ptr<DevToolsListener>>; + + DevToolsAgentMap devtools_agent_; uint32_t process_id_ = 0; - std::map<content::DevToolsAgentHost*, std::unique_ptr<DevToolsListener>> - devtools_agent_; - base::FilePath coverage_store_; DISALLOW_COPY_AND_ASSIGN(DevToolsListenerBrowserTest); }; @@ -106,7 +106,7 @@ content::DevToolsAgentHost::RemoveObserver(this); content::RunAllTasksUntilIdle(); - CollectCodeCoverage(); + CollectCodeCoverage("CanCollectCodeCoverage"); content::DevToolsAgentHost::DetachAllClients(); content::RunAllTasksUntilIdle();
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index c275354..e4d3bb0e 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -1051,6 +1051,7 @@ "//chromeos/settings", "//chromeos/system", "//chromeos/tpm", + "//chromeos/ui/base", "//components/arc", "//components/constrained_window", "//components/drive",
diff --git a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc index 0fba941..592b1ae 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc
@@ -33,9 +33,9 @@ #include "ui/display/test/test_screen.h" #if defined(OS_CHROMEOS) -#include "ash/public/cpp/window_pin_type.h" -#include "ash/public/cpp/window_properties.h" #include "chrome/browser/chromeos/policy/dlp/mock_dlp_content_manager.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" #endif namespace extensions { @@ -991,7 +991,7 @@ // In locked fullscreen mode we should not be able to create any tabs. browser_window()->GetNativeWindow()->SetProperty( - ash::kWindowPinTypeKey, ash::WindowPinType::kTrustedPinned); + chromeos::kWindowPinTypeKey, chromeos::WindowPinType::kTrustedPinned); EXPECT_EQ(tabs_constants::kLockedFullscreenModeNewTabError, extension_function_test_utils::RunFunctionAndReturnError(
diff --git a/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc b/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc index 4ed2273..a4ddb8c9 100644 --- a/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc +++ b/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc
@@ -5,8 +5,6 @@ #include "chrome/browser/extensions/api/tabs/tabs_util.h" #include "ash/public/cpp/assistant/assistant_state.h" -#include "ash/public/cpp/window_pin_type.h" -#include "ash/public/cpp/window_properties.h" #include "base/metrics/histogram_macros.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/arc/arc_util.h" @@ -17,6 +15,8 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_command_controller.h" #include "chrome/browser/ui/browser_window.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/web_contents.h" #include "ui/aura/window.h" @@ -32,9 +32,9 @@ aura::Window* window = browser->window()->GetNativeWindow(); // TRUSTED_PINNED is used here because that one locks the window fullscreen // without allowing the user to exit (as opposed to regular PINNED). - window->SetProperty( - ash::kWindowPinTypeKey, - locked ? ash::WindowPinType::kTrustedPinned : ash::WindowPinType::kNone); + window->SetProperty(chromeos::kWindowPinTypeKey, + locked ? chromeos::WindowPinType::kTrustedPinned + : chromeos::WindowPinType::kNone); // Update the set of available browser commands. browser->command_controller()->LockedFullscreenStateChanged();
diff --git a/chrome/browser/extensions/window_open_apitest.cc b/chrome/browser/extensions/window_open_apitest.cc index f05793ef..b5c2205b 100644 --- a/chrome/browser/extensions/window_open_apitest.cc +++ b/chrome/browser/extensions/window_open_apitest.cc
@@ -40,12 +40,12 @@ #include "ui/base/base_window.h" #if defined(OS_CHROMEOS) -#include "ash/public/cpp/window_pin_type.h" -#include "ash/public/cpp/window_properties.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/extensions/window_controller.h" #include "chrome/browser/extensions/window_controller_list.h" #include "chrome/browser/ui/browser_command_controller.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" #include "ui/aura/window.h" #endif @@ -377,14 +377,14 @@ return controller->window()->GetNativeWindow(); } -ash::WindowPinType GetCurrentWindowPinType() { - ash::WindowPinType type = - GetCurrentWindow()->GetProperty(ash::kWindowPinTypeKey); +chromeos::WindowPinType GetCurrentWindowPinType() { + chromeos::WindowPinType type = + GetCurrentWindow()->GetProperty(chromeos::kWindowPinTypeKey); return type; } -void SetCurrentWindowPinType(ash::WindowPinType type) { - GetCurrentWindow()->SetProperty(ash::kWindowPinTypeKey, type); +void SetCurrentWindowPinType(chromeos::WindowPinType type) { + GetCurrentWindow()->SetProperty(chromeos::kWindowPinTypeKey, type); } } // namespace @@ -396,7 +396,7 @@ // Make sure the newly created window is "trusted pinned" (which means that // it's in locked fullscreen mode). - EXPECT_EQ(ash::WindowPinType::kTrustedPinned, GetCurrentWindowPinType()); + EXPECT_EQ(chromeos::WindowPinType::kTrustedPinned, GetCurrentWindowPinType()); } IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, UpdateWindowToLockedFullscreen) { @@ -405,13 +405,13 @@ << message_; // Make sure the current window is put into the "trusted pinned" state. - EXPECT_EQ(ash::WindowPinType::kTrustedPinned, GetCurrentWindowPinType()); + EXPECT_EQ(chromeos::WindowPinType::kTrustedPinned, GetCurrentWindowPinType()); } IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, RemoveLockedFullscreenFromWindow) { // After locking the window, do a LockedFullscreenStateChanged so the // command_controller state catches up as well. - SetCurrentWindowPinType(ash::WindowPinType::kTrustedPinned); + SetCurrentWindowPinType(chromeos::WindowPinType::kTrustedPinned); browser()->command_controller()->LockedFullscreenStateChanged(); ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission", @@ -419,7 +419,7 @@ << message_; // Make sure the current window is removed from locked-fullscreen state. - EXPECT_EQ(ash::WindowPinType::kNone, GetCurrentWindowPinType()); + EXPECT_EQ(chromeos::WindowPinType::kNone, GetCurrentWindowPinType()); } // Make sure that commands disabling code works in locked fullscreen mode. @@ -465,12 +465,12 @@ // chrome.windows.update call fails since this extension doesn't have the // correct permission and hence the current window has NONE as WindowPinType. - EXPECT_EQ(ash::WindowPinType::kNone, GetCurrentWindowPinType()); + EXPECT_EQ(chromeos::WindowPinType::kNone, GetCurrentWindowPinType()); } IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, RemoveLockedFullscreenFromWindowWithoutPermission) { - SetCurrentWindowPinType(ash::WindowPinType::kTrustedPinned); + SetCurrentWindowPinType(chromeos::WindowPinType::kTrustedPinned); browser()->command_controller()->LockedFullscreenStateChanged(); ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission", @@ -478,7 +478,7 @@ << message_; // The current window is still locked-fullscreen. - EXPECT_EQ(ash::WindowPinType::kTrustedPinned, GetCurrentWindowPinType()); + EXPECT_EQ(chromeos::WindowPinType::kTrustedPinned, GetCurrentWindowPinType()); } #endif // defined(OS_CHROMEOS)
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 99dbdc7..398b865 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -237,6 +237,11 @@ "expiry_milestone": 78 }, { + "name": "audio-player-js-modules", + "owners": [ "lucmult", "jboulic", "simmonsjosh" ], + "expiry_milestone": 91 + }, + { "name": "audio-worklet-realtime-thread", "owners": [ "//third_party/blink/renderer/modules/webaudio/OWNERS" ], "expiry_milestone": 90 @@ -2149,11 +2154,6 @@ "expiry_milestone": 87 }, { - "name": "enable-system-webapps", - "owners": [ "calamity" ], - "expiry_milestone": 78 - }, - { "name": "enable-tab-engagement-reporting", "owners": [ "memex-team@google.com" ], "expiry_milestone": 90 @@ -2516,6 +2516,11 @@ "expiry_milestone": 90 }, { + "name": "files-js-modules", + "owners": [ "lucmult", "jboulic", "simmonsjosh" ], + "expiry_milestone": 91 + }, + { "name": "files-ng", "owners": [ "adanilo", "noel" ], "expiry_milestone": 88 @@ -4683,6 +4688,11 @@ "expiry_milestone": 88 }, { + "name": "video-player-js-modules", + "owners": [ "lucmult", "jboulic", "simmonsjosh" ], + "expiry_milestone": 91 + }, + { "name": "video-tutorials", "owners": [ "shaktisahu", "hesen" ], "expiry_milestone": 90
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 8d44076a..dfebabd 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -4101,6 +4101,18 @@ "Enables the Files App to display Camera folder with i18n name and make it " "nonmodifiable"; +const char kFilesJsModulesName[] = "Enable JS Modules for Files app"; +const char kFilesJsModulesDescription[] = + "Enable running Files app using JS Modules."; + +const char kAudioPlayerJsModulesName[] = "Enable JS Modules for Audio Player"; +const char kAudioPlayerJsModulesDescription[] = + "Enable running Audio Player app using JS Modules."; + +const char kVideoPlayerJsModulesName[] = "Enable JS Modules for Video Player"; +const char kVideoPlayerJsModulesDescription[] = + "Enable running Video Player app using JS Modules."; + const char kFilesNGName[] = "Enable Files App. NG."; const char kFilesNGDescription[] = "Enable the next generation UI style of the file manager.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 90fe6432..0651a4dd 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2340,6 +2340,15 @@ extern const char kTrimOnMemoryPressureName[]; extern const char kTrimOnMemoryPressureDescription[]; +extern const char kFilesJsModulesName[]; +extern const char kFilesJsModulesDescription[]; + +extern const char kAudioPlayerJsModulesName[]; +extern const char kAudioPlayerJsModulesDescription[]; + +extern const char kVideoPlayerJsModulesName[]; +extern const char kVideoPlayerJsModulesDescription[]; + extern const char kEnableSuggestedFilesName[]; extern const char kEnableSuggestedFilesDescription[];
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc index 4d5e7c0..5bd4a7e8 100644 --- a/chrome/browser/metrics/ukm_browsertest.cc +++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -159,19 +159,6 @@ } #endif // !defined(OS_ANDROID) -#if !defined(OS_ANDROID) -Profile* CreateGuestProfile() { - ProfileManager* profile_manager = g_browser_process->profile_manager(); - base::FilePath new_path = profile_manager->GetGuestProfilePath(); - base::RunLoop run_loop; - profile_manager->CreateProfileAsync( - new_path, base::Bind(&UnblockOnProfileCreation, &run_loop), - base::string16(), std::string()); - run_loop.Run(); - return profile_manager->GetProfileByPath(new_path); -} -#endif // !defined(OS_ANDROID) - // A helper object for overriding metrics enabled state. class MetricsConsentOverride { public: @@ -500,10 +487,8 @@ EXPECT_TRUE(ukm_test_helper.IsRecordingEnabled()); uint64_t original_client_id = ukm_test_helper.GetClientId(); - // Create browser for guest profile. Only "off the record" browsers may be - // opened in this mode. - Profile* guest_profile = CreateGuestProfile(); - Browser* guest_browser = CreateIncognitoBrowser(guest_profile); + // Create browser for guest profile. + Browser* guest_browser = InProcessBrowserTest::CreateGuestBrowser(); EXPECT_FALSE(ukm_test_helper.IsRecordingEnabled()); CloseBrowserSynchronously(guest_browser);
diff --git a/chrome/browser/platform_util_chromeos.cc b/chrome/browser/platform_util_chromeos.cc index 61b0366b..17a1f84 100644 --- a/chrome/browser/platform_util_chromeos.cc +++ b/chrome/browser/platform_util_chromeos.cc
@@ -4,8 +4,6 @@ #include "chrome/browser/platform_util.h" -#include "ash/public/cpp/window_pin_type.h" -#include "ash/public/cpp/window_properties.h" #include "base/bind.h" #include "base/files/file_path.h" #include "chrome/browser/chromeos/file_manager/open_util.h" @@ -16,6 +14,8 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/simple_message_box.h" #include "chromeos/strings/grit/chromeos_strings.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" #include "content/public/browser/browser_thread.h" #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" @@ -113,8 +113,8 @@ // |window| can be nullptr inside of unit tests. if (!window) return false; - return window->GetProperty(ash::kWindowPinTypeKey) == - ash::WindowPinType::kTrustedPinned; + return window->GetProperty(chromeos::kWindowPinTypeKey) == + chromeos::WindowPinType::kTrustedPinned; } } // namespace platform_util
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index 5a42593..7e0a048 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -102,8 +102,8 @@ #endif #if defined(OS_CHROMEOS) -#include "ash/public/cpp/window_pin_type.h" -#include "ash/public/cpp/window_properties.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" #include "ui/aura/window.h" #endif @@ -441,7 +441,7 @@ // Set locked fullscreen state. browser()->window()->GetNativeWindow()->SetProperty( - ash::kWindowPinTypeKey, ash::WindowPinType::kTrustedPinned); + chromeos::kWindowPinTypeKey, chromeos::WindowPinType::kTrustedPinned); // All entries are disabled in locked fullscreen (testing only a subset here). for (auto entry : entries_to_test)
diff --git a/chrome/browser/resources/omnibox/BUILD.gn b/chrome/browser/resources/omnibox/BUILD.gn index 1e3b932..8369776 100644 --- a/chrome/browser/resources/omnibox/BUILD.gn +++ b/chrome/browser/resources/omnibox/BUILD.gn
@@ -2,11 +2,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//third_party/closure_compiler/closure_args.gni") import("//third_party/closure_compiler/compile_js.gni") import("//tools/grit/grit_rule.gni") js_type_check("closure_compile") { uses_js_modules = true + closure_flags = mojom_js_args deps = [ ":omnibox", ":omnibox_element", @@ -20,7 +22,7 @@ deps = [ ":omnibox_input", ":omnibox_output", - "//chrome/browser/ui/webui/omnibox:mojo_bindings_js_library_for_compile", + "//chrome/browser/ui/webui/omnibox:mojo_bindings_webui_js", "//ui/webui/resources/js:cr.m", "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js:util.m", @@ -39,14 +41,14 @@ deps = [ ":omnibox_element", ":omnibox_input", - "//chrome/browser/ui/webui/omnibox:mojo_bindings_js_library_for_compile", + "//chrome/browser/ui/webui/omnibox:mojo_bindings_webui_js", ] externs_list = [ "$externs_path/pending.js" ] } js_library("omnibox_popup") { deps = [ - "//chrome/browser/ui/webui/omnibox:mojo_bindings_js_library_for_compile", + "//chrome/browser/ui/webui/omnibox:mojo_bindings_webui_js", "//ui/webui/resources/cr_components/omnibox:cr_autocomplete_match_list", ] } @@ -63,5 +65,5 @@ "-E", "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir), ] - deps = [ "//chrome/browser/ui/webui/omnibox:mojo_bindings_js" ] + deps = [ "//chrome/browser/ui/webui/omnibox:mojo_bindings_webui_js" ] }
diff --git a/chrome/browser/resources/omnibox/omnibox.js b/chrome/browser/resources/omnibox/omnibox.js index 4184371..c6d1ed2 100644 --- a/chrome/browser/resources/omnibox/omnibox.js +++ b/chrome/browser/resources/omnibox/omnibox.js
@@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; -import './chrome/browser/ui/webui/omnibox/omnibox.mojom-lite.js'; import './strings.m.js'; +import {OmniboxPageCallbackRouter, OmniboxPageHandler, OmniboxPageHandlerRemote, OmniboxResponse} from '/chrome/browser/ui/webui/omnibox/omnibox.mojom-webui.js'; import {sendWithPromise} from 'chrome://resources/js/cr.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {$} from 'chrome://resources/js/util.m.js'; @@ -31,7 +30,7 @@ /** * @typedef {{ * inputText: string, - * callback: function(!mojom.OmniboxResponse):Promise, + * callback: function(!OmniboxResponse):Promise, * display: boolean, * }} */ @@ -49,7 +48,7 @@ * @typedef {{ * queryInputs: QueryInputs, * displayInputs: DisplayInputs, - * responsesHistory: !Array<!Array<!mojom.OmniboxResponse>>, + * responsesHistory: !Array<!Array<!OmniboxResponse>>, * }} */ let OmniboxExport; @@ -66,8 +65,8 @@ class BrowserProxy { /** @param {!OmniboxOutput} omniboxOutput */ constructor(omniboxOutput) { - /** @private {!mojom.OmniboxPageCallbackRouter} */ - this.callbackRouter_ = new mojom.OmniboxPageCallbackRouter; + /** @private {!OmniboxPageCallbackRouter} */ + this.callbackRouter_ = new OmniboxPageCallbackRouter; this.callbackRouter_.handleNewAutocompleteResponse.addListener( this.handleNewAutocompleteResponse.bind(this)); @@ -76,8 +75,8 @@ this.callbackRouter_.handleAnswerImageData.addListener( omniboxOutput.updateAnswerImage.bind(omniboxOutput)); - /** @private {!mojom.OmniboxPageHandlerRemote} */ - this.handler_ = mojom.OmniboxPageHandler.getRemote(); + /** @private {!OmniboxPageHandlerRemote} */ + this.handler_ = OmniboxPageHandler.getRemote(); this.handler_.setClientPage( this.callbackRouter_.$.bindNewPipeAndPassRemote()); @@ -86,7 +85,7 @@ } /** - * @param {!mojom.OmniboxResponse} response + * @param {!OmniboxResponse} response * @param {boolean} isPageController */ handleNewAutocompleteResponse(response, isPageController) {
diff --git a/chrome/browser/resources/omnibox/omnibox_output.js b/chrome/browser/resources/omnibox/omnibox_output.js index 8c1d0ea..800eb2b 100644 --- a/chrome/browser/resources/omnibox/omnibox_output.js +++ b/chrome/browser/resources/omnibox/omnibox_output.js
@@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; -import './chrome/browser/ui/webui/omnibox/omnibox.mojom-lite.js'; +import {ACMatchClassification, AutocompleteMatch, OmniboxResponse} from '/chrome/browser/ui/webui/omnibox/omnibox.mojom-webui.js'; import {OmniboxElement} from './omnibox_element.js'; -import {OmniboxInput, DisplayInputs} from './omnibox_input.js'; +import {DisplayInputs, OmniboxInput} from './omnibox_input.js'; /** * @typedef {{ @@ -33,7 +32,7 @@ /** @private {number} */ this.selectedResponseIndex_ = 0; - /** @type {!Array<!Array<!mojom.OmniboxResponse>>} */ + /** @type {!Array<!Array<!OmniboxResponse>>} */ this.responsesHistory = []; /** @private {!Array<!OutputResultsGroup>} */ this.resultsGroups_ = []; @@ -55,7 +54,7 @@ this.updateFilterHighlights_(); } - /** @param {!Array<!Array<!mojom.OmniboxResponse>>} responsesHistory */ + /** @param {!Array<!Array<!OmniboxResponse>>} responsesHistory */ setResponsesHistory(responsesHistory) { this.responsesHistory = responsesHistory; this.dispatchEvent(new CustomEvent( @@ -79,7 +78,7 @@ 'responses-count-changed', {detail: this.responsesHistory.length})); } - /** @param {!mojom.OmniboxResponse} response */ + /** @param {!OmniboxResponse} response */ addAutocompleteResponse(response) { const lastIndex = this.responsesHistory.length - 1; this.responsesHistory[lastIndex].push(response); @@ -99,7 +98,7 @@ /** * Creates and adds a result group to the UI. - * @private @param {!mojom.OmniboxResponse} response + * @private @param {!OmniboxResponse} response */ createResultsGroup_(response) { const resultsGroup = OutputResultsGroup.create(response); @@ -187,7 +186,7 @@ */ class OutputResultsGroup extends OmniboxElement { /** - * @param {!mojom.OmniboxResponse} resultsGroup + * @param {!OmniboxResponse} resultsGroup * @return {!OutputResultsGroup} */ static create(resultsGroup) { @@ -200,7 +199,7 @@ super('output-results-group-template'); } - /** @param {!mojom.OmniboxResponse} resultsGroup */ + /** @param {!OmniboxResponse} resultsGroup */ setResultsGroup(resultsGroup) { /** @private {ResultsDetails} */ this.details_ = { @@ -357,7 +356,7 @@ */ class OutputResultsTable extends HTMLTableSectionElement { /** - * @param {!Array<!mojom.AutocompleteMatch>} results + * @param {!Array<!AutocompleteMatch>} results * @return {!OutputResultsTable} */ static create(results) { @@ -373,7 +372,7 @@ this.autocompleteMatches = []; } - /** @param {!Array<!mojom.AutocompleteMatch>} results */ + /** @param {!Array<!AutocompleteMatch>} results */ set results(results) { this.autocompleteMatches.forEach(match => match.remove()); this.autocompleteMatches = results.map(OutputMatch.create); @@ -404,7 +403,7 @@ } /** - * @param {!mojom.AutocompleteMatch} match + * @param {!AutocompleteMatch} match * @return {!OutputMatch} */ static create(match) { @@ -414,7 +413,7 @@ return outputMatch; } - /** @param {!mojom.AutocompleteMatch} match */ + /** @param {!AutocompleteMatch} match */ set match(match) { /** @type {!Object<string, !OutputProperty>} */ this.properties = {}; @@ -703,11 +702,11 @@ this.values_; OutputAnswerProperty.renderClassifiedText_( this.contents_, /** @type {string} */ (contents), - /** @type {!Array<!mojom.ACMatchClassification>} */ + /** @type {!Array<!ACMatchClassification>} */ (contentsClassification)); OutputAnswerProperty.renderClassifiedText_( this.description_, /** @type {string} */ (description), - /** @type {!Array<!mojom.ACMatchClassification>} */ + /** @type {!Array<!ACMatchClassification>} */ (descriptionClassification)); this.answer_.textContent = answer; this.imageUrl_.textContent = image; @@ -723,7 +722,7 @@ * @private * @param {!Element} container * @param {string} string - * @param {!Array<!mojom.ACMatchClassification>} classes + * @param {!Array<!ACMatchClassification>} classes */ static renderClassifiedText_(container, string, classes) { clearChildren(container); @@ -736,7 +735,7 @@ /** * @param {string} string - * @param {!Array<!mojom.ACMatchClassification>} classes + * @param {!Array<!ACMatchClassification>} classes * @return {!Array<{string: string, style: number}>} */ static classify(string, classes) {
diff --git a/chrome/browser/resources/omnibox/omnibox_popup.js b/chrome/browser/resources/omnibox/omnibox_popup.js index a6b55b23..2ce6368b 100644 --- a/chrome/browser/resources/omnibox/omnibox_popup.js +++ b/chrome/browser/resources/omnibox/omnibox_popup.js
@@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; -import './chrome/browser/ui/webui/omnibox/omnibox.mojom-lite.js'; - +import {OmniboxPageCallbackRouter, OmniboxPageHandler, OmniboxPageHandlerRemote} from '/chrome/browser/ui/webui/omnibox/omnibox.mojom-webui.js'; import {AutocompleteMatchListElement} from 'chrome://resources/cr_components/omnibox/cr_autocomplete_match_list.js'; /** @@ -14,8 +12,8 @@ */ document.addEventListener('DOMContentLoaded', () => { - /** @private {!mojom.OmniboxPageCallbackRouter} */ - const callbackRouter = new mojom.OmniboxPageCallbackRouter; + /** @private {!OmniboxPageCallbackRouter} */ + const callbackRouter = new OmniboxPageCallbackRouter; // Basically a Hello World proof of concept that writes the Autocomplete // responses to the whole document. @@ -31,7 +29,7 @@ } }); - /** @private {!mojom.OmniboxPageHandlerRemote} */ - const handler = mojom.OmniboxPageHandler.getRemote(); + /** @private {!OmniboxPageHandlerRemote} */ + const handler = OmniboxPageHandler.getRemote(); handler.setClientPage(callbackRouter.$.bindNewPipeAndPassRemote()); });
diff --git a/chrome/browser/resources/omnibox/resources.grd b/chrome/browser/resources/omnibox/resources.grd index 273065f1..9821c83 100644 --- a/chrome/browser/resources/omnibox/resources.grd +++ b/chrome/browser/resources/omnibox/resources.grd
@@ -46,7 +46,7 @@ file="omnibox.js" type="BINDATA" /> <include name="IDR_OMNIBOX_MOJO_JS" - file="${root_gen_dir}\chrome\browser\ui\webui\omnibox\omnibox.mojom-lite.js" + file="${root_gen_dir}\mojom-webui\chrome\browser\ui\webui\omnibox\omnibox.mojom-webui.js" use_base_dir="false" type="BINDATA" /> </includes>
diff --git a/chrome/browser/resources/quota_internals/event_handler.js b/chrome/browser/resources/quota_internals/event_handler.js index d8c8b78..cde55cb1 100644 --- a/chrome/browser/resources/quota_internals/event_handler.js +++ b/chrome/browser/resources/quota_internals/event_handler.js
@@ -245,20 +245,14 @@ return originObject; } -/** - * Event Handler for |cr.quota.onAvailableSpaceUpdated|. - * |event.detail| contains |availableSpace|. - * |availableSpace| represents total available disk space. - * @param {!CustomEvent<number>} event AvailableSpaceUpdated event. - */ -function handleAvailableSpace(event) { - availableSpace = event.detail; +/** @param {number} space Total available disk space. */ +function handleAvailableSpace(space) { + availableSpace = space; $('diskspace-entry').textContent = numBytesToText_(availableSpace); } /** - * Event Handler for |cr.quota.onGlobalInfoUpdated|. - * |event.detail| contains a record which has: + * |data| contains a record which has: * |type|: * Storage type, that is either 'temporary' or 'persistent'. * |usage|: @@ -270,15 +264,14 @@ * * |usage|, |unlimitedUsage| and |quota| can be missing, * and some additional fields can be included. - * @param {!CustomEvent<!{ + * @param {!{ * type: string, * usage: ?number, * unlimitedUsage: ?number, * quota: ?string - * }>} event GlobalInfoUpdated event. + * }} data */ -function handleGlobalInfo(event) { - const data = event.detail; +function handleGlobalInfo(data) { const storageObject = getStorageObject(data.type); copyAttributes_(data, storageObject.detail.payload); storageObject.reveal(); @@ -288,8 +281,7 @@ } /** - * Event Handler for |cr.quota.onPerHostInfoUpdated|. - * |event.detail| contains records which have: + * |dataArray| contains records which have: * |host|: * Hostname of the entry. (e.g. 'example.com') * |type|: @@ -301,16 +293,14 @@ * * |usage| and |quota| can be missing, * and some additional fields can be included. - * @param {!CustomEvent<!Array<{ + * @param {!Array<{ * host: string, * type: string, * usage: ?number, * quota: ?number - * }>>} event PerHostInfoUpdated event. + * }>} dataArray */ -function handlePerHostInfo(event) { - const dataArray = event.detail; - +function handlePerHostInfo(dataArray) { for (let i = 0; i < dataArray.length; ++i) { const data = dataArray[i]; const hostObject = getHostObject(data.type, data.host); @@ -323,8 +313,7 @@ } /** - * Event Handler for |cr.quota.onPerOriginInfoUpdated|. - * |event.detail| contains records which have: + * |dataArray| contains records which have: * |origin|: * Origin URL of the entry. * |type|: @@ -344,7 +333,7 @@ * * |inUse|, |usedCount|, |lastAccessTime| and |lastModifiedTime| can be missing, * and some additional fields can be included. - * @param {!CustomEvent<!Array<!{ + * @param {!Array<!{ * origin: string, * type: string, * host: string, @@ -352,11 +341,9 @@ * usedCount: ?number, * lastAccessTime: ?number, * lastModifiedTime: ?number - * }>>} event PerOriginInfoUpdated event. + * }>} dataArray */ -function handlePerOriginInfo(event) { - const dataArray = event.detail; - +function handlePerOriginInfo(dataArray) { for (let i = 0; i < dataArray.length; ++i) { const data = dataArray[i]; const originObject = getOriginObject(data.type, data.host, data.origin); @@ -369,12 +356,10 @@ } /** - * Event Handler for |cr.quota.onStatisticsUpdated|. - * |event.detail| contains misc statistics data as dictionary. - * @param {!CustomEvent<!Object>} event StatisticsUpdated event. + * |data| contains misc statistics data as dictionary. + * @param {!Object} data */ -function handleStatistics(event) { - const data = event.detail; +function handleStatistics(data) { for (const key in data) { let entry = statistics[key]; if (!entry) { @@ -391,13 +376,10 @@ } /** - * Event Handler for |cr.quota.onStoragePressureFlagUpdated|. - * |event.detail| contains a boolean representing whether or not to show - * the storage pressure UI. - * @param {!CustomEvent<!Object>} event StoragePressureFlagUpdated event. + * @param {!{isStoragePressureEnabled: boolean}} data Contains a boolean + * representing whether or not to show the storage pressure UI. */ -function handleStoragePressureFlagInfo(event) { - const data = event.detail; +function handleStoragePressureFlagInfo(data) { $('storage-pressure-loading').hidden = true; if (data.isStoragePressureEnabled) { $('storage-pressure-outer').hidden = false; @@ -499,15 +481,14 @@ function onLoad() { cr.ui.decorate('tabbox', cr.ui.TabBox); - cr.quota.onAvailableSpaceUpdated.addEventListener( - 'update', handleAvailableSpace); - cr.quota.onGlobalInfoUpdated.addEventListener('update', handleGlobalInfo); - cr.quota.onPerHostInfoUpdated.addEventListener('update', handlePerHostInfo); - cr.quota.onPerOriginInfoUpdated.addEventListener( - 'update', handlePerOriginInfo); - cr.quota.onStatisticsUpdated.addEventListener('update', handleStatistics); - cr.quota.onStoragePressureFlagUpdated.addEventListener( - 'update', handleStoragePressureFlagInfo); + cr.addWebUIListener('AvailableSpaceUpdated', handleAvailableSpace); + cr.addWebUIListener('GlobalInfoUpdated', handleGlobalInfo); + cr.addWebUIListener('PerHostInfoUpdated', handlePerHostInfo); + cr.addWebUIListener('PerOriginInfoUpdated', handlePerOriginInfo); + cr.addWebUIListener('StatisticsUpdated', handleStatistics); + cr.addWebUIListener( + 'StoragePressureFlagUpdated', handleStoragePressureFlagInfo); + cr.quota.requestInfo(); $('refresh-button').addEventListener('click', cr.quota.requestInfo, false);
diff --git a/chrome/browser/resources/quota_internals/message_dispatcher.js b/chrome/browser/resources/quota_internals/message_dispatcher.js index 25fa7ec..3c69202 100644 --- a/chrome/browser/resources/quota_internals/message_dispatcher.js +++ b/chrome/browser/resources/quota_internals/message_dispatcher.js
@@ -3,14 +3,10 @@ // found in the LICENSE file. // require cr.js -// require cr/event_target.js -// require cr/util.js /** * Bridge between the browser and the page. * In this file: - * * define EventTargets to receive message from the browser, - * * dispatch browser messages to EventTarget, * * define interface to request data to the browser. */ @@ -31,66 +27,10 @@ chrome.send('triggerStoragePressure', [origin]); } - /** - * Callback entry point from Browser. - * Messages are Dispatched as Event to: - * * onAvailableSpaceUpdated, - * * onGlobalInfoUpdated, - * * onPerHostInfoUpdated, - * * onPerOriginInfoUpdated, - * * onStatisticsUpdated, - * * onStoragePressureFlagUpdated. - * @param {string} message Message label. Possible Values are: - * * 'AvailableSpaceUpdated', - * * 'GlobalInfoUpdated', - * * 'PerHostInfoUpdated', - * * 'PerOriginInfoUpdated', - * * 'StatisticsUpdated', - * * 'StoragePressureFlagUpdated'. - * @param {Object} detail Message specific additional data. - */ - function messageHandler(message, detail) { - let target = null; - switch (message) { - case 'AvailableSpaceUpdated': - target = cr.quota.onAvailableSpaceUpdated; - break; - case 'GlobalInfoUpdated': - target = cr.quota.onGlobalInfoUpdated; - break; - case 'PerHostInfoUpdated': - target = cr.quota.onPerHostInfoUpdated; - break; - case 'PerOriginInfoUpdated': - target = cr.quota.onPerOriginInfoUpdated; - break; - case 'StatisticsUpdated': - target = cr.quota.onStatisticsUpdated; - break; - case 'StoragePressureFlagUpdated': - target = cr.quota.onStoragePressureFlagUpdated; - break; - default: - console.error('Unknown Message'); - break; - } - if (target) { - const event = document.createEvent('CustomEvent'); - event.initCustomEvent('update', false, false, detail); - target.dispatchEvent(event); - } - } + return { - onAvailableSpaceUpdated: new cr.EventTarget(), - onGlobalInfoUpdated: new cr.EventTarget(), - onPerHostInfoUpdated: new cr.EventTarget(), - onPerOriginInfoUpdated: new cr.EventTarget(), - onStatisticsUpdated: new cr.EventTarget(), - onStoragePressureFlagUpdated: new cr.EventTarget(), - requestInfo: requestInfo, triggerStoragePressure: triggerStoragePressure, - messageHandler: messageHandler }; });
diff --git a/chrome/browser/sync/chrome_sync_client.h b/chrome/browser/sync/chrome_sync_client.h index 44e4be4..141426cd 100644 --- a/chrome/browser/sync/chrome_sync_client.h +++ b/chrome/browser/sync/chrome_sync_client.h
@@ -89,8 +89,6 @@ Profile* const profile_; // The sync api component factory in use by this client. - // TODO(crbug.com/915154): Revert to SyncApiComponentFactory once common - // controller creation is moved elsewhere. std::unique_ptr<browser_sync::ProfileSyncComponentsFactoryImpl> component_factory_;
diff --git a/chrome/browser/sync/sync_startup_tracker_unittest.cc b/chrome/browser/sync/sync_startup_tracker_unittest.cc index 836737e..a3af1d7 100644 --- a/chrome/browser/sync/sync_startup_tracker_unittest.cc +++ b/chrome/browser/sync/sync_startup_tracker_unittest.cc
@@ -15,8 +15,8 @@ class MockObserver : public SyncStartupTracker::Observer { public: - MOCK_METHOD0(SyncStartupCompleted, void()); - MOCK_METHOD0(SyncStartupFailed, void()); + MOCK_METHOD(void, SyncStartupCompleted, (), (override)); + MOCK_METHOD(void, SyncStartupFailed, (), (override)); }; class SyncStartupTrackerTest : public testing::Test {
diff --git a/chrome/browser/sync/test/integration/autofill_helper.cc b/chrome/browser/sync/test/integration/autofill_helper.cc index d872509..2b053f6 100644 --- a/chrome/browser/sync/test/integration/autofill_helper.cc +++ b/chrome/browser/sync/test/integration/autofill_helper.cc
@@ -56,7 +56,10 @@ class MockWebDataServiceObserver : public AutofillWebDataServiceObserverOnDBSequence { public: - MOCK_METHOD1(AutofillEntriesChanged, void(const AutofillChangeList& changes)); + MOCK_METHOD(void, + AutofillEntriesChanged, + (const AutofillChangeList& changes), + (override)); }; scoped_refptr<AutofillWebDataService> GetWebDataService(int index) {
diff --git a/chrome/browser/sync/test/integration/autofill_helper.h b/chrome/browser/sync/test/integration/autofill_helper.h index b6698207..62b47b3a 100644 --- a/chrome/browser/sync/test/integration/autofill_helper.h +++ b/chrome/browser/sync/test/integration/autofill_helper.h
@@ -150,8 +150,8 @@ PersonalDataLoadedObserverMock(); ~PersonalDataLoadedObserverMock() override; - MOCK_METHOD0(OnPersonalDataChanged, void()); - MOCK_METHOD0(OnPersonalDataFinishedProfileTasks, void()); + MOCK_METHOD(void, OnPersonalDataChanged, (), (override)); + MOCK_METHOD(void, OnPersonalDataFinishedProfileTasks, (), (override)); }; #endif // CHROME_BROWSER_SYNC_TEST_INTEGRATION_AUTOFILL_HELPER_H_
diff --git a/chrome/browser/ui/browser_command_controller_browsertest.cc b/chrome/browser/ui/browser_command_controller_browsertest.cc index 0eebeeb..9a0add7e 100644 --- a/chrome/browser/ui/browser_command_controller_browsertest.cc +++ b/chrome/browser/ui/browser_command_controller_browsertest.cc
@@ -33,9 +33,9 @@ #include "content/public/test/test_utils.h" #if defined(OS_CHROMEOS) -#include "ash/public/cpp/window_pin_type.h" -#include "ash/public/cpp/window_properties.h" #include "chromeos/constants/chromeos_switches.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" #include "ui/aura/window.h" #endif @@ -126,7 +126,7 @@ EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_EXIT)); // Set locked fullscreen mode. browser()->window()->GetNativeWindow()->SetProperty( - ash::kWindowPinTypeKey, ash::WindowPinType::kTrustedPinned); + chromeos::kWindowPinTypeKey, chromeos::WindowPinType::kTrustedPinned); // Update the corresponding command_controller state. browser()->command_controller()->LockedFullscreenStateChanged(); // Update some more states just to make sure the wrong commands don't get @@ -156,7 +156,7 @@ // Exit locked fullscreen mode. browser()->window()->GetNativeWindow()->SetProperty( - ash::kWindowPinTypeKey, ash::WindowPinType::kNone); + chromeos::kWindowPinTypeKey, chromeos::WindowPinType::kNone); // Update the corresponding command_controller state. browser()->command_controller()->LockedFullscreenStateChanged(); // IDC_EXIT is enabled again.
diff --git a/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc b/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc index 82d8e45..1cd2d02c 100644 --- a/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc +++ b/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/public/cpp/window_pin_type.h" -#include "ash/public/cpp/window_properties.h" #include "base/command_line.h" #include "chrome/browser/chromeos/login/chrome_restart_request.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -24,6 +22,8 @@ #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/ui_test_utils.h" #include "chromeos/constants/chromeos_switches.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" #include "components/account_id/account_id.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" @@ -134,8 +134,8 @@ NavigationBlockedInLockedFullscreen) { // Set locked fullscreen state. aura::Window* window = browser()->window()->GetNativeWindow(); - window->SetProperty(ash::kWindowPinTypeKey, - ash::WindowPinType::kTrustedPinned); + window->SetProperty(chromeos::kWindowPinTypeKey, + chromeos::WindowPinType::kTrustedPinned); // Navigate to a page. auto url = GURL(chrome::kChromeUIVersionURL); @@ -155,7 +155,8 @@ // As a sanity check unset the locked fullscreen state and make sure that the // navigation happens (the following EXPECTs fail if the next line isn't // executed). - window->SetProperty(ash::kWindowPinTypeKey, ash::WindowPinType::kNone); + window->SetProperty(chromeos::kWindowPinTypeKey, + chromeos::WindowPinType::kNone); Navigate(¶ms);
diff --git a/chrome/browser/ui/views/accessibility/accessibility_focus_highlight.cc b/chrome/browser/ui/views/accessibility/accessibility_focus_highlight.cc index dc98f64..eb2c8ed 100644 --- a/chrome/browser/ui/views/accessibility/accessibility_focus_highlight.cc +++ b/chrome/browser/ui/views/accessibility/accessibility_focus_highlight.cc
@@ -89,12 +89,12 @@ profile_pref_registrar_.Init(browser_view_->browser()->profile()->GetPrefs()); profile_pref_registrar_.Add( prefs::kAccessibilityFocusHighlightEnabled, - base::BindRepeating( - &AccessibilityFocusHighlight::AddOrRemoveFocusObserver, - base::Unretained(this))); + base::BindRepeating(&AccessibilityFocusHighlight::AddOrRemoveObservers, + base::Unretained(this))); - // Initialise focus observer based on current preferences. - AddOrRemoveFocusObserver(); + // Initialise focus and tab strip model observers based on current + // preferences. + AddOrRemoveObservers(); // One-time initialization of statics the first time an instance is created. if (fade_in_time_.is_zero()) { @@ -215,8 +215,10 @@ } } -void AccessibilityFocusHighlight::AddOrRemoveFocusObserver() { - PrefService* prefs = browser_view_->browser()->profile()->GetPrefs(); +void AccessibilityFocusHighlight::AddOrRemoveObservers() { + Browser* browser = browser_view_->browser(); + PrefService* prefs = browser->profile()->GetPrefs(); + TabStripModel* tab_strip_model = browser->tab_strip_model(); if (prefs->GetBoolean(prefs::kAccessibilityFocusHighlightEnabled)) { // Listen for focus changes. Automatically deregisters when destroyed, @@ -224,15 +226,18 @@ notification_registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, content::NotificationService::AllSources()); - return; - } - if (notification_registrar_.IsRegistered( + tab_strip_model->AddObserver(this); + return; + } else { + if (notification_registrar_.IsRegistered( + this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, + content::NotificationService::AllSources())) { + notification_registrar_.Remove( this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, - content::NotificationService::AllSources())) { - notification_registrar_.Remove(this, - content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, - content::NotificationService::AllSources()); + content::NotificationService::AllSources()); + } + tab_strip_model->RemoveObserver(this); } } @@ -390,3 +395,10 @@ compositor_ = nullptr; } } + +void AccessibilityFocusHighlight::OnTabStripModelChanged( + TabStripModel*, + const TabStripModelChange&, + const TabStripSelectionChange&) { + RemoveLayer(); +}
diff --git a/chrome/browser/ui/views/accessibility/accessibility_focus_highlight.h b/chrome/browser/ui/views/accessibility/accessibility_focus_highlight.h index 6b622554..664d9bdb 100644 --- a/chrome/browser/ui/views/accessibility/accessibility_focus_highlight.h +++ b/chrome/browser/ui/views/accessibility/accessibility_focus_highlight.h
@@ -10,6 +10,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/time/time.h" +#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "components/prefs/pref_change_registrar.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -29,7 +30,8 @@ // highlight the focused UI element for accessibility. class AccessibilityFocusHighlight : public ui::LayerDelegate, public ui::CompositorAnimationObserver, - public content::NotificationObserver { + public content::NotificationObserver, + public TabStripModelObserver { public: explicit AccessibilityFocusHighlight(BrowserView* browser_view); ~AccessibilityFocusHighlight() override; @@ -56,8 +58,8 @@ // Get rid of the layer and stop animation. void RemoveLayer(); - // Handle preference changes by adding or removing the layer as necessary. - void AddOrRemoveFocusObserver(); + // Handle preference changes by adding or removing observers as necessary. + void AddOrRemoveObservers(); // content::NotificationObserver overrides: void Observe(int type, @@ -73,6 +75,11 @@ void OnAnimationStep(base::TimeTicks timestamp) override; void OnCompositingShuttingDown(ui::Compositor* compositor) override; + // TabStripModelObserver + void OnTabStripModelChanged(TabStripModel*, + const TabStripModelChange&, + const TabStripSelectionChange&) override; + // Compute the highlight color based on theme colors and defaults. SkColor GetHighlightColor();
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc index f10881d..e81d7ac 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
@@ -308,8 +308,8 @@ const bool should_hide_shelf = !profiles::IsPublicSession() && fullscreen_types != AppWindow::FULLSCREEN_TYPE_OS; - widget()->GetNativeWindow()->SetProperty(ash::kHideShelfWhenFullscreenKey, - should_hide_shelf); + widget()->GetNativeWindow()->SetProperty( + chromeos::kHideShelfWhenFullscreenKey, should_hide_shelf); widget()->non_client_view()->Layout(); }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc index 89b4065..d1ce34d 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -10,7 +10,6 @@ #include "ash/public/cpp/shelf_test_api.h" #include "ash/public/cpp/split_view_test_api.h" #include "ash/public/cpp/test/shell_test_api.h" -#include "ash/public/cpp/window_pin_type.h" #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" #include "ash/wm/overview/overview_controller.h" @@ -72,6 +71,8 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "chromeos/ui/base/chromeos_ui_constants.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #include "components/account_id/account_id.h" @@ -736,7 +737,7 @@ // Set locked fullscreen state. browser()->window()->GetNativeWindow()->SetProperty( - ash::kWindowPinTypeKey, ash::WindowPinType::kTrustedPinned); + chromeos::kWindowPinTypeKey, chromeos::WindowPinType::kTrustedPinned); // We're fullscreen, immersive is disabled in locked fullscreen, and while // we're at it, also make sure that the shelf is hidden. @@ -762,7 +763,7 @@ // Set locked fullscreen state. browser()->window()->GetNativeWindow()->SetProperty( - ash::kWindowPinTypeKey, ash::WindowPinType::kTrustedPinned); + chromeos::kWindowPinTypeKey, chromeos::WindowPinType::kTrustedPinned); // We're fullscreen, immersive is disabled in locked fullscreen, and while // we're at it, also make sure that the shelf is hidden.
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc index 5bf9730..c3c4699 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" -#include "ash/public/cpp/window_properties.h" #include "base/macros.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" @@ -219,14 +218,14 @@ ->fullscreen_controller() ->IsWindowFullscreenForTabOrPending(); browser_view_->GetNativeWindow()->SetProperty( - ash::kHideShelfWhenFullscreenKey, in_tab_fullscreen); + chromeos::kHideShelfWhenFullscreenKey, in_tab_fullscreen); } void ImmersiveModeControllerAsh::OnWindowPropertyChanged(aura::Window* window, const void* key, intptr_t old) { // Track locked fullscreen changes. - if (key == ash::kWindowPinTypeKey) { + if (key == chromeos::kWindowPinTypeKey) { browser_view_->FullscreenStateChanging(); return; }
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc index 8bc2966c..d4fd4db 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" -#include "ash/public/cpp/window_pin_type.h" #include "ash/public/cpp/window_properties.h" #include "ash/root_window_controller.h" #include "ash/shell.h" @@ -26,6 +25,7 @@ #include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chromeos/ui/base/window_pin_type.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #include "ui/aura/window.h" #include "ui/base/pointer/touch_ui_controller.h"
diff --git a/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.cc b/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.cc index 30ce939..2758d4f7 100644 --- a/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.cc +++ b/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.cc
@@ -105,7 +105,6 @@ std::vector<TargetInfo> targets, apps::mojom::IntentPtr intent, sharesheet::CloseCallback close_callback) { - targets_ = std::move(targets); intent_ = std::move(intent); close_callback_ = std::move(close_callback); @@ -132,7 +131,7 @@ main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kSpacing); auto scroll_view = std::make_unique<views::ScrollView>(); - scroll_view->SetContents(MakeScrollableTargetView()); + scroll_view->SetContents(MakeScrollableTargetView(std::move(targets))); scroll_view->ClipHeightTo(kTargetViewHeight, kTargetViewExpandedHeight); // TODO(crbug.com/1097623) Update grey border lines. @@ -142,8 +141,9 @@ main_layout->StartRow(views::GridLayout::kFixedSize, COLUMN_SET_ID_TITLE, kShortSpacing); - expand_button_ = - main_layout->AddView(std::make_unique<SharesheetExpandButton>(this)); + expand_button_ = main_layout->AddView( + std::make_unique<SharesheetExpandButton>(base::BindRepeating( + &SharesheetBubbleView::ExpandButtonPressed, base::Unretained(this)))); main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kShortSpacing); main_view_->SetFocusBehavior(View::FocusBehavior::ALWAYS); @@ -153,17 +153,18 @@ GetWidget()->GetRootView()->Layout(); widget->Show(); - if (targets_.size() <= (kMaxRowsForDefaultView * kMaxTargetsPerRow)) { + if (expanded_view_->children().size() > 1) { + SetToDefaultBubbleSizing(); + } else { width_ = kDefaultBubbleWidth; height_ = kNoExtensionBubbleHeight; expand_button_->SetVisible(false); - } else { - SetToDefaultBubbleSizing(); } UpdateAnchorPosition(); } -std::unique_ptr<views::View> SharesheetBubbleView::MakeScrollableTargetView() { +std::unique_ptr<views::View> SharesheetBubbleView::MakeScrollableTargetView( + std::vector<TargetInfo> targets) { // Set up default and expanded views. auto default_view = std::make_unique<views::View>(); auto* default_layout = @@ -197,7 +198,8 @@ expanded_layout->AddPaddingRow(views::GridLayout::kFixedSize, kExpandViewPadding); - PopulateLayoutsWithTargets(default_layout, expanded_layout); + PopulateLayoutsWithTargets(std::move(targets), default_layout, + expanded_layout); default_layout->AddPaddingRow(views::GridLayout::kFixedSize, kShortSpacing); auto scrollable_view = std::make_unique<views::View>(); @@ -215,14 +217,15 @@ } void SharesheetBubbleView::PopulateLayoutsWithTargets( + std::vector<TargetInfo> targets, views::GridLayout* default_layout, views::GridLayout* expanded_layout) { // Add first kMaxRowsForDefaultView*kMaxTargetsPerRow targets to // |default_view| and subsequent targets to |expanded_view|. - size_t target_counter = 0; size_t row_count = 0; + size_t target_counter = 0; auto* layout_for_target = default_layout; - for (const auto& target : targets_) { + for (auto& target : targets) { if (target_counter % kMaxTargetsPerRow == 0) { // When we've reached kMaxRowsForDefaultView switch to populating // |expanded_layout|. @@ -238,13 +241,16 @@ layout_for_target->StartRow(views::GridLayout::kFixedSize, COLUMN_SET_ID_TARGETS); } + ++target_counter; base::string16 secondary_display_name = target.secondary_display_name.value_or(base::string16()); auto target_view = std::make_unique<SharesheetTargetButton>( - this, target.display_name, secondary_display_name, &target.icon); - target_view->set_tag(target_counter++); + base::BindRepeating(&SharesheetBubbleView::TargetButtonPressed, + base::Unretained(this), + base::Passed(std::move(target))), + target.display_name, secondary_display_name, &target.icon); layout_for_target->AddView(std::move(target_view)); } @@ -265,7 +271,6 @@ views::Widget* widget = View::GetWidget(); widget->CloseWithReason(views::Widget::ClosedReason::kAcceptButtonClicked); // Reset all bubble values. - targets_.clear(); active_target_ = base::string16(); intent_.reset(); keyboard_highlighted_target_ = 0; @@ -297,63 +302,25 @@ break; } - keyboard_highlighted_target_ += delta; + const size_t default_views = default_view_->children().size(); + // The -1 here and +1 below account for the app list label. + const size_t targets = + default_views + + (show_expanded_view_ ? (expanded_view_->children().size() - 1) : 0); + const int new_target = int{keyboard_highlighted_target_} + delta; + keyboard_highlighted_target_ = + size_t{base::ClampToRange(new_target, 0, int{targets} - 1)}; - int default_view_max = kMaxTargetsPerRow * kMaxRowsForDefaultView - 1; - int max_target_index = targets_.size() - 1; - if ((!show_expanded_view_) && (max_target_index > default_view_max)) { - max_target_index = default_view_max; - } - - if (keyboard_highlighted_target_ > max_target_index) { - keyboard_highlighted_target_ = max_target_index; - } else if (keyboard_highlighted_target_ < 0) { - keyboard_highlighted_target_ = 0; - } - - if (keyboard_highlighted_target_ <= default_view_max) { + if (keyboard_highlighted_target_ < default_views) { default_view_->children()[keyboard_highlighted_target_]->RequestFocus(); } else { - DCHECK_LT(keyboard_highlighted_target_ - default_view_max, - expanded_view_->children().size()); - DCHECK(show_expanded_view_); - expanded_view_->children()[keyboard_highlighted_target_ - default_view_max] + expanded_view_->children()[keyboard_highlighted_target_ + 1 - default_views] ->RequestFocus(); } View::OnKeyEvent(event); } -void SharesheetBubbleView::ButtonPressed(views::Button* sender, - const ui::Event& event) { - if (sender == expand_button_) { - if (show_expanded_view_) { - expand_button_->SetDefaultView(); - expanded_view_->SetVisible(false); - ResizeBubble(kDefaultBubbleWidth, kDefaultBubbleHeight); - } else { - expand_button_->SetExpandedView(); - expanded_view_->SetVisible(true); - ResizeBubble(kDefaultBubbleWidth, kExpandedBubbleHeight); - } - show_expanded_view_ = !show_expanded_view_; - } else { - auto type = targets_[sender->tag()].type; - if (type == sharesheet::TargetType::kAction) { - active_target_ = targets_[sender->tag()].launch_name; - } else { - intent_->activity_name = targets_[sender->tag()].activity_name; - } - delegate_->OnTargetSelected(targets_[sender->tag()].launch_name, type, - std::move(intent_), share_action_view_); - intent_.reset(); - user_cancelled_ = false; - if (close_callback_) { - std::move(close_callback_).Run(sharesheet::SharesheetResult::kSuccess); - } - } -} - std::unique_ptr<views::NonClientFrameView> SharesheetBubbleView::CreateNonClientFrameView(views::Widget* widget) { auto bubble_border = @@ -413,6 +380,31 @@ share_action_view_->SetVisible(false); } +void SharesheetBubbleView::ExpandButtonPressed() { + show_expanded_view_ = !show_expanded_view_; + if (show_expanded_view_) + expand_button_->SetExpandedView(); + else + expand_button_->SetDefaultView(); + expanded_view_->SetVisible(show_expanded_view_); + ResizeBubble(kDefaultBubbleWidth, show_expanded_view_ ? kExpandedBubbleHeight + : kDefaultBubbleHeight); +} + +void SharesheetBubbleView::TargetButtonPressed(TargetInfo target) { + auto type = target.type; + if (type == sharesheet::TargetType::kAction) + active_target_ = target.launch_name; + else + intent_->activity_name = target.activity_name; + delegate_->OnTargetSelected(target.launch_name, type, std::move(intent_), + share_action_view_); + intent_.reset(); + user_cancelled_ = false; + if (close_callback_) + std::move(close_callback_).Run(sharesheet::SharesheetResult::kSuccess); +} + void SharesheetBubbleView::UpdateAnchorPosition() { // If |width_| is not set, set to default value. if (width_ == 0) {
diff --git a/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.h b/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.h index 0340ec12..86f4302 100644 --- a/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.h +++ b/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.h
@@ -10,7 +10,6 @@ #include "chrome/browser/sharesheet/sharesheet_types.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" -#include "ui/views/controls/button/button.h" namespace views { class GridLayout; @@ -26,8 +25,7 @@ class SharesheetExpandButton; -class SharesheetBubbleView : public views::BubbleDialogDelegateView, - public views::ButtonListener { +class SharesheetBubbleView : public views::BubbleDialogDelegateView { public: using TargetInfo = sharesheet::TargetInfo; @@ -51,9 +49,6 @@ // ui::EventHandler overrides: void OnKeyEvent(ui::KeyEvent* event) override; - // views::ButtonListener overrides - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // views::WidgetDelegate override std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView( views::Widget* widget) override; @@ -63,16 +58,18 @@ void OnWidgetDestroyed(views::Widget* widget) override; void CreateBubble(); - std::unique_ptr<views::View> MakeScrollableTargetView(); - void PopulateLayoutsWithTargets(views::GridLayout* default_layout, + std::unique_ptr<views::View> MakeScrollableTargetView( + std::vector<TargetInfo> targets); + void PopulateLayoutsWithTargets(std::vector<TargetInfo> targets, + views::GridLayout* default_layout, views::GridLayout* expanded_layout); - void OnDialogClosed(); + void ExpandButtonPressed(); + void TargetButtonPressed(TargetInfo target); void UpdateAnchorPosition(); void SetToDefaultBubbleSizing(); // Owns this class. sharesheet::SharesheetServiceDelegate* delegate_; - std::vector<TargetInfo> targets_; base::string16 active_target_; apps::mojom::IntentPtr intent_; sharesheet::CloseCallback close_callback_; @@ -82,7 +79,7 @@ bool user_cancelled_ = true; bool show_expanded_view_ = false; - int keyboard_highlighted_target_ = 0; + size_t keyboard_highlighted_target_ = 0; views::View* root_view_ = nullptr; views::View* main_view_ = nullptr;
diff --git a/chrome/browser/ui/views/sharesheet/sharesheet_expand_button.cc b/chrome/browser/ui/views/sharesheet/sharesheet_expand_button.cc index b443a12..1fbf761 100644 --- a/chrome/browser/ui/views/sharesheet/sharesheet_expand_button.cc +++ b/chrome/browser/ui/views/sharesheet/sharesheet_expand_button.cc
@@ -27,8 +27,8 @@ } // namespace -SharesheetExpandButton::SharesheetExpandButton(views::ButtonListener* listener) - : Button(listener) { +SharesheetExpandButton::SharesheetExpandButton(PressedCallback callback) + : Button(std::move(callback)) { auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kHorizontal, gfx::Insets(6, 16, 6, 16), kBetweenChildSpacing, true));
diff --git a/chrome/browser/ui/views/sharesheet/sharesheet_expand_button.h b/chrome/browser/ui/views/sharesheet/sharesheet_expand_button.h index d899829..78fbbf55 100644 --- a/chrome/browser/ui/views/sharesheet/sharesheet_expand_button.h +++ b/chrome/browser/ui/views/sharesheet/sharesheet_expand_button.h
@@ -12,7 +12,7 @@ class SharesheetExpandButton : public views::Button { public: - explicit SharesheetExpandButton(views::ButtonListener* listener); + explicit SharesheetExpandButton(PressedCallback callback); SharesheetExpandButton(const SharesheetExpandButton&) = delete; SharesheetExpandButton& operator=(const SharesheetExpandButton&) = delete;
diff --git a/chrome/browser/ui/views/sharesheet/sharesheet_target_button.cc b/chrome/browser/ui/views/sharesheet/sharesheet_target_button.cc index f872f19..ae40b70 100644 --- a/chrome/browser/ui/views/sharesheet/sharesheet_target_button.cc +++ b/chrome/browser/ui/views/sharesheet/sharesheet_target_button.cc
@@ -35,11 +35,11 @@ // A button that represents a candidate share target. SharesheetTargetButton::SharesheetTargetButton( - views::ButtonListener* listener, + PressedCallback callback, const base::string16& display_name, const base::string16& secondary_display_name, const gfx::ImageSkia* icon) - : Button(listener) { + : Button(std::move(callback)) { // TODO(crbug.com/1097623) Margins shouldn't be within // SharesheetTargetButton as the margins are different in |expanded_view_|. auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
diff --git a/chrome/browser/ui/views/sharesheet/sharesheet_target_button.h b/chrome/browser/ui/views/sharesheet/sharesheet_target_button.h index 987b70d..b808d7a 100644 --- a/chrome/browser/ui/views/sharesheet/sharesheet_target_button.h +++ b/chrome/browser/ui/views/sharesheet/sharesheet_target_button.h
@@ -11,7 +11,7 @@ class SharesheetTargetButton : public views::Button { public: - SharesheetTargetButton(views::ButtonListener* listener, + SharesheetTargetButton(PressedCallback callback, const base::string16& display_name, const base::string16& secondary_display_name, const gfx::ImageSkia* icon);
diff --git a/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_browsertest.cc b/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_browsertest.cc index 4326d37..9f25585 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_browsertest.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_browsertest.cc
@@ -20,30 +20,6 @@ #include "ui/gfx/animation/animation.h" #include "ui/gfx/animation/animation_test_api.h" -// TODO(crbug.com/1061637): Clean this and the same code in ukm_browsertest. -// Maybe move them to InProcessBrowserTest. -namespace { - -void UnblockOnProfileCreation(base::RunLoop* run_loop, - Profile* profile, - Profile::CreateStatus status) { - if (status == Profile::CREATE_STATUS_INITIALIZED) - run_loop->Quit(); -} - -Profile* CreateGuestProfile() { - ProfileManager* profile_manager = g_browser_process->profile_manager(); - base::FilePath new_path = profile_manager->GetGuestProfilePath(); - base::RunLoop run_loop; - profile_manager->CreateProfileAsync( - new_path, base::BindRepeating(&UnblockOnProfileCreation, &run_loop), - base::string16(), std::string()); - run_loop.Run(); - return profile_manager->GetProfileByPath(new_path); -} - -} // namespace - // The param is whether to use the highlight in the container. class ToolbarAccountIconContainerViewBrowserTest : public InProcessBrowserTest { public: @@ -108,9 +84,7 @@ IN_PROC_BROWSER_TEST_F(ToolbarAccountIconContainerViewBrowserTest, ShouldUpdateHighlightInGuestWindow) { - Profile* guest_profile = CreateGuestProfile(); - Browser* guest_browser = CreateIncognitoBrowser(guest_profile); - ASSERT_TRUE(guest_browser->profile()->IsGuestSession()); + Browser* guest_browser = InProcessBrowserTest::CreateGuestBrowser(); ToolbarAccountIconContainerView* container_view = BrowserView::GetBrowserViewForBrowser(guest_browser) ->toolbar()
diff --git a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc index eae3acf..21037b4 100644 --- a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc +++ b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
@@ -10,7 +10,6 @@ #include "base/check_op.h" #include "base/debug/dump_without_crashing.h" -#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/metrics/histogram_functions.h" #include "base/optional.h" @@ -35,10 +34,6 @@ #include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_launch/web_launch_files_helper.h" -#include "chrome/common/chrome_features.h" -#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" -#include "content/public/common/content_switches.h" -#include "third_party/blink/public/common/features.h" #include "ui/base/window_open_disposition.h" #include "ui/display/types/display_constants.h" @@ -228,39 +223,22 @@ content::WebContents* web_contents = nullptr; - // TODO(crbug.com/1129340): Remove these lines and make CCA resizeable after - // CCA supports responsive UI. - bool can_resize = app_type != SystemAppType::CAMERA; - if (base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions)) { - if (!browser) { - browser = CreateWebApplicationWindow(profile_for_launch, params->app_id, - params->disposition, can_resize); - } + if (!browser) { + // TODO(crbug.com/1129340): Remove these lines and make CCA resizeable after + // CCA supports responsive UI. + bool can_resize = app_type != SystemAppType::CAMERA; + browser = CreateWebApplicationWindow(profile_for_launch, params->app_id, + params->disposition, can_resize); + } - // Navigate application window to application's |url| if necessary. - // Help app always navigates because its url might not match the url inside - // the iframe, and the iframe's url is the one that matters. - web_contents = browser->tab_strip_model()->GetWebContentsAt(0); - if (!web_contents || web_contents->GetURL() != url || - app_type == SystemAppType::HELP) { - web_contents = NavigateWebApplicationWindow( - browser, params->app_id, url, WindowOpenDisposition::CURRENT_TAB); - } - } else { - if (!browser) { - browser = - CreateApplicationWindow(profile_for_launch, *params, url, can_resize); - } - - // Navigate application window to application's |url| if necessary. - // Help app always navigates because its url might not match the url inside - // the iframe, and the iframe's url is the one that matters. - web_contents = browser->tab_strip_model()->GetWebContentsAt(0); - if (!web_contents || web_contents->GetURL() != url || - app_type == SystemAppType::HELP) { - web_contents = NavigateApplicationWindow( - browser, *params, url, WindowOpenDisposition::CURRENT_TAB); - } + // Navigate application window to application's |url| if necessary. + // Help app always navigates because its url might not match the url inside + // the iframe, and the iframe's url is the one that matters. + web_contents = browser->tab_strip_model()->GetWebContentsAt(0); + if (!web_contents || web_contents->GetURL() != url || + app_type == SystemAppType::HELP) { + web_contents = NavigateWebApplicationWindow( + browser, params->app_id, url, WindowOpenDisposition::CURRENT_TAB); } // Send launch files.
diff --git a/chrome/browser/ui/webui/omnibox/BUILD.gn b/chrome/browser/ui/webui/omnibox/BUILD.gn index b58f3e4..b7d5bda 100644 --- a/chrome/browser/ui/webui/omnibox/BUILD.gn +++ b/chrome/browser/ui/webui/omnibox/BUILD.gn
@@ -6,4 +6,5 @@ mojom("mojo_bindings") { sources = [ "omnibox.mojom" ] + webui_module_path = "/chrome/browser/ui/webui/omnibox" }
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_ui.cc b/chrome/browser/ui/webui/omnibox/omnibox_ui.cc index ba37706f..f15c23a 100644 --- a/chrome/browser/ui/webui/omnibox/omnibox_ui.cc +++ b/chrome/browser/ui/webui/omnibox/omnibox_ui.cc
@@ -49,7 +49,7 @@ {"omnibox_input.js", IDR_OMNIBOX_INPUT_JS}, {"omnibox_output.js", IDR_OMNIBOX_OUTPUT_JS}, {"omnibox.js", IDR_OMNIBOX_JS}, - {"chrome/browser/ui/webui/omnibox/omnibox.mojom-lite.js", + {"chrome/browser/ui/webui/omnibox/omnibox.mojom-webui.js", IDR_OMNIBOX_MOJO_JS}, }; webui::AddResourcePathsBulk(source, kResources);
diff --git a/chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc b/chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc index ea3df0ae..b21849b 100644 --- a/chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc +++ b/chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc
@@ -51,13 +51,13 @@ } void QuotaInternalsHandler::ReportAvailableSpace(int64_t available_space) { - SendMessage("AvailableSpaceUpdated", - base::Value(static_cast<double>(available_space))); + FireWebUIListener("AvailableSpaceUpdated", + base::Value(static_cast<double>(available_space))); } void QuotaInternalsHandler::ReportGlobalInfo(const GlobalStorageInfo& data) { std::unique_ptr<base::Value> value(data.NewValue()); - SendMessage("GlobalInfoUpdated", *value); + FireWebUIListener("GlobalInfoUpdated", *value); } void QuotaInternalsHandler::ReportPerHostInfo( @@ -67,7 +67,7 @@ values.Append(itr->NewValue()); } - SendMessage("PerHostInfoUpdated", values); + FireWebUIListener("PerHostInfoUpdated", values); } void QuotaInternalsHandler::ReportPerOriginInfo( @@ -77,7 +77,7 @@ origins_value.Append(itr->NewValue()); } - SendMessage("PerOriginInfoUpdated", origins_value); + FireWebUIListener("PerOriginInfoUpdated", origins_value); } void QuotaInternalsHandler::ReportStatistics(const Statistics& stats) { @@ -86,23 +86,18 @@ dict.SetString(itr->first, itr->second); } - SendMessage("StatisticsUpdated", dict); + FireWebUIListener("StatisticsUpdated", dict); } void QuotaInternalsHandler::ReportStoragePressureFlag() { base::DictionaryValue flag_enabled; flag_enabled.SetBoolean("isStoragePressureEnabled", IsStoragePressureEnabled()); - SendMessage("StoragePressureFlagUpdated", flag_enabled); -} - -void QuotaInternalsHandler::SendMessage(const std::string& message, - const base::Value& value) { - web_ui()->CallJavascriptFunctionUnsafe("cr.quota.messageHandler", - base::Value(message), value); + FireWebUIListener("StoragePressureFlagUpdated", flag_enabled); } void QuotaInternalsHandler::OnRequestInfo(const base::ListValue*) { + AllowJavascript(); if (!proxy_.get()) proxy_ = new QuotaInternalsProxy(this); ReportStoragePressureFlag(); @@ -113,6 +108,7 @@ void QuotaInternalsHandler::OnTriggerStoragePressure( const base::ListValue* args) { + AllowJavascript(); CHECK_EQ(1U, args->GetSize()); std::string origin_string; CHECK(args->GetString(0, &origin_string));
diff --git a/chrome/browser/ui/webui/quota_internals/quota_internals_handler.h b/chrome/browser/ui/webui/quota_internals/quota_internals_handler.h index 1469f488..2d155a6 100644 --- a/chrome/browser/ui/webui/quota_internals/quota_internals_handler.h +++ b/chrome/browser/ui/webui/quota_internals/quota_internals_handler.h
@@ -16,7 +16,6 @@ #include "content/public/browser/web_ui_message_handler.h" namespace base { -class Value; class ListValue; } @@ -47,7 +46,6 @@ private: void OnRequestInfo(const base::ListValue*); void OnTriggerStoragePressure(const base::ListValue*); - void SendMessage(const std::string& message, const base::Value& value); scoped_refptr<QuotaInternalsProxy> proxy_;
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index e478e89c..aba94be9 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1602955577-a20645f1db5850cab28b6e02a84227b75223b9dc.profdata +chrome-linux-master-1603087080-212b8c940037ae1d78d2bd42956b635be6add59e.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 53a489a..ef557a28 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1602955577-bb0b49bc2897e7981bccc868b6d9f8258514b16c.profdata +chrome-mac-master-1603087080-138c0bc7a94d51e9caaa7300e866d8f7233b285e.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 8f1283ef..cf88274 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1602892676-f42fcf882f856a6f2f9f9f80f30554db75044c2b.profdata +chrome-win32-master-1603031994-5f3b6fcba7bce636145481c18ca09ca6363425d3.profdata
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc index 8b2c48a..baf3f0f8 100644 --- a/chrome/test/base/in_process_browser_test.cc +++ b/chrome/test/base/in_process_browser_test.cc
@@ -154,6 +154,17 @@ } #endif // defined(OS_CHROMEOS) +#if !defined(OS_ANDROID) +// An observer that returns back to test code after a new profile is +// initialized. +void UnblockOnProfileCreation(base::RunLoop* run_loop, + Profile* profile, + Profile::CreateStatus status) { + if (status == Profile::CREATE_STATUS_INITIALIZED) + run_loop->Quit(); +} +#endif + } // namespace // static @@ -486,6 +497,29 @@ } #endif // !defined(OS_MAC) +#if !defined(OS_ANDROID) +Browser* InProcessBrowserTest::CreateGuestBrowser() { + // Get Guest profile. + ProfileManager* profile_manager = g_browser_process->profile_manager(); + base::FilePath guest_path = profile_manager->GetGuestProfilePath(); + + base::RunLoop run_loop; + profile_manager->CreateProfileAsync( + guest_path, base::Bind(&UnblockOnProfileCreation, &run_loop), + base::string16(), std::string()); + run_loop.Run(); + + Profile* profile = profile_manager->GetProfileByPath(guest_path); + if (!profile->IsEphemeralGuestProfile()) + profile = profile->GetPrimaryOTRProfile(); + + // Create browser and add tab. + Browser* browser = new Browser(Browser::CreateParams(profile, true)); + AddBlankTabAndShow(browser); + return browser; +} +#endif + void InProcessBrowserTest::AddBlankTabAndShow(Browser* browser) { content::WindowedNotificationObserver observer( content::NOTIFICATION_LOAD_STOP,
diff --git a/chrome/test/base/in_process_browser_test.h b/chrome/test/base/in_process_browser_test.h index 6a0796f0c..867dcf2 100644 --- a/chrome/test/base/in_process_browser_test.h +++ b/chrome/test/base/in_process_browser_test.h
@@ -227,6 +227,11 @@ // is omitted, the currently active profile will be used. Browser* CreateIncognitoBrowser(Profile* profile = nullptr); +#if !defined(OS_ANDROID) + // Similar to |CreateBrowser|, but creates a Guest browser. + Browser* CreateGuestBrowser(); +#endif + // Creates a browser for a popup window with a single tab (about:blank), waits // for the tab to finish loading, and shows the browser. Browser* CreateBrowserForPopup(Profile* profile);
diff --git a/chrome/test/data/webui/chromeos/diagnostics/realtime_cpu_chart_test.js b/chrome/test/data/webui/chromeos/diagnostics/realtime_cpu_chart_test.js index 07b162f..0f83ba812 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/realtime_cpu_chart_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/realtime_cpu_chart_test.js
@@ -81,7 +81,8 @@ }); }); - test('InitializePlot', () => { + // Flaky: https://crbug.com/1139523 + test.skip('InitializePlot', () => { const user = 10; const system = 30; return initializeRealtimeCpuChart(user, system).then(() => {
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 2ac4a76f..5a0c1b2a 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -13538.0.0 \ No newline at end of file +13540.0.0 \ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/resources/.eslintrc.js b/chromeos/components/camera_app_ui/resources/.eslintrc.js index 204669008..271a5add 100644 --- a/chromeos/components/camera_app_ui/resources/.eslintrc.js +++ b/chromeos/components/camera_app_ui/resources/.eslintrc.js
@@ -362,24 +362,19 @@ 'root': true, 'env': { 'browser': true, - 'es6': true, + 'es2020': true, 'webextensions': true, }, 'parserOptions': { - 'ecmaVersion': 2018, + 'ecmaVersion': 2020, 'sourceType': 'module', }, 'extends': 'eslint:recommended', 'globals': { 'arc': 'readable', - // Adds BigInt64Array here since current version of eslint does not treat - // BigInt64Array as a defined type. - 'BigInt64Array': 'readable', 'chromeosCamera': 'readable', 'blink': 'readable', - 'cca': 'readable', // TODO(inker): remove this after resolving b/141518780. 'cros': 'readable', - 'globalThis': 'readable', 'webkitRequestFileSystem': 'readable', }, // Generally, the rules should be compatible to both bundled and the newest
diff --git a/chromeos/components/camera_app_ui/resources/js/views/camera/preview.js b/chromeos/components/camera_app_ui/resources/js/views/camera/preview.js index f429a82..40cc51d1 100644 --- a/chromeos/components/camera_app_ui/resources/js/views/camera/preview.js +++ b/chromeos/components/camera_app_ui/resources/js/views/camera/preview.js
@@ -226,28 +226,33 @@ element.textContent = val; }; - const buildInverseTable = (obj, prefix) => { - const tbl = {}; + /** + * @param {!Object<string, number>} obj + * @param {string} prefix + * @return {!Map<number, string>} + */ + const buildInverseMap = (obj, prefix) => { + const map = new Map(); for (const [key, val] of Object.entries(obj)) { if (!key.startsWith(prefix)) { continue; } - if (tbl.hasOwnProperty(val)) { + if (map.has(val)) { console.error(`Duplicated value: ${val}`); continue; } - tbl[val] = key.slice(prefix.length); + map.set(val, key.slice(prefix.length)); } - return tbl; + return map; }; - const afStateName = buildInverseTable( + const afStateName = buildInverseMap( cros.mojom.AndroidControlAfState, 'ANDROID_CONTROL_AF_STATE_'); - const aeStateName = buildInverseTable( + const aeStateName = buildInverseMap( cros.mojom.AndroidControlAeState, 'ANDROID_CONTROL_AE_STATE_'); - const awbStateName = buildInverseTable( + const awbStateName = buildInverseMap( cros.mojom.AndroidControlAwbState, 'ANDROID_CONTROL_AWB_STATE_'); - const aeAntibandingModeName = buildInverseTable( + const aeAntibandingModeName = buildInverseMap( cros.mojom.AndroidControlAeAntibandingMode, 'ANDROID_CONTROL_AE_ANTIBANDING_MODE_'); @@ -262,7 +267,7 @@ showValue('#preview-focus-distance', `${focusDistance} cm`); }, [tag.ANDROID_CONTROL_AF_STATE]: ([value]) => { - showValue('#preview-af-state', afStateName[value]); + showValue('#preview-af-state', afStateName.get(value)); }, [tag.ANDROID_SENSOR_SENSITIVITY]: ([value]) => { const sensitivity = value; @@ -277,10 +282,11 @@ showValue('#preview-frame-duration', `${frameFrequency} Hz`); }, [tag.ANDROID_CONTROL_AE_ANTIBANDING_MODE]: ([value]) => { - showValue('#preview-ae-antibanding-mode', aeAntibandingModeName[value]); + showValue( + '#preview-ae-antibanding-mode', aeAntibandingModeName.get(value)); }, [tag.ANDROID_CONTROL_AE_STATE]: ([value]) => { - showValue('#preview-ae-state', aeStateName[value]); + showValue('#preview-ae-state', aeStateName.get(value)); }, [tag.ANDROID_COLOR_CORRECTION_GAINS]: ([valueRed, , , valueBlue]) => { const wbGainRed = valueRed.toFixed(2); @@ -289,7 +295,7 @@ showValue('#preview-wb-gain-blue', `${wbGainBlue}x`); }, [tag.ANDROID_CONTROL_AWB_STATE]: ([value]) => { - showValue('#preview-awb-state', awbStateName[value]); + showValue('#preview-awb-state', awbStateName.get(value)); }, [tag.ANDROID_CONTROL_AF_MODE]: ([value]) => { displayCategory(
diff --git a/chromeos/components/phonehub/notification_manager.cc b/chromeos/components/phonehub/notification_manager.cc index 1613fa3b..89d11905 100644 --- a/chromeos/components/phonehub/notification_manager.cc +++ b/chromeos/components/phonehub/notification_manager.cc
@@ -70,7 +70,9 @@ for (int64_t id : notification_ids) { auto it = id_to_notification_map_.find(id); - DCHECK(it != id_to_notification_map_.end()); + if (it == id_to_notification_map_.end()) + continue; + id_to_notification_map_.erase(it); }
diff --git a/chromeos/components/phonehub/notification_manager_impl.cc b/chromeos/components/phonehub/notification_manager_impl.cc index f079bc3..c711d93 100644 --- a/chromeos/components/phonehub/notification_manager_impl.cc +++ b/chromeos/components/phonehub/notification_manager_impl.cc
@@ -22,6 +22,12 @@ void NotificationManagerImpl::DismissNotification(int64_t notification_id) { PA_LOG(INFO) << "Dismissing notification with ID " << notification_id << "."; + if (!GetNotification(notification_id)) { + PA_LOG(WARNING) << "Attempted to dismiss an invalid notification with id: " + << notification_id << "."; + return; + } + RemoveNotificationsInternal(base::flat_set<int64_t>{notification_id}); message_sender_->SendDismissNotificationRequest(notification_id); }
diff --git a/chromeos/components/phonehub/notification_manager_impl_unittest.cc b/chromeos/components/phonehub/notification_manager_impl_unittest.cc index 296a91db..7d800bf 100644 --- a/chromeos/components/phonehub/notification_manager_impl_unittest.cc +++ b/chromeos/components/phonehub/notification_manager_impl_unittest.cc
@@ -176,6 +176,15 @@ EXPECT_EQ(1u, fake_message_sender().GetDismissNotificationRequestCallCount()); EXPECT_EQ(expected_id2, fake_message_sender().GetRecentDismissNotificationRequest()); + + // Dismiss the same notification again, verify nothing happens. + manager().DismissNotification(expected_id2); + EXPECT_EQ(1u, GetNumNotifications()); + EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1)); + EXPECT_EQ(NotificationState::kRemoved, GetNotificationState(expected_id2)); + EXPECT_EQ(1u, fake_message_sender().GetDismissNotificationRequestCallCount()); + EXPECT_EQ(expected_id2, + fake_message_sender().GetRecentDismissNotificationRequest()); } TEST_F(NotificationManagerImplTest, UpdatedNotification) {
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 7694c6e..7fac3108 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -272,6 +272,18 @@ // Enables the next generation file manager. const base::Feature kFilesNG{"FilesNG", base::FEATURE_ENABLED_BY_DEFAULT}; +// Enables JS modules for Files app. +const base::Feature kFilesJsModules{"FilesJsModules", + base::FEATURE_DISABLED_BY_DEFAULT}; + +// Enables JS modules for Audio Player. +const base::Feature kAudioPlayerJsModules{"AudioPlayerJsModules", + base::FEATURE_DISABLED_BY_DEFAULT}; + +// Enables JS modules for Video Player. +const base::Feature kVideoPlayerJsModules{"VideoPlayerJsModules", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables partitioning of removable disks in file manager. const base::Feature kFilesSinglePartitionFormat{ "FilesSinglePartitionFormat", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index a2612f43..d522df9 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -131,6 +131,11 @@ extern const base::Feature kFamilyLinkOnSchoolDevice; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kFilesCameraFolder; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kFilesJsModules; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +extern const base::Feature kAudioPlayerJsModules; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +extern const base::Feature kVideoPlayerJsModules; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kFilesNG; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kFilesSinglePartitionFormat;
diff --git a/chromeos/ui/base/BUILD.gn b/chromeos/ui/base/BUILD.gn index e807214e..bc21fb7 100644 --- a/chromeos/ui/base/BUILD.gn +++ b/chromeos/ui/base/BUILD.gn
@@ -13,6 +13,8 @@ "chromeos_ui_constants.h", "tablet_state.cc", "tablet_state.h", + "window_pin_type.cc", + "window_pin_type.h", "window_properties.cc", "window_properties.h", "window_state_type.cc",
diff --git a/ash/public/cpp/window_pin_type.cc b/chromeos/ui/base/window_pin_type.cc similarity index 84% rename from ash/public/cpp/window_pin_type.cc rename to chromeos/ui/base/window_pin_type.cc index 6307c2c..d6a371a7 100644 --- a/ash/public/cpp/window_pin_type.cc +++ b/chromeos/ui/base/window_pin_type.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/public/cpp/window_pin_type.h" +#include "chromeos/ui/base/window_pin_type.h" #include "base/notreached.h" -namespace ash { +namespace chromeos { std::ostream& operator<<(std::ostream& out, WindowPinType pin_type) { switch (pin_type) { @@ -22,4 +22,4 @@ return out; } -} // namespace ash +} // namespace chromeos
diff --git a/ash/public/cpp/window_pin_type.h b/chromeos/ui/base/window_pin_type.h similarity index 73% rename from ash/public/cpp/window_pin_type.h rename to chromeos/ui/base/window_pin_type.h index 3308bb5..5246186 100644 --- a/ash/public/cpp/window_pin_type.h +++ b/chromeos/ui/base/window_pin_type.h
@@ -7,9 +7,9 @@ #include <ostream> -#include "ash/public/cpp/ash_public_export.h" +#include "base/component_export.h" -namespace ash { +namespace chromeos { // The window's pin type enum. enum class WindowPinType { @@ -23,9 +23,9 @@ kTrustedPinned, }; -ASH_PUBLIC_EXPORT std::ostream& operator<<(std::ostream& stream, - WindowPinType pin_type); +COMPONENT_EXPORT(CHROMEOS_UI_BASE) +std::ostream& operator<<(std::ostream& stream, WindowPinType pin_type); -} // namespace ash +} // namespace chromeos #endif // ASH_PUBLIC_CPP_WINDOW_PIN_TYPE_H_
diff --git a/chromeos/ui/base/window_properties.cc b/chromeos/ui/base/window_properties.cc index 4079eaa..d235c2c6 100644 --- a/chromeos/ui/base/window_properties.cc +++ b/chromeos/ui/base/window_properties.cc
@@ -4,11 +4,16 @@ #include "chromeos/ui/base/window_properties.h" +#include "chromeos/ui/base/window_pin_type.h" #include "chromeos/ui/base/window_state_type.h" #include "ui/aura/window.h" +DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(COMPONENT_EXPORT(CHROMEOS_UI_BASE), + chromeos::WindowPinType) + namespace chromeos { +DEFINE_UI_CLASS_PROPERTY_KEY(bool, kHideShelfWhenFullscreenKey, true) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kImmersiveImpliedByFullscreen, true) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kImmersiveIsActive, false) DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Rect, @@ -17,6 +22,10 @@ DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIsShowingInOverviewKey, false) +DEFINE_UI_CLASS_PROPERTY_KEY(WindowPinType, + kWindowPinTypeKey, + WindowPinType::kNone) + DEFINE_UI_CLASS_PROPERTY_KEY(WindowStateType, kWindowStateTypeKey, WindowStateType::kDefault)
diff --git a/chromeos/ui/base/window_properties.h b/chromeos/ui/base/window_properties.h index a38a183..34b77a1e 100644 --- a/chromeos/ui/base/window_properties.h +++ b/chromeos/ui/base/window_properties.h
@@ -20,11 +20,17 @@ namespace chromeos { enum class WindowStateType; +enum class WindowPinType; // Shell-specific window property keys for use by ash and lacros clients. // Alphabetical sort. +// Whether the shelf should be hidden when this window is put into fullscreen. +// Exposed because some windows want to explicitly opt-out of this. +COMPONENT_EXPORT(CHROMEOS_UI_BASE) +extern const aura::WindowProperty<bool>* const kHideShelfWhenFullscreenKey; + // Whether entering fullscreen means that a window should automatically enter // immersive mode. This is false for some client windows, such as Chrome Apps. COMPONENT_EXPORT(CHROMEOS_UI_BASE) @@ -48,6 +54,14 @@ COMPONENT_EXPORT(CHROMEOS_UI_BASE) extern const aura::WindowProperty<WindowStateType>* const kWindowStateTypeKey; +// A property key to store ash::WindowPinType for a window. +// When setting this property to PINNED or TRUSTED_PINNED, the window manager +// will try to fullscreen the window and pin it on the top of the screen. If the +// window manager failed to do it, the property will be restored to NONE. When +// setting this property to NONE, the window manager will restore the window. +COMPONENT_EXPORT(CHROMEOS_UI_BASE) +extern const aura::WindowProperty<WindowPinType>* const kWindowPinTypeKey; + // Alphabetical sort. } // namespace chromeos
diff --git a/components/autofill_assistant/browser/actions/action_delegate_util_unittest.cc b/components/autofill_assistant/browser/actions/action_delegate_util_unittest.cc index 03329aa..dd81657 100644 --- a/components/autofill_assistant/browser/actions/action_delegate_util_unittest.cc +++ b/components/autofill_assistant/browser/actions/action_delegate_util_unittest.cc
@@ -108,6 +108,36 @@ base::Unretained(this))); } +TEST_F(ActionDelegateUtilTest, + FindElementAndExecuteMultipleActionsAbortsOnError) { + InSequence sequence; + + Selector expected_selector({"#element"}); + auto expected_element = + test_util::MockFindElement(mock_action_delegate_, expected_selector); + + EXPECT_CALL(*this, MockIndexedAction(1, EqualsElement(expected_element), _)) + .WillOnce(RunOnceCallback<2>(OkClientStatus())); + EXPECT_CALL(*this, MockIndexedAction(2, EqualsElement(expected_element), _)) + .WillOnce(RunOnceCallback<2>(ClientStatus(UNEXPECTED_JS_ERROR))); + EXPECT_CALL(*this, MockIndexedAction(3, EqualsElement(expected_element), _)) + .Times(0); + EXPECT_CALL(*this, MockDone(EqualsStatus(ClientStatus(UNEXPECTED_JS_ERROR)))); + + auto actions = std::make_unique<ElementActionVector>(); + actions->emplace_back(base::BindOnce( + &ActionDelegateUtilTest::MockIndexedAction, base::Unretained(this), 1)); + actions->emplace_back(base::BindOnce( + &ActionDelegateUtilTest::MockIndexedAction, base::Unretained(this), 2)); + actions->emplace_back(base::BindOnce( + &ActionDelegateUtilTest::MockIndexedAction, base::Unretained(this), 3)); + + FindElementAndPerformAll(&mock_action_delegate_, expected_selector, + std::move(actions), + base::BindOnce(&ActionDelegateUtilTest::MockDone, + base::Unretained(this))); +} + TEST_F(ActionDelegateUtilTest, ActionDelegateDeletedDuringExecution) { InSequence sequence;
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index fea598f..07abf79 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -650,6 +650,9 @@ // More information included for |SetFormFieldValueProto| related errors. optional SetFormFieldErrorInfoProto form_field_error_info = 4; + + // Additional information from the |WebController|. + optional WebControllerErrorInfoProto web_controller_error_info = 5; } message NavigationInfoProto { @@ -761,6 +764,63 @@ optional int32 invalid_keypress_index = 1; } +// Message to report errors related to WebController execution. +message WebControllerErrorInfoProto { + enum WebAction { + UNSPECIFIED_WEB_ACTION = 0; + + // Scroll an element into view by centering it on the page. This uses + // native JS functionality. + SCROLL_INTO_VIEW = 1; + + // Waiting for the document ready state to be interactive. + WAIT_FOR_DOCUMENT_TO_BECOME_INTERACTIVE = 2; + + // Send a click or tap event to an element. + CLICK_OR_TAP_ELEMENT = 3; + + // Select an option from an HTML dropdown. + SELECT_OPTION = 4; + + // Set the element's style to be highlighted by adding a BoxShadow to the + // element. + HIGHLIGHT_ELEMENT = 5; + + // Scroll the element into view with padding. This does not use native JS + // functionality but calculates the scrolling manually. + SCROLL_INTO_VIEW_WITH_PADDING = 6; + + // Get the |value| attribute of an element. + GET_FIELD_VALUE = 7; + + // Get any attribute of an element. + GET_STRING_ATTRIBUTE = 8; + + // Select an element's value. This does only work for text elements. + SELECT_FIELD_VALUE = 9; + + // Set the |value| attribute of an element. + SET_VALUE_ATTRIBUTE = 10; + + // Set any attribute of an element. + SET_ATTRIBUTE = 11; + + // Send a series of keystroke inputs. This requires an element to have + // focus to receive them. + SEND_KEYBOARD_INPUT = 12; + + // Get the outer HTML of an element. + GET_OUTER_HTML = 13; + + // Get the tag of an element. + GET_ELEMENT_TAG = 14; + } + + // The web-action that failed. This is usually a step in an execution chain + // for an action. + optional WebAction failed_web_action = 1; +} + // The pseudo type values come from // https://chromedevtools.github.io/devtools-protocol/tot/DOM#type-PseudoType. enum PseudoType {
diff --git a/components/autofill_assistant/browser/web/web_controller.cc b/components/autofill_assistant/browser/web/web_controller.cc index f6e357d..c3e63ca 100644 --- a/components/autofill_assistant/browser/web/web_controller.cc +++ b/components/autofill_assistant/browser/web/web_controller.cc
@@ -259,6 +259,32 @@ std::move(callback).Run(status, static_cast<DocumentReadyState>(ready_state)); } +void DecorateWebControllerStatus( + WebControllerErrorInfoProto::WebAction web_action, + base::OnceCallback<void(const ClientStatus&)> callback, + const ClientStatus& status) { + ClientStatus copy = status; + if (!status.ok()) { + VLOG(1) << web_action << " failed with status: " << status; + FillWebControllerErrorInfo(web_action, ©); + } + std::move(callback).Run(copy); +} + +template <typename T> +void DecorateControllerStatusWithValue( + WebControllerErrorInfoProto::WebAction web_action, + base::OnceCallback<void(const ClientStatus&, const T&)> callback, + const ClientStatus& status, + const T& result) { + ClientStatus copy = status; + if (!status.ok()) { + VLOG(1) << web_action << " failed with status: " << status; + FillWebControllerErrorInfo(web_action, ©); + } + std::move(callback).Run(copy, result); +} + } // namespace // static @@ -334,8 +360,11 @@ .SetReturnByValue(true) .Build(), element.node_frame_id, - base::BindOnce(&WebController::OnJavaScriptResult, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + base::BindOnce( + &WebController::OnJavaScriptResult, weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&DecorateWebControllerStatus, + WebControllerErrorInfoProto::SCROLL_INTO_VIEW, + std::move(callback)))); } void WebController::WaitForDocumentToBecomeInteractive( @@ -348,11 +377,65 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } +void WebController::InternalWaitForDocumentToBecomeInteractive( + int remaining_rounds, + const std::string& object_id, + const std::string& node_frame_id, + base::OnceCallback<void(bool)> callback) { + devtools_client_->GetRuntime()->CallFunctionOn( + runtime::CallFunctionOnParams::Builder() + .SetObjectId(object_id) + .SetFunctionDeclaration(std::string(kIsDocumentReadyForInteract)) + .SetReturnByValue(true) + .Build(), + node_frame_id, + base::BindOnce( + &WebController::OnInternalWaitForDocumentToBecomeInteractive, + weak_ptr_factory_.GetWeakPtr(), remaining_rounds, object_id, + node_frame_id, std::move(callback))); +} + +void WebController::OnInternalWaitForDocumentToBecomeInteractive( + int remaining_rounds, + const std::string& object_id, + const std::string& node_frame_id, + base::OnceCallback<void(bool)> callback, + const DevtoolsClient::ReplyStatus& reply_status, + std::unique_ptr<runtime::CallFunctionOnResult> result) { + ClientStatus status = + CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__); + if (!status.ok() || remaining_rounds <= 0) { + VLOG(1) << __func__ + << " Failed to wait for the document to become interactive with " + "remaining_rounds: " + << remaining_rounds; + std::move(callback).Run(false); + return; + } + + bool ready; + if (SafeGetBool(result->GetResult(), &ready) && ready) { + std::move(callback).Run(true); + return; + } + + content::GetUIThreadTaskRunner({})->PostDelayedTask( + FROM_HERE, + base::BindOnce(&WebController::InternalWaitForDocumentToBecomeInteractive, + weak_ptr_factory_.GetWeakPtr(), --remaining_rounds, + object_id, node_frame_id, std::move(callback)), + settings_->document_ready_check_interval); +} + void WebController::OnWaitForDocumentToBecomeInteractive( base::OnceCallback<void(const ClientStatus&)> callback, bool result) { if (!result) { - std::move(callback).Run(ClientStatus(TIMED_OUT)); + ClientStatus error_status(TIMED_OUT); + FillWebControllerErrorInfo( + WebControllerErrorInfoProto::WAIT_FOR_DOCUMENT_TO_BECOME_INTERACTIVE, + &error_status); + std::move(callback).Run(error_status); return; } std::move(callback).Run(OkClientStatus()); @@ -375,9 +458,11 @@ .SetFunctionDeclaration(kClickElement) .Build(), element.node_frame_id, - base::BindOnce(&WebController::OnJavaScriptResult, - weak_ptr_factory_.GetWeakPtr(), - std::move(wrapped_callback))); + base::BindOnce( + &WebController::OnJavaScriptResult, weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&DecorateWebControllerStatus, + WebControllerErrorInfoProto::CLICK_OR_TAP_ELEMENT, + std::move(wrapped_callback)))); return; } @@ -388,9 +473,13 @@ pending_workers_.emplace_back(std::move(getter)); ptr->Start( element.container_frame_host, element.object_id, - base::BindOnce(&WebController::TapOrClickOnCoordinates, - weak_ptr_factory_.GetWeakPtr(), ptr, element.node_frame_id, - click_type, std::move(wrapped_callback))); + base::BindOnce( + &WebController::TapOrClickOnCoordinates, + weak_ptr_factory_.GetWeakPtr(), ptr, element.node_frame_id, + click_type, + base::BindOnce(&DecorateWebControllerStatus, + WebControllerErrorInfoProto::CLICK_OR_TAP_ELEMENT, + std::move(wrapped_callback)))); } void WebController::TapOrClickOnCoordinates( @@ -849,7 +938,10 @@ .Build(), element.node_frame_id, base::BindOnce(&WebController::OnSelectOption, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&DecorateWebControllerStatus, + WebControllerErrorInfoProto::SELECT_OPTION, + std::move(callback)))); } void WebController::OnSelectOption( @@ -891,8 +983,11 @@ .SetReturnByValue(true) .Build(), element.node_frame_id, - base::BindOnce(&WebController::OnJavaScriptResult, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + base::BindOnce( + &WebController::OnJavaScriptResult, weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&DecorateWebControllerStatus, + WebControllerErrorInfoProto::HIGHLIGHT_ELEMENT, + std::move(callback)))); } void WebController::FocusElement( @@ -911,8 +1006,12 @@ .SetReturnByValue(true) .Build(), element.node_frame_id, - base::BindOnce(&WebController::OnJavaScriptResult, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + base::BindOnce( + &WebController::OnJavaScriptResult, weak_ptr_factory_.GetWeakPtr(), + base::BindOnce( + &DecorateWebControllerStatus, + WebControllerErrorInfoProto::SCROLL_INTO_VIEW_WITH_PADDING, + std::move(callback)))); } void WebController::GetFieldValue( @@ -942,8 +1041,12 @@ .SetReturnByValue(true) .Build(), element_result->node_frame_id, - base::BindOnce(&WebController::OnJavaScriptResultForString, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + base::BindOnce( + &WebController::OnJavaScriptResultForString, + weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&DecorateControllerStatusWithValue<std::string>, + WebControllerErrorInfoProto::GET_FIELD_VALUE, + std::move(callback)))); } void WebController::GetStringAttribute( @@ -955,7 +1058,10 @@ << "]"; if (attributes.empty()) { - std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__), ""); + ClientStatus error_status = UnexpectedErrorStatus(__FILE__, __LINE__); + FillWebControllerErrorInfo( + WebControllerErrorInfoProto::GET_STRING_ATTRIBUTE, &error_status); + std::move(callback).Run(error_status, ""); return; } base::Value::ListStorage attribute_values; @@ -973,8 +1079,12 @@ .SetReturnByValue(true) .Build(), element.node_frame_id, - base::BindOnce(&WebController::OnJavaScriptResultForString, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + base::BindOnce( + &WebController::OnJavaScriptResultForString, + weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&DecorateControllerStatusWithValue<std::string>, + WebControllerErrorInfoProto::GET_STRING_ATTRIBUTE, + std::move(callback)))); } void WebController::SelectFieldValue( @@ -986,8 +1096,93 @@ .SetFunctionDeclaration(std::string(kSelectFieldValue)) .Build(), element.node_frame_id, + base::BindOnce( + &WebController::OnJavaScriptResult, weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&DecorateWebControllerStatus, + WebControllerErrorInfoProto::SELECT_FIELD_VALUE, + std::move(callback)))); +} + +void WebController::SetValueAttribute( + const ElementFinder::Result& element, + const std::string& value, + base::OnceCallback<void(const ClientStatus&)> callback) { + std::vector<std::unique_ptr<runtime::CallArgument>> argument; + AddRuntimeCallArgument(value, &argument); + devtools_client_->GetRuntime()->CallFunctionOn( + runtime::CallFunctionOnParams::Builder() + .SetObjectId(element.object_id) + .SetArguments(std::move(argument)) + .SetFunctionDeclaration(std::string(kSetValueAttributeScript)) + .Build(), + element.node_frame_id, + base::BindOnce( + &WebController::OnJavaScriptResult, weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&DecorateWebControllerStatus, + WebControllerErrorInfoProto::SET_VALUE_ATTRIBUTE, + std::move(callback)))); +} + +void WebController::SetAttribute( + const ElementFinder::Result& element, + const std::vector<std::string>& attributes, + const std::string& value, + base::OnceCallback<void(const ClientStatus&)> callback) { + DVLOG(3) << __func__ << " attributes=[" << base::JoinString(attributes, ",") + << "], value=" << value; + + if (attributes.empty()) { + ClientStatus error_status = UnexpectedErrorStatus(__FILE__, __LINE__); + FillWebControllerErrorInfo(WebControllerErrorInfoProto::SET_ATTRIBUTE, + &error_status); + std::move(callback).Run(error_status); + return; + } + base::Value::ListStorage attribute_values; + for (const std::string& attribute : attributes) { + attribute_values.emplace_back(base::Value(attribute)); + } + + std::vector<std::unique_ptr<runtime::CallArgument>> arguments; + AddRuntimeCallArgument(attribute_values, &arguments); + AddRuntimeCallArgument(value, &arguments); + devtools_client_->GetRuntime()->CallFunctionOn( + runtime::CallFunctionOnParams::Builder() + .SetObjectId(element.object_id) + .SetArguments(std::move(arguments)) + .SetFunctionDeclaration(std::string(kSetAttributeScript)) + .Build(), + element.node_frame_id, base::BindOnce(&WebController::OnJavaScriptResult, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&DecorateWebControllerStatus, + WebControllerErrorInfoProto::SET_ATTRIBUTE, + std::move(callback)))); +} + +void WebController::SendKeyboardInput( + const ElementFinder::Result& element, + const std::vector<UChar32>& codepoints, + const int delay_in_millisecond, + base::OnceCallback<void(const ClientStatus&)> callback) { + if (VLOG_IS_ON(3)) { + std::string input_str; + if (!UnicodeToUTF8(codepoints, &input_str)) { + input_str.assign("<invalid input>"); + } +#ifdef NDEBUG + VLOG(3) << __func__ << " input=(redacted)"; +#else + DVLOG(3) << __func__ << " input=" << input_str; +#endif + } + + DispatchKeyboardTextDownEvent( + element.node_frame_id, codepoints, 0, + /* delay= */ false, delay_in_millisecond, + base::BindOnce(&DecorateWebControllerStatus, + WebControllerErrorInfoProto::SEND_KEYBOARD_INPUT, + std::move(callback))); } void WebController::DispatchKeyboardTextDownEvent( @@ -1073,76 +1268,6 @@ return params; } -void WebController::SetValueAttribute( - const ElementFinder::Result& element, - const std::string& value, - base::OnceCallback<void(const ClientStatus&)> callback) { - std::vector<std::unique_ptr<runtime::CallArgument>> argument; - AddRuntimeCallArgument(value, &argument); - devtools_client_->GetRuntime()->CallFunctionOn( - runtime::CallFunctionOnParams::Builder() - .SetObjectId(element.object_id) - .SetArguments(std::move(argument)) - .SetFunctionDeclaration(std::string(kSetValueAttributeScript)) - .Build(), - element.node_frame_id, - base::BindOnce(&WebController::OnJavaScriptResult, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); -} - -void WebController::SetAttribute( - const ElementFinder::Result& element, - const std::vector<std::string>& attributes, - const std::string& value, - base::OnceCallback<void(const ClientStatus&)> callback) { - DVLOG(3) << __func__ << " attributes=[" << base::JoinString(attributes, ",") - << "], value=" << value; - - if (attributes.empty()) { - std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__)); - return; - } - base::Value::ListStorage attribute_values; - for (const std::string& attribute : attributes) { - attribute_values.emplace_back(base::Value(attribute)); - } - - std::vector<std::unique_ptr<runtime::CallArgument>> arguments; - AddRuntimeCallArgument(attribute_values, &arguments); - AddRuntimeCallArgument(value, &arguments); - devtools_client_->GetRuntime()->CallFunctionOn( - runtime::CallFunctionOnParams::Builder() - .SetObjectId(element.object_id) - .SetArguments(std::move(arguments)) - .SetFunctionDeclaration(std::string(kSetAttributeScript)) - .Build(), - element.node_frame_id, - base::BindOnce(&WebController::OnJavaScriptResult, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); -} - -void WebController::SendKeyboardInput( - const ElementFinder::Result& element, - const std::vector<UChar32>& codepoints, - const int delay_in_millisecond, - base::OnceCallback<void(const ClientStatus&)> callback) { - if (VLOG_IS_ON(3)) { - std::string input_str; - if (!UnicodeToUTF8(codepoints, &input_str)) { - input_str.assign("<invalid input>"); - } -#ifdef NDEBUG - VLOG(3) << __func__ << " input=(redacted)"; -#else - DVLOG(3) << __func__ << " input=" << input_str; -#endif - } - - DispatchKeyboardTextDownEvent(element.node_frame_id, codepoints, 0, - /* delay= */ false, delay_in_millisecond, - std::move(callback)); -} - void WebController::GetVisualViewport( base::OnceCallback<void(const ClientStatus&, const RectF&)> callback) { devtools_client_->GetRuntime()->Evaluate( @@ -1237,8 +1362,12 @@ .SetReturnByValue(true) .Build(), element.node_frame_id, - base::BindOnce(&WebController::OnJavaScriptResultForString, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + base::BindOnce( + &WebController::OnJavaScriptResultForString, + weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&DecorateControllerStatusWithValue<std::string>, + WebControllerErrorInfoProto::GET_OUTER_HTML, + std::move(callback)))); } void WebController::GetElementTag( @@ -1252,58 +1381,12 @@ .SetReturnByValue(true) .Build(), element.node_frame_id, - base::BindOnce(&WebController::OnJavaScriptResultForString, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); -} - -void WebController::InternalWaitForDocumentToBecomeInteractive( - int remaining_rounds, - const std::string& object_id, - const std::string& node_frame_id, - base::OnceCallback<void(bool)> callback) { - devtools_client_->GetRuntime()->CallFunctionOn( - runtime::CallFunctionOnParams::Builder() - .SetObjectId(object_id) - .SetFunctionDeclaration(std::string(kIsDocumentReadyForInteract)) - .SetReturnByValue(true) - .Build(), - node_frame_id, base::BindOnce( - &WebController::OnInternalWaitForDocumentToBecomeInteractive, - weak_ptr_factory_.GetWeakPtr(), remaining_rounds, object_id, - node_frame_id, std::move(callback))); -} - -void WebController::OnInternalWaitForDocumentToBecomeInteractive( - int remaining_rounds, - const std::string& object_id, - const std::string& node_frame_id, - base::OnceCallback<void(bool)> callback, - const DevtoolsClient::ReplyStatus& reply_status, - std::unique_ptr<runtime::CallFunctionOnResult> result) { - ClientStatus status = - CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__); - if (!status.ok() || remaining_rounds <= 0) { - VLOG(1) << __func__ - << " Failed to wait for the document to become interactive with " - "remaining_rounds: " - << remaining_rounds; - std::move(callback).Run(false); - return; - } - - bool ready; - if (SafeGetBool(result->GetResult(), &ready) && ready) { - std::move(callback).Run(true); - return; - } - - content::GetUIThreadTaskRunner({})->PostDelayedTask( - FROM_HERE, - base::BindOnce(&WebController::InternalWaitForDocumentToBecomeInteractive, - weak_ptr_factory_.GetWeakPtr(), --remaining_rounds, - object_id, node_frame_id, std::move(callback)), - settings_->document_ready_check_interval); + &WebController::OnJavaScriptResultForString, + weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&DecorateControllerStatusWithValue<std::string>, + WebControllerErrorInfoProto::GET_ELEMENT_TAG, + std::move(callback)))); } WebController::ScopedAssistantActionStateRunning::
diff --git a/components/autofill_assistant/browser/web/web_controller_util.cc b/components/autofill_assistant/browser/web/web_controller_util.cc index aadf965e..d25d628 100644 --- a/components/autofill_assistant/browser/web/web_controller_util.cc +++ b/components/autofill_assistant/browser/web/web_controller_util.cc
@@ -5,6 +5,7 @@ #include "components/autofill_assistant/browser/web/web_controller_util.h" #include "components/autofill_assistant/browser/devtools/devtools/domains/types_runtime.h" +#include "components/autofill_assistant/browser/service.pb.h" namespace autofill_assistant { @@ -56,6 +57,14 @@ return status; } +void FillWebControllerErrorInfo( + WebControllerErrorInfoProto::WebAction failed_web_action, + ClientStatus* status) { + status->mutable_details() + ->mutable_web_controller_error_info() + ->set_failed_web_action(failed_web_action); +} + bool SafeGetObjectId(const runtime::RemoteObject* result, std::string* out) { if (result && result->HasObjectId()) { *out = result->GetObjectId();
diff --git a/components/autofill_assistant/browser/web/web_controller_util.h b/components/autofill_assistant/browser/web/web_controller_util.h index dda9a43..c81437b 100644 --- a/components/autofill_assistant/browser/web/web_controller_util.h +++ b/components/autofill_assistant/browser/web/web_controller_util.h
@@ -10,6 +10,7 @@ #include "components/autofill_assistant/browser/client_status.h" #include "components/autofill_assistant/browser/devtools/devtools/domains/types_runtime.h" #include "components/autofill_assistant/browser/devtools/devtools_client.h" +#include "components/autofill_assistant/browser/service.pb.h" namespace autofill_assistant { @@ -57,6 +58,11 @@ // Fills a ClientStatus with appropriate details for a Chrome Autofill error. ClientStatus FillAutofillErrorStatus(ClientStatus status); +// Fills a ClientStatus with appropriate details from the +void FillWebControllerErrorInfo( + WebControllerErrorInfoProto::WebAction failed_web_action, + ClientStatus* status); + // Safely gets an object id from a RemoteObject bool SafeGetObjectId(const runtime::RemoteObject* result, std::string* out);
diff --git a/components/exo/BUILD.gn b/components/exo/BUILD.gn index 4a22a91..3143ccb 100644 --- a/components/exo/BUILD.gn +++ b/components/exo/BUILD.gn
@@ -307,6 +307,7 @@ "//ash/keyboard/ui", "//ash/public/cpp", "//chromeos/constants", + "//chromeos/ui/base", "//chromeos/ui/frame", "//ui/base:test_support", "//ui/base/cursor/mojom:cursor_type",
diff --git a/components/exo/client_controlled_shell_surface.cc b/components/exo/client_controlled_shell_surface.cc index 99bbca0..3399e59 100644 --- a/components/exo/client_controlled_shell_surface.cc +++ b/components/exo/client_controlled_shell_surface.cc
@@ -15,7 +15,6 @@ #include "ash/public/cpp/rounded_corner_decorator.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/window_backdrop.h" -#include "ash/public/cpp/window_pin_type.h" #include "ash/public/cpp/window_properties.h" #include "ash/root_window_controller.h" #include "ash/shell.h" @@ -36,6 +35,8 @@ #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/traced_value.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/base/window_state_type.h" #include "chromeos/ui/frame/caption_buttons/caption_button_model.h" #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" @@ -324,7 +325,7 @@ int container, bool default_scale_cancellation) : ShellSurfaceBase(surface, gfx::Point(), true, can_minimize, container), - current_pin_(ash::WindowPinType::kNone), + current_pin_(chromeos::WindowPinType::kNone), use_default_scale_cancellation_(default_scale_cancellation) {} ClientControlledShellSurface::~ClientControlledShellSurface() { @@ -335,8 +336,8 @@ if (client_controlled_state_) client_controlled_state_->ResetDelegate(); wide_frame_.reset(); - if (current_pin_ != ash::WindowPinType::kNone) - SetPinned(ash::WindowPinType::kNone); + if (current_pin_ != chromeos::WindowPinType::kNone) + SetPinned(chromeos::WindowPinType::kNone); } void ClientControlledShellSurface::SetBounds(int64_t display_id, @@ -419,14 +420,14 @@ pending_window_state_ = chromeos::WindowStateType::kPip; } -void ClientControlledShellSurface::SetPinned(ash::WindowPinType type) { +void ClientControlledShellSurface::SetPinned(chromeos::WindowPinType type) { TRACE_EVENT1("exo", "ClientControlledShellSurface::SetPinned", "type", static_cast<int>(type)); if (!widget_) CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL); - widget_->GetNativeWindow()->SetProperty(ash::kWindowPinTypeKey, type); + widget_->GetNativeWindow()->SetProperty(chromeos::kWindowPinTypeKey, type); current_pin_ = type; }
diff --git a/components/exo/client_controlled_shell_surface.h b/components/exo/client_controlled_shell_surface.h index 3dcb07e..5141d59 100644 --- a/components/exo/client_controlled_shell_surface.h +++ b/components/exo/client_controlled_shell_surface.h
@@ -141,7 +141,7 @@ // Pin/unpin the surface. Pinned surface cannot be switched to // other windows unless its explicitly unpinned. - void SetPinned(ash::WindowPinType type); + void SetPinned(chromeos::WindowPinType type); // Sets the surface to be on top of all other windows. void SetAlwaysOnTop(bool always_on_top); @@ -350,7 +350,7 @@ SurfaceFrameType pending_frame_type_ = SurfaceFrameType::NONE; - ash::WindowPinType current_pin_; + chromeos::WindowPinType current_pin_; bool can_maximize_ = true;
diff --git a/components/exo/client_controlled_shell_surface_unittest.cc b/components/exo/client_controlled_shell_surface_unittest.cc index aafbbd3..11dde36 100644 --- a/components/exo/client_controlled_shell_surface_unittest.cc +++ b/components/exo/client_controlled_shell_surface_unittest.cc
@@ -9,8 +9,6 @@ #include "ash/frame/non_client_frame_view_ash.h" #include "ash/frame/wide_frame_view.h" #include "ash/public/cpp/test/shell_test_api.h" -#include "ash/public/cpp/window_pin_type.h" -#include "ash/public/cpp/window_properties.h" #include "ash/shell.h" #include "ash/system/unified/unified_system_tray.h" #include "ash/wm/drag_window_resizer.h" @@ -31,6 +29,8 @@ #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "cc/paint/display_item_list.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/frame/caption_buttons/caption_button_model.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" #include "components/exo/buffer.h" @@ -74,10 +74,10 @@ } bool IsWidgetPinned(views::Widget* widget) { - ash::WindowPinType type = - widget->GetNativeWindow()->GetProperty(ash::kWindowPinTypeKey); - return type == ash::WindowPinType::kPinned || - type == ash::WindowPinType::kTrustedPinned; + chromeos::WindowPinType type = + widget->GetNativeWindow()->GetProperty(chromeos::kWindowPinTypeKey); + return type == chromeos::WindowPinType::kPinned || + type == chromeos::WindowPinType::kTrustedPinned; } int GetShadowElevation(aura::Window* window) { @@ -123,16 +123,16 @@ auto shell_surface( exo_test_helper()->CreateClientControlledShellSurface(surface.get())); - shell_surface->SetPinned(ash::WindowPinType::kTrustedPinned); + shell_surface->SetPinned(chromeos::WindowPinType::kTrustedPinned); EXPECT_TRUE(IsWidgetPinned(shell_surface->GetWidget())); - shell_surface->SetPinned(ash::WindowPinType::kNone); + shell_surface->SetPinned(chromeos::WindowPinType::kNone); EXPECT_FALSE(IsWidgetPinned(shell_surface->GetWidget())); - shell_surface->SetPinned(ash::WindowPinType::kPinned); + shell_surface->SetPinned(chromeos::WindowPinType::kPinned); EXPECT_TRUE(IsWidgetPinned(shell_surface->GetWidget())); - shell_surface->SetPinned(ash::WindowPinType::kNone); + shell_surface->SetPinned(chromeos::WindowPinType::kNone); EXPECT_FALSE(IsWidgetPinned(shell_surface->GetWidget())); }
diff --git a/components/exo/display_unittest.cc b/components/exo/display_unittest.cc index b8fc458..d3696c20 100644 --- a/components/exo/display_unittest.cc +++ b/components/exo/display_unittest.cc
@@ -4,8 +4,8 @@ #include "components/exo/display.h" #include "ash/public/cpp/shell_window_ids.h" -#include "ash/public/cpp/window_pin_type.h" #include "ash/wm/desks/desks_util.h" +#include "chromeos/ui/base/window_pin_type.h" #include "components/exo/buffer.h" #include "components/exo/client_controlled_shell_surface.h" #include "components/exo/data_device.h" @@ -268,7 +268,7 @@ // This should not crash shell_surface->SetAlwaysOnTop(true); - shell_surface->SetPinned(ash::WindowPinType::kPinned); + shell_surface->SetPinned(chromeos::WindowPinType::kPinned); } } // namespace
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc index 40b08f2..797df9baef 100644 --- a/components/exo/shell_surface_base.cc +++ b/components/exo/shell_surface_base.cc
@@ -9,7 +9,6 @@ #include "ash/frame/non_client_frame_view_ash.h" #include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/shell_window_ids.h" -#include "ash/public/cpp/window_pin_type.h" #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" #include "ash/wm/desks/desks_util.h" @@ -27,6 +26,7 @@ #include "cc/trees/layer_tree_frame_sink.h" #include "chromeos/crosapi/cpp/crosapi_constants.h" #include "chromeos/ui/base//window_properties.h" +#include "chromeos/ui/base/window_pin_type.h" #include "chromeos/ui/base/window_state_type.h" #include "components/exo/shell_surface_util.h" #include "components/exo/surface.h"
diff --git a/components/exo/shell_surface_util.cc b/components/exo/shell_surface_util.cc index 271c9e0..0541638 100644 --- a/components/exo/shell_surface_util.cc +++ b/components/exo/shell_surface_util.cc
@@ -23,7 +23,6 @@ #include "ui/wm/core/window_util.h" #if defined(OS_CHROMEOS) -#include "ash/public/cpp/window_properties.h" #include "chromeos/ui/base/window_properties.h" #endif // defined(OS_CHROMEOS) @@ -123,7 +122,7 @@ // Ensure the shelf is fully hidden in plain fullscreen, but shown // (auto-hides based on mouse movement) when in immersive fullscreen. - window->SetProperty(ash::kHideShelfWhenFullscreenKey, !value); + window->SetProperty(chromeos::kHideShelfWhenFullscreenKey, !value); #endif // defined(OS_CHROMEOS) }
diff --git a/components/exo/wayland/zcr_remote_shell.cc b/components/exo/wayland/zcr_remote_shell.cc index 999518f3..76f8cc6 100644 --- a/components/exo/wayland/zcr_remote_shell.cc +++ b/components/exo/wayland/zcr_remote_shell.cc
@@ -10,7 +10,6 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/tablet_mode_observer.h" -#include "ash/public/cpp/window_pin_type.h" #include "ash/public/cpp/window_properties.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_layout_manager.h" @@ -24,6 +23,7 @@ #include "base/numerics/safe_conversions.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "chromeos/ui/base/window_pin_type.h" #include "components/exo/client_controlled_shell_surface.h" #include "components/exo/display.h" #include "components/exo/input_method_surface.h" @@ -318,13 +318,13 @@ wl_resource* resource, int32_t trusted) { GetUserDataAs<ClientControlledShellSurface>(resource)->SetPinned( - trusted ? ash::WindowPinType::kTrustedPinned - : ash::WindowPinType::kPinned); + trusted ? chromeos::WindowPinType::kTrustedPinned + : chromeos::WindowPinType::kPinned); } void remote_surface_unpin(wl_client* client, wl_resource* resource) { GetUserDataAs<ClientControlledShellSurface>(resource)->SetPinned( - ash::WindowPinType::kNone); + chromeos::WindowPinType::kNone); } void remote_surface_set_system_modal(wl_client* client, wl_resource* resource) {
diff --git a/components/feature_engagement/internal/BUILD.gn b/components/feature_engagement/internal/BUILD.gn index b1320da..9894de87 100644 --- a/components/feature_engagement/internal/BUILD.gn +++ b/components/feature_engagement/internal/BUILD.gn
@@ -58,6 +58,8 @@ "single_invalid_configuration.h", "stats.cc", "stats.h", + "switches.cc", + "switches.h", "system_time_provider.cc", "system_time_provider.h", "time_provider.h", @@ -78,9 +80,14 @@ sources += [ "android/tracker_impl_android.cc", "android/tracker_impl_android.h", + "android/wrapping_test_tracker.cc", + "android/wrapping_test_tracker.h", ] - deps += [ ":jni_headers" ] + deps += [ + ":jni_headers", + "//components/feature_engagement/public:jni_headers", + ] } }
diff --git a/components/feature_engagement/internal/android/java/src/org/chromium/components/feature_engagement/internal/TrackerImpl.java b/components/feature_engagement/internal/android/java/src/org/chromium/components/feature_engagement/internal/TrackerImpl.java index 2b2047a..934753f1 100644 --- a/components/feature_engagement/internal/android/java/src/org/chromium/components/feature_engagement/internal/TrackerImpl.java +++ b/components/feature_engagement/internal/android/java/src/org/chromium/components/feature_engagement/internal/TrackerImpl.java
@@ -128,6 +128,12 @@ TrackerImplJni.get().addOnInitializedCallback(mNativePtr, TrackerImpl.this, callback); } + @Override + public void injectTracker(Tracker tracker) { + assert mNativePtr != 0; + TrackerImplJni.get().injectTracker(mNativePtr, TrackerImpl.this, tracker); + } + @CalledByNative private void clearNativePtr() { mNativePtr = 0; @@ -155,6 +161,7 @@ boolean isInitialized(long nativeTrackerImplAndroid, TrackerImpl caller); void addOnInitializedCallback( long nativeTrackerImplAndroid, TrackerImpl caller, Callback<Boolean> callback); + void injectTracker(long nativeTrackerImplAndroid, TrackerImpl caller, Tracker tracker); void release(long nativeDisplayLockHandleAndroid); } }
diff --git a/components/feature_engagement/internal/android/tracker_impl_android.cc b/components/feature_engagement/internal/android/tracker_impl_android.cc index adf3ee4..bfc159b0 100644 --- a/components/feature_engagement/internal/android/tracker_impl_android.cc +++ b/components/feature_engagement/internal/android/tracker_impl_android.cc
@@ -13,9 +13,12 @@ #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" #include "base/bind.h" +#include "base/command_line.h" #include "base/feature_list.h" #include "base/memory/ptr_util.h" +#include "components/feature_engagement/internal/android/wrapping_test_tracker.h" #include "components/feature_engagement/internal/jni_headers/TrackerImpl_jni.h" +#include "components/feature_engagement/internal/switches.h" #include "components/feature_engagement/public/feature_list.h" #include "components/feature_engagement/public/tracker.h" @@ -175,6 +178,20 @@ base::android::ScopedJavaGlobalRef<jobject>(j_callback_obj))); } +void TrackerImplAndroid::InjectTracker( + JNIEnv* env, + const base::android::JavaRef<jobject>& jobj, + const base::android::JavaRef<jobject>& jtracker) { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (!command_line->HasSwitch(switches::kUseJavaProxyTracker)) { + NOTREACHED(); + return; + } + WrappingTestTracker* test_tracker_ = + static_cast<WrappingTestTracker*>(tracker_impl_); + test_tracker_->InjectTracker(jtracker); +} + DisplayLockHandleAndroid::DisplayLockHandleAndroid( std::unique_ptr<DisplayLockHandle> display_lock_handle) : display_lock_handle_(std::move(display_lock_handle)) {
diff --git a/components/feature_engagement/internal/android/tracker_impl_android.h b/components/feature_engagement/internal/android/tracker_impl_android.h index 7a028314..580c13dd 100644 --- a/components/feature_engagement/internal/android/tracker_impl_android.h +++ b/components/feature_engagement/internal/android/tracker_impl_android.h
@@ -102,6 +102,14 @@ const base::android::JavaRef<jobject>& jobj, const base::android::JavaParamRef<jobject>& j_callback_obj); + /** + * Injects a Java tracker for encapsulation. For further details, see + * WrappingTestTracker::InjectTracker. + */ + void InjectTracker(JNIEnv* env, + const base::android::JavaRef<jobject>& jobj, + const base::android::JavaRef<jobject>& jtracker); + private: // A map from the feature name to the base::Feature, to ensure that the Java // version of the API can use the string name. If base::Feature becomes a Java
diff --git a/components/feature_engagement/internal/android/wrapping_test_tracker.cc b/components/feature_engagement/internal/android/wrapping_test_tracker.cc new file mode 100644 index 0000000..27f5d0e --- /dev/null +++ b/components/feature_engagement/internal/android/wrapping_test_tracker.cc
@@ -0,0 +1,134 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/feature_engagement/internal/android/wrapping_test_tracker.h" + +#include <memory> +#include <utility> + +#include "base/android/jni_string.h" +#include "components/feature_engagement/internal/availability_model_impl.h" +#include "components/feature_engagement/internal/display_lock_controller_impl.h" +#include "components/feature_engagement/internal/editable_configuration.h" +#include "components/feature_engagement/internal/event_model_impl.h" +#include "components/feature_engagement/internal/feature_config_condition_validator.h" +#include "components/feature_engagement/internal/system_time_provider.h" +#include "components/feature_engagement/public/jni_headers/CppWrappedTestTracker_jni.h" + +namespace feature_engagement { + +WrappingTestTracker::WrappingTestTracker( + std::unique_ptr<EventModel> event_model, + std::unique_ptr<AvailabilityModel> availability_model, + std::unique_ptr<Configuration> configuration, + std::unique_ptr<DisplayLockController> display_lock_controller, + std::unique_ptr<ConditionValidator> condition_validator, + std::unique_ptr<TimeProvider> time_provider) + : TrackerImpl(std::move(event_model), + std::move(availability_model), + std::move(configuration), + std::make_unique<DisplayLockControllerImpl>(), + std::move(condition_validator), + std::move(time_provider)) {} + +WrappingTestTracker::~WrappingTestTracker() {} + +void WrappingTestTracker::InjectTracker( + const base::android::JavaRef<jobject>& jtracker) { + java_tracker_ = jtracker; +} + +void WrappingTestTracker::NotifyEvent(const std::string& event) { + if (!java_tracker_) { + TrackerImpl::NotifyEvent(event); + return; + } + + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::ScopedJavaLocalRef<jstring> jevent( + base::android::ConvertUTF8ToJavaString(env, event.c_str())); + Java_CppWrappedTestTracker_notifyEvent(base::android::AttachCurrentThread(), + java_tracker_, jevent); +} + +bool WrappingTestTracker::ShouldTriggerHelpUI(const base::Feature& feature) { + if (!java_tracker_) + return TrackerImpl::ShouldTriggerHelpUI(feature); + + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::ScopedJavaLocalRef<jstring> jfeature( + base::android::ConvertUTF8ToJavaString(env, feature.name)); + return Java_CppWrappedTestTracker_shouldTriggerHelpUI( + base::android::AttachCurrentThread(), java_tracker_, jfeature); +} + +bool WrappingTestTracker::WouldTriggerHelpUI( + const base::Feature& feature) const { + if (!java_tracker_) + return TrackerImpl::WouldTriggerHelpUI(feature); + + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::ScopedJavaLocalRef<jstring> jfeature( + base::android::ConvertUTF8ToJavaString(env, feature.name)); + return Java_CppWrappedTestTracker_wouldTriggerHelpUI( + base::android::AttachCurrentThread(), java_tracker_, jfeature); +} + +bool WrappingTestTracker::HasEverTriggered(const base::Feature& feature, + bool from_window) const { + if (!java_tracker_) + return TrackerImpl::HasEverTriggered(feature, from_window); + + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::ScopedJavaLocalRef<jstring> jfeature( + base::android::ConvertUTF8ToJavaString(env, feature.name)); + return Java_CppWrappedTestTracker_hasEverTriggered( + base::android::AttachCurrentThread(), java_tracker_, jfeature, + from_window); +} + +Tracker::TriggerState WrappingTestTracker::GetTriggerState( + const base::Feature& feature) const { + if (!java_tracker_) + return TrackerImpl::GetTriggerState(feature); + + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::ScopedJavaLocalRef<jstring> jfeature( + base::android::ConvertUTF8ToJavaString(env, feature.name)); + return static_cast<Tracker::TriggerState>( + Java_CppWrappedTestTracker_getTriggerState( + base::android::AttachCurrentThread(), java_tracker_, jfeature)); +} + +void WrappingTestTracker::Dismissed(const base::Feature& feature) { + if (!java_tracker_) { + TrackerImpl::Dismissed(feature); + return; + } + + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::ScopedJavaLocalRef<jstring> jfeature( + base::android::ConvertUTF8ToJavaString(env, feature.name)); + Java_CppWrappedTestTracker_dismissed(base::android::AttachCurrentThread(), + java_tracker_, jfeature); +} + +std::unique_ptr<DisplayLockHandle> WrappingTestTracker::AcquireDisplayLock() { + return TrackerImpl::AcquireDisplayLock(); +} + +bool WrappingTestTracker::IsInitialized() const { + if (!java_tracker_) + return TrackerImpl::IsInitialized(); + + return Java_CppWrappedTestTracker_isInitialized( + base::android::AttachCurrentThread(), java_tracker_); +} + +void WrappingTestTracker::AddOnInitializedCallback( + OnInitializedCallback callback) { + TrackerImpl::AddOnInitializedCallback(std::move(callback)); +} + +} // namespace feature_engagement
diff --git a/components/feature_engagement/internal/android/wrapping_test_tracker.h b/components/feature_engagement/internal/android/wrapping_test_tracker.h new file mode 100644 index 0000000..f8d8c7a --- /dev/null +++ b/components/feature_engagement/internal/android/wrapping_test_tracker.h
@@ -0,0 +1,73 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_FEATURE_ENGAGEMENT_INTERNAL_ANDROID_WRAPPING_TEST_TRACKER_H_ +#define COMPONENTS_FEATURE_ENGAGEMENT_INTERNAL_ANDROID_WRAPPING_TEST_TRACKER_H_ + +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/macros.h" +#include "build/build_config.h" +#include "components/feature_engagement/internal/tracker_impl.h" + +#if defined(OS_ANDROID) +#include "base/android/jni_android.h" +#endif // defined(OS_ANDROID) + +namespace feature_engagement { +class AvailabilityModel; +class Configuration; +class ConditionValidator; +class DisplayLockController; +class EventModel; +class TimeProvider; + +// This class is a thin wrapper around TrackerImpl and has two modes of +// operating. To start with, it does nothing but forward all calls to its base +// class implementation. However, at some point a Java test can inject a +// tracker, at +// which point this class will start to forward the calls to Java. See +// InjectTracker for details. +class WrappingTestTracker : public TrackerImpl { + public: + WrappingTestTracker( + std::unique_ptr<EventModel> event_model, + std::unique_ptr<AvailabilityModel> availability_model, + std::unique_ptr<Configuration> configuration, + std::unique_ptr<DisplayLockController> display_lock_controller, + std::unique_ptr<ConditionValidator> condition_validator, + std::unique_ptr<TimeProvider> time_provider); + ~WrappingTestTracker() override; + + // Injects a tracker from Java to proxy calls to. By default, all functions + // will be forwarded to the base class for processing until this function is + // called, at which point the proxying calls to Java starts. Note that not all + // functions are proxied to Java. Some are still handled by the base class. + // See .cc for details. + void InjectTracker(const base::android::JavaRef<jobject>& jtracker); + + // TrackerImpl: + + void NotifyEvent(const std::string& event) override; + bool ShouldTriggerHelpUI(const base::Feature& feature) override; + bool WouldTriggerHelpUI(const base::Feature& feature) const override; + bool HasEverTriggered(const base::Feature& feature, + bool from_window) const override; + TriggerState GetTriggerState(const base::Feature& feature) const override; + void Dismissed(const base::Feature& feature) override; + std::unique_ptr<DisplayLockHandle> AcquireDisplayLock() override; + bool IsInitialized() const override; + void AddOnInitializedCallback(OnInitializedCallback callback) override; + + private: + base::android::ScopedJavaGlobalRef<jobject> java_tracker_; + + DISALLOW_COPY_AND_ASSIGN(WrappingTestTracker); +}; + +} // namespace feature_engagement + +#endif // COMPONENTS_FEATURE_ENGAGEMENT_INTERNAL_ANDROID_WRAPPING_TEST_TRACKER_H_
diff --git a/components/feature_engagement/internal/switches.cc b/components/feature_engagement/internal/switches.cc new file mode 100644 index 0000000..5904db9 --- /dev/null +++ b/components/feature_engagement/internal/switches.cc
@@ -0,0 +1,16 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/feature_engagement/internal/switches.h" + +namespace feature_engagement { +namespace switches { + +// This switch causes TrackerImpl to be wrapped, so that functions can be +// proxied up into Java land, to facilitate end-to-end Java tests that exercise +// the feature engagement. +const char kUseJavaProxyTracker[] = "use-java-proxy-tracker"; + +} // namespace switches +} // namespace feature_engagement \ No newline at end of file
diff --git a/components/feature_engagement/internal/switches.h b/components/feature_engagement/internal/switches.h new file mode 100644 index 0000000..fe3509c --- /dev/null +++ b/components/feature_engagement/internal/switches.h
@@ -0,0 +1,16 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_FEATURE_ENGAGEMENT_INTERNAL_SWITCHES_H_ +#define COMPONENTS_FEATURE_ENGAGEMENT_INTERNAL_SWITCHES_H_ + +namespace feature_engagement { +namespace switches { + +extern const char kUseJavaProxyTracker[]; + +} // namespace switches +} // namespace feature_engagement + +#endif // COMPONENTS_FEATURE_ENGAGEMENT_INTERNAL_SWITCHES_H_
diff --git a/components/feature_engagement/internal/tracker_impl.cc b/components/feature_engagement/internal/tracker_impl.cc index 763bd31..59696fc0 100644 --- a/components/feature_engagement/internal/tracker_impl.cc +++ b/components/feature_engagement/internal/tracker_impl.cc
@@ -8,12 +8,14 @@ #include <utility> #include "base/bind.h" +#include "base/command_line.h" #include "base/feature_list.h" #include "base/files/file_path.h" #include "base/logging.h" #include "base/metrics/field_trial_params.h" #include "base/metrics/user_metrics.h" #include "base/threading/thread_task_runner_handle.h" +#include "build/build_config.h" #include "components/feature_engagement/internal/availability_model_impl.h" #include "components/feature_engagement/internal/chrome_variations_configuration.h" #include "components/feature_engagement/internal/display_lock_controller_impl.h" @@ -30,11 +32,16 @@ #include "components/feature_engagement/internal/persistent_event_store.h" #include "components/feature_engagement/internal/proto/availability.pb.h" #include "components/feature_engagement/internal/stats.h" +#include "components/feature_engagement/internal/switches.h" #include "components/feature_engagement/internal/system_time_provider.h" #include "components/feature_engagement/public/feature_constants.h" #include "components/feature_engagement/public/feature_list.h" #include "components/leveldb_proto/public/proto_database_provider.h" +#if defined(OS_ANDROID) +#include "components/feature_engagement/internal/android/wrapping_test_tracker.h" +#endif + namespace feature_engagement { namespace { @@ -133,6 +140,16 @@ auto availability_model = std::make_unique<AvailabilityModelImpl>( std::move(availability_store_loader)); +#if defined(OS_ANDROID) + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kUseJavaProxyTracker)) { + return new WrappingTestTracker( + std::move(event_model), std::move(availability_model), + std::move(configuration), std::make_unique<DisplayLockControllerImpl>(), + std::move(condition_validator), std::move(time_provider)); + } +#endif + return new TrackerImpl( std::move(event_model), std::move(availability_model), std::move(configuration), std::make_unique<DisplayLockControllerImpl>(),
diff --git a/components/feature_engagement/public/BUILD.gn b/components/feature_engagement/public/BUILD.gn index 090e8518..59b4cc5 100644 --- a/components/feature_engagement/public/BUILD.gn +++ b/components/feature_engagement/public/BUILD.gn
@@ -48,15 +48,18 @@ if (is_android) { android_library("public_java") { sources = [ + "android/java/src/org/chromium/components/feature_engagement/CppWrappedTestTracker.java", "android/java/src/org/chromium/components/feature_engagement/EventConstants.java", "android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java", "android/java/src/org/chromium/components/feature_engagement/Tracker.java", ] deps = [ + ":jni_headers", "//base:base_java", "//third_party/android_deps:androidx_annotation_annotation_java", ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] srcjar_deps = [ ":public_java_enums_srcjar" ] } @@ -66,4 +69,8 @@ sources = [ "tracker.h" ] } + + generate_jni("jni_headers") { + sources = [ "android/java/src/org/chromium/components/feature_engagement/CppWrappedTestTracker.java" ] + } }
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/CppWrappedTestTracker.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/CppWrappedTestTracker.java new file mode 100644 index 0000000..5e26fbf --- /dev/null +++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/CppWrappedTestTracker.java
@@ -0,0 +1,125 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.feature_engagement; + +import android.text.TextUtils; + +import androidx.annotation.CheckResult; +import androidx.annotation.Nullable; + +import org.chromium.base.Callback; +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; + +/** + * CppWrappedTestTracker is a Java implementation of a {@link Tracker} object that is + * encapsulated by a Tracker object in C++, which will proxy (most) calls over from C++ to + * Java. + * + * NOTE: For testing, most of the time this class is overkill and it suffices to create a test + * object that derives from Tracker and call TrackerFactory#setTrackerForTests on it. However, this + * will only replace the Tracker object on the Java side, and that object will never receive the + * notifyEvent calls that the actual tracker in C++ receives. So, if receiving events is important + * for your test, you may need {@link CppWrapperTestTracker}. + * + * Example usage in tests: + * + * mTracker = new CppWrappedTestTracker(FeatureConstants.YOU_FEATURE_HERE) { + * @Override + * public void notifyEvent(String event) { + * super.notifyEvent(event); + * // Validate that the right event was received. + * } + * }; + * TrackerFactory.getTrackerForProfile(profile).injectTracker(mTracker); + */ +@JNINamespace("feature_engagement") +public class CppWrappedTestTracker implements Tracker { + private String mOurFeature; + private boolean mWasDismissed; + private String mLastEvent; + + public CppWrappedTestTracker(String feature) { + mOurFeature = feature; + } + + public boolean wasDismissed() { + return mWasDismissed; + } + + public String getLastEvent() { + return mLastEvent; + } + + @CalledByNative + @Override + public void notifyEvent(String event) { + mLastEvent = event; + } + + @CheckResult + @CalledByNative + @Override + public boolean shouldTriggerHelpUI(String feature) { + return ourFeature(feature); + } + + @CalledByNative + @Override + public boolean wouldTriggerHelpUI(String feature) { + return ourFeature(feature); + } + + @CalledByNative + @Override + public boolean hasEverTriggered(String feature, boolean fromWindow) { + return true; + } + + @TriggerState + @CalledByNative + @Override + public int getTriggerState(String feature) { + return ourFeature(feature) ? TriggerState.HAS_NOT_BEEN_DISPLAYED + : TriggerState.HAS_BEEN_DISPLAYED; + } + + @CalledByNative + @Override + public void dismissed(String feature) { + if (ourFeature(feature)) { + mWasDismissed = true; + } + } + + @CheckResult + @Nullable + @Override + public DisplayLockHandle acquireDisplayLock() { + assert false : "This should only be called on a production tracker"; + return () -> {}; + } + + @CalledByNative + @Override + public boolean isInitialized() { + return true; + } + + @Override + public void addOnInitializedCallback(Callback<Boolean> callback) { + assert false : "This should only be called on a production tracker"; + callback.onResult(true); + } + + @Override + public final void injectTracker(Tracker tracker) { + assert false : "This should only be called on a production tracker"; + } + + private boolean ourFeature(String feature) { + return TextUtils.equals(mOurFeature, feature); + } +}
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java index 3fd1362..147c01c 100644 --- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java +++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java
@@ -202,6 +202,9 @@ /** Reengagement events. */ public static final String STARTED_FROM_MAIN_INTENT = "started_from_main_intent"; + /** PWA install events. */ + public static final String PWA_INSTALL_MENU_SELECTED = "pwa_install_menu_clicked"; + /** * Do not instantiate. */
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/Tracker.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/Tracker.java index 2af818ee..6e11417 100644 --- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/Tracker.java +++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/Tracker.java
@@ -127,4 +127,11 @@ * ready to receive calls. */ void addOnInitializedCallback(Callback<Boolean> callback); + + /** + * Instructs the tracker in C++ to start proxying calls to Java. See {@link + * CppWrappedTestTracker} for usage and details. + * @param tracker The tracker object that should be receiving the calls. + */ + void injectTracker(Tracker tracker); }
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc index 78ac432..7a1b94a3 100644 --- a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc +++ b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
@@ -183,42 +183,74 @@ class MockSyncMetadataStore : public PasswordStoreSync::MetadataStore { public: - MOCK_METHOD0(GetAllSyncMetadata, std::unique_ptr<syncer::MetadataBatch>()); - MOCK_METHOD0(DeleteAllSyncMetadata, void()); - MOCK_METHOD3(UpdateSyncMetadata, - bool(syncer::ModelType, - const std::string&, - const sync_pb::EntityMetadata&)); - MOCK_METHOD2(ClearSyncMetadata, bool(syncer::ModelType, const std::string&)); - MOCK_METHOD2(UpdateModelTypeState, - bool(syncer::ModelType, const sync_pb::ModelTypeState&)); - MOCK_METHOD1(ClearModelTypeState, bool(syncer::ModelType)); - MOCK_METHOD1(SetDeletionsHaveSyncedCallback, - void(base::RepeatingCallback<void(bool)>)); - MOCK_METHOD0(HasUnsyncedDeletions, bool()); + MOCK_METHOD(std::unique_ptr<syncer::MetadataBatch>, + GetAllSyncMetadata, + (), + (override)); + MOCK_METHOD(void, DeleteAllSyncMetadata, (), (override)); + MOCK_METHOD(bool, + UpdateSyncMetadata, + (syncer::ModelType, + const std::string&, + const sync_pb::EntityMetadata&), + (override)); + MOCK_METHOD(bool, + ClearSyncMetadata, + (syncer::ModelType, const std::string&), + (override)); + MOCK_METHOD(bool, + UpdateModelTypeState, + (syncer::ModelType, const sync_pb::ModelTypeState&), + (override)); + MOCK_METHOD(bool, ClearModelTypeState, (syncer::ModelType), (override)); + MOCK_METHOD(void, + SetDeletionsHaveSyncedCallback, + (base::RepeatingCallback<void(bool)>), + (override)); + MOCK_METHOD(bool, HasUnsyncedDeletions, (), (override)); }; class MockPasswordStoreSync : public PasswordStoreSync { public: - MOCK_METHOD1(ReadAllLogins, FormRetrievalResult(PrimaryKeyToFormMap*)); - MOCK_METHOD1(RemoveLoginByPrimaryKeySync, PasswordStoreChangeList(int)); - MOCK_METHOD0(DeleteUndecryptableLogins, DatabaseCleanupResult()); - MOCK_METHOD2(AddLoginSync, - PasswordStoreChangeList(const PasswordForm&, AddLoginError*)); - MOCK_METHOD2(UpdateLoginSync, - PasswordStoreChangeList(const PasswordForm&, UpdateLoginError*)); - MOCK_METHOD1(RemoveLoginSync, PasswordStoreChangeList(const PasswordForm&)); - MOCK_METHOD1(NotifyLoginsChanged, void(const PasswordStoreChangeList&)); - MOCK_METHOD1(NotifyDeletionsHaveSynced, void(bool)); - - MOCK_METHOD1(NotifyUnsyncedCredentialsWillBeDeleted, - void(std::vector<PasswordForm> unsynced_credentials)); - MOCK_METHOD0(BeginTransaction, bool()); - MOCK_METHOD0(CommitTransaction, bool()); - MOCK_METHOD0(RollbackTransaction, void()); - MOCK_METHOD0(GetMetadataStore, PasswordStoreSync::MetadataStore*()); - MOCK_CONST_METHOD0(IsAccountStore, bool()); - MOCK_METHOD0(DeleteAndRecreateDatabaseFile, bool()); + MOCK_METHOD(FormRetrievalResult, + ReadAllLogins, + (PrimaryKeyToFormMap*), + (override)); + MOCK_METHOD(PasswordStoreChangeList, + RemoveLoginByPrimaryKeySync, + (int), + (override)); + MOCK_METHOD(DatabaseCleanupResult, DeleteUndecryptableLogins, (), (override)); + MOCK_METHOD(PasswordStoreChangeList, + AddLoginSync, + (const PasswordForm&, AddLoginError*), + (override)); + MOCK_METHOD(PasswordStoreChangeList, + UpdateLoginSync, + (const PasswordForm&, UpdateLoginError*), + (override)); + MOCK_METHOD(PasswordStoreChangeList, + RemoveLoginSync, + (const PasswordForm&), + (override)); + MOCK_METHOD(void, + NotifyLoginsChanged, + (const PasswordStoreChangeList&), + (override)); + MOCK_METHOD(void, NotifyDeletionsHaveSynced, (bool), (override)); + MOCK_METHOD(void, + NotifyUnsyncedCredentialsWillBeDeleted, + (std::vector<PasswordForm> unsynced_credentials), + (override)); + MOCK_METHOD(bool, BeginTransaction, (), (override)); + MOCK_METHOD(bool, CommitTransaction, (), (override)); + MOCK_METHOD(void, RollbackTransaction, (), (override)); + MOCK_METHOD(PasswordStoreSync::MetadataStore*, + GetMetadataStore, + (), + (override)); + MOCK_METHOD(bool, IsAccountStore, (), (const override)); + MOCK_METHOD(bool, DeleteAndRecreateDatabaseFile, (), (override)); }; } // namespace
diff --git a/components/sync/base/sync_prefs_unittest.cc b/components/sync/base/sync_prefs_unittest.cc index 3129d1c..f4b1bebe 100644 --- a/components/sync/base/sync_prefs_unittest.cc +++ b/components/sync/base/sync_prefs_unittest.cc
@@ -72,10 +72,10 @@ class MockSyncPrefObserver : public SyncPrefObserver { public: - MOCK_METHOD1(OnSyncManagedPrefChange, void(bool)); - MOCK_METHOD1(OnFirstSetupCompletePrefChange, void(bool)); - MOCK_METHOD1(OnSyncRequestedPrefChange, void(bool)); - MOCK_METHOD0(OnPreferredDataTypesPrefChange, void()); + MOCK_METHOD(void, OnSyncManagedPrefChange, (bool), (override)); + MOCK_METHOD(void, OnFirstSetupCompletePrefChange, (bool), (override)); + MOCK_METHOD(void, OnSyncRequestedPrefChange, (bool), (override)); + MOCK_METHOD(void, OnPreferredDataTypesPrefChange, (), (override)); }; TEST_F(SyncPrefsTest, ObservedPrefs) {
diff --git a/components/sync/base/weak_handle_unittest.cc b/components/sync/base/weak_handle_unittest.cc index 5e46dc3..a02a9fc 100644 --- a/components/sync/base/weak_handle_unittest.cc +++ b/components/sync/base/weak_handle_unittest.cc
@@ -26,14 +26,12 @@ } void Kill() { weak_ptr_factory_.InvalidateWeakPtrs(); } - - MOCK_METHOD0(Test, void()); - MOCK_METHOD1(Test1, void(const int&)); - MOCK_METHOD2(Test2, void(const int&, Base*)); - MOCK_METHOD3(Test3, void(const int&, Base*, float)); - MOCK_METHOD4(Test4, void(const int&, Base*, float, const char*)); - - MOCK_METHOD1(TestWithSelf, void(const WeakHandle<Base>&)); + MOCK_METHOD(void, Test, (), ()); + MOCK_METHOD(void, Test1, (const int&), ()); + MOCK_METHOD(void, Test2, (const int&, Base*), ()); + MOCK_METHOD(void, Test3, (const int&, Base*, float), ()); + MOCK_METHOD(void, Test4, (const int&, Base*, float, const char*), ()); + MOCK_METHOD(void, TestWithSelf, (const WeakHandle<Base>&), ()); private: base::WeakPtrFactory<Base> weak_ptr_factory_{this};
diff --git a/components/sync/driver/backend_migrator_unittest.cc b/components/sync/driver/backend_migrator_unittest.cc index 21c09fb..1d6c808 100644 --- a/components/sync/driver/backend_migrator_unittest.cc +++ b/components/sync/driver/backend_migrator_unittest.cc
@@ -87,7 +87,7 @@ public: ~MockMigrationObserver() override {} - MOCK_METHOD0(OnMigrationStateChange, void()); + MOCK_METHOD(void, OnMigrationStateChange, ()); }; // Test that in the normal case a migration does transition through each state
diff --git a/components/sync/driver/data_type_manager_mock.h b/components/sync/driver/data_type_manager_mock.h index 2a6d76a..2c119601 100644 --- a/components/sync/driver/data_type_manager_mock.h +++ b/components/sync/driver/data_type_manager_mock.h
@@ -15,16 +15,17 @@ public: DataTypeManagerMock(); ~DataTypeManagerMock() override; - - MOCK_METHOD2(Configure, void(ModelTypeSet, const ConfigureContext&)); - MOCK_METHOD1(DataTypePreconditionChanged, void(ModelType)); - MOCK_METHOD0(ResetDataTypeErrors, void()); - MOCK_METHOD1(PurgeForMigration, void(ModelTypeSet)); - MOCK_METHOD1(Stop, void(ShutdownReason)); - MOCK_METHOD0(controllers, const DataTypeController::TypeMap&()); - MOCK_CONST_METHOD0(GetActiveDataTypes, ModelTypeSet()); - MOCK_CONST_METHOD0(GetPurgedDataTypes, ModelTypeSet()); - MOCK_CONST_METHOD0(state, State()); + MOCK_METHOD(void, + Configure, + (ModelTypeSet, const ConfigureContext&), + (override)); + MOCK_METHOD(void, DataTypePreconditionChanged, (ModelType), (override)); + MOCK_METHOD(void, ResetDataTypeErrors, (), (override)); + MOCK_METHOD(void, PurgeForMigration, (ModelTypeSet), (override)); + MOCK_METHOD(void, Stop, (ShutdownReason), (override)); + MOCK_METHOD(ModelTypeSet, GetActiveDataTypes, (), (const override)); + MOCK_METHOD(ModelTypeSet, GetPurgedDataTypes, (), (const override)); + MOCK_METHOD(State, state, (), (const override)); private: DataTypeManager::ConfigureResult result_;
diff --git a/components/sync/driver/glue/sync_engine_impl_unittest.cc b/components/sync/driver/glue/sync_engine_impl_unittest.cc index 2087d5d..c7f2de3 100644 --- a/components/sync/driver/glue/sync_engine_impl_unittest.cc +++ b/components/sync/driver/glue/sync_engine_impl_unittest.cc
@@ -143,21 +143,33 @@ public: MockInvalidationService() = default; ~MockInvalidationService() override = default; - - MOCK_METHOD1(RegisterInvalidationHandler, - void(syncer::InvalidationHandler* handler)); - MOCK_METHOD2(UpdateInterestedTopics, - bool(syncer::InvalidationHandler* handler, - const syncer::TopicSet& topics)); - MOCK_METHOD1(UnregisterInvalidationHandler, - void(syncer::InvalidationHandler* handler)); - MOCK_METHOD0(GetInvalidatorStat, syncer::InvalidatorState()); - MOCK_CONST_METHOD0(GetInvalidatorState, syncer::InvalidatorState()); - MOCK_CONST_METHOD0(GetInvalidatorClientId, std::string()); - MOCK_METHOD0(GetInvalidationLogger, invalidation::InvalidationLogger*()); - MOCK_CONST_METHOD1(RequestDetailedStatus, - void(base::RepeatingCallback< - void(const base::DictionaryValue&)> post_caller)); + MOCK_METHOD(void, + RegisterInvalidationHandler, + (syncer::InvalidationHandler * handler), + (override)); + MOCK_METHOD(bool, + UpdateInterestedTopics, + (syncer::InvalidationHandler * handler, + const syncer::TopicSet& topics), + (override)); + MOCK_METHOD(void, + UnregisterInvalidationHandler, + (syncer::InvalidationHandler * handler), + (override)); + MOCK_METHOD(syncer::InvalidatorState, + GetInvalidatorState, + (), + (const override)); + MOCK_METHOD(std::string, GetInvalidatorClientId, (), (const override)); + MOCK_METHOD(invalidation::InvalidationLogger*, + GetInvalidationLogger, + (), + (override)); + MOCK_METHOD( + void, + RequestDetailedStatus, + (base::RepeatingCallback<void(const base::DictionaryValue&)> post_caller), + (const override)); }; std::unique_ptr<HttpPostProviderFactory> CreateHttpBridgeFactory() {
diff --git a/components/sync/driver/mock_sync_service.h b/components/sync/driver/mock_sync_service.h index 4b7f27c..365b3a9 100644 --- a/components/sync/driver/mock_sync_service.h +++ b/components/sync/driver/mock_sync_service.h
@@ -33,62 +33,107 @@ // SyncService implementation. syncer::SyncUserSettings* GetUserSettings() override; const syncer::SyncUserSettings* GetUserSettings() const override; - MOCK_CONST_METHOD0(GetDisableReasons, DisableReasonSet()); - MOCK_CONST_METHOD0(GetTransportState, TransportState()); - MOCK_CONST_METHOD0(IsLocalSyncEnabled, bool()); - MOCK_CONST_METHOD0(GetAuthenticatedAccountInfo, CoreAccountInfo()); - MOCK_CONST_METHOD0(IsAuthenticatedAccountPrimary, bool()); - MOCK_CONST_METHOD0(GetAuthError, GoogleServiceAuthError()); - MOCK_CONST_METHOD0(GetAuthErrorTime, base::Time()); - MOCK_CONST_METHOD0(RequiresClientUpgrade, bool()); - MOCK_METHOD0(GetSetupInProgressHandle, - std::unique_ptr<SyncSetupInProgressHandle>()); - MOCK_CONST_METHOD0(IsSetupInProgress, bool()); - - MOCK_CONST_METHOD0(GetPreferredDataTypes, ModelTypeSet()); - MOCK_CONST_METHOD0(GetActiveDataTypes, ModelTypeSet()); - MOCK_CONST_METHOD0(GetBackedOffDataTypes, ModelTypeSet()); - - MOCK_METHOD0(StopAndClear, void()); - MOCK_METHOD1(OnDataTypeRequestsSyncStartup, void(ModelType type)); - MOCK_METHOD1(TriggerRefresh, void(const ModelTypeSet& types)); - MOCK_METHOD1(DataTypePreconditionChanged, void(syncer::ModelType type)); - MOCK_METHOD1(SetInvalidationsForSessionsEnabled, void(bool enabled)); - MOCK_METHOD3(AddTrustedVaultDecryptionKeysFromWeb, - void(const std::string& gaia_id, - const std::vector<std::vector<uint8_t>>& keys, - int last_key_version)); - MOCK_METHOD3(AddTrustedVaultRecoveryMethodFromWeb, - void(const std::string& gaia_id, - const std::vector<uint8_t>& public_key, - base::OnceClosure callback)); - MOCK_METHOD1(GetUserNoisedBirthYearAndGender, - UserDemographicsResult(base::Time now)); - - MOCK_METHOD1(AddObserver, void(SyncServiceObserver* observer)); - MOCK_METHOD1(RemoveObserver, void(SyncServiceObserver* observer)); - MOCK_CONST_METHOD1(HasObserver, bool(const SyncServiceObserver* observer)); - - MOCK_CONST_METHOD0(GetSyncTokenStatusForDebugging, SyncTokenStatus()); - MOCK_CONST_METHOD1(QueryDetailedSyncStatusForDebugging, - bool(SyncStatus* result)); - MOCK_CONST_METHOD0(GetLastSyncedTimeForDebugging, base::Time()); - MOCK_CONST_METHOD0(GetLastCycleSnapshotForDebugging, SyncCycleSnapshot()); - MOCK_METHOD0(GetTypeStatusMapForDebugging, std::unique_ptr<base::Value>()); - MOCK_CONST_METHOD0(GetSyncServiceUrlForDebugging, const GURL&()); - MOCK_CONST_METHOD0(GetUnrecoverableErrorMessageForDebugging, std::string()); - MOCK_CONST_METHOD0(GetUnrecoverableErrorLocationForDebugging, - base::Location()); - MOCK_METHOD1(AddProtocolEventObserver, void(ProtocolEventObserver* observer)); - MOCK_METHOD1(RemoveProtocolEventObserver, - void(ProtocolEventObserver* observer)); - MOCK_METHOD0(GetJsController, base::WeakPtr<JsController>()); - MOCK_METHOD1(GetAllNodesForDebugging, - void(base::OnceCallback<void(std::unique_ptr<base::ListValue>)> - callback)); + MOCK_METHOD(DisableReasonSet, GetDisableReasons, (), (const override)); + MOCK_METHOD(TransportState, GetTransportState, (), (const override)); + MOCK_METHOD(bool, IsLocalSyncEnabled, (), (const override)); + MOCK_METHOD(CoreAccountInfo, + GetAuthenticatedAccountInfo, + (), + (const override)); + MOCK_METHOD(bool, IsAuthenticatedAccountPrimary, (), (const override)); + MOCK_METHOD(GoogleServiceAuthError, GetAuthError, (), (const override)); + MOCK_METHOD(base::Time, GetAuthErrorTime, (), (const override)); + MOCK_METHOD(bool, RequiresClientUpgrade, (), (const override)); + MOCK_METHOD(std::unique_ptr<SyncSetupInProgressHandle>, + GetSetupInProgressHandle, + (), + (override)); + MOCK_METHOD(bool, IsSetupInProgress, (), (const override)); + MOCK_METHOD(ModelTypeSet, GetPreferredDataTypes, (), (const override)); + MOCK_METHOD(ModelTypeSet, GetActiveDataTypes, (), (const override)); + MOCK_METHOD(ModelTypeSet, GetBackedOffDataTypes, (), (const override)); + MOCK_METHOD(void, StopAndClear, (), (override)); + MOCK_METHOD(void, + OnDataTypeRequestsSyncStartup, + (ModelType type), + (override)); + MOCK_METHOD(void, TriggerRefresh, (const ModelTypeSet& types), (override)); + MOCK_METHOD(void, + DataTypePreconditionChanged, + (syncer::ModelType type), + (override)); + MOCK_METHOD(void, + SetInvalidationsForSessionsEnabled, + (bool enabled), + (override)); + MOCK_METHOD(void, + AddTrustedVaultDecryptionKeysFromWeb, + (const std::string& gaia_id, + const std::vector<std::vector<uint8_t>>& keys, + int last_key_version), + (override)); + MOCK_METHOD(void, + AddTrustedVaultRecoveryMethodFromWeb, + (const std::string& gaia_id, + const std::vector<uint8_t>& public_key, + base::OnceClosure callback), + (override)); + MOCK_METHOD(UserDemographicsResult, + GetUserNoisedBirthYearAndGender, + (base::Time now), + (override)); + MOCK_METHOD(void, AddObserver, (SyncServiceObserver * observer), (override)); + MOCK_METHOD(void, + RemoveObserver, + (SyncServiceObserver * observer), + (override)); + MOCK_METHOD(bool, + HasObserver, + (const SyncServiceObserver* observer), + (const override)); + MOCK_METHOD(SyncTokenStatus, + GetSyncTokenStatusForDebugging, + (), + (const override)); + MOCK_METHOD(bool, + QueryDetailedSyncStatusForDebugging, + (SyncStatus * result), + (const override)); + MOCK_METHOD(base::Time, GetLastSyncedTimeForDebugging, (), (const override)); + MOCK_METHOD(SyncCycleSnapshot, + GetLastCycleSnapshotForDebugging, + (), + (const override)); + MOCK_METHOD(std::unique_ptr<base::Value>, + GetTypeStatusMapForDebugging, + (), + (override)); + MOCK_METHOD(const GURL&, GetSyncServiceUrlForDebugging, (), (const override)); + MOCK_METHOD(std::string, + GetUnrecoverableErrorMessageForDebugging, + (), + (const override)); + MOCK_METHOD(base::Location, + GetUnrecoverableErrorLocationForDebugging, + (), + (const override)); + MOCK_METHOD(void, + AddProtocolEventObserver, + (ProtocolEventObserver * observer), + (override)); + MOCK_METHOD(void, + RemoveProtocolEventObserver, + (ProtocolEventObserver * observer), + (override)); + MOCK_METHOD(base::WeakPtr<JsController>, GetJsController, (), (override)); + MOCK_METHOD( + void, + GetAllNodesForDebugging, + (base::OnceCallback<void(std::unique_ptr<base::ListValue>)> callback), + (override)); // KeyedService implementation. - MOCK_METHOD0(Shutdown, void()); + MOCK_METHOD(void, Shutdown, (), (override)); private: testing::NiceMock<syncer::SyncUserSettingsMock> user_settings_;
diff --git a/components/sync/driver/model_association_manager_unittest.cc b/components/sync/driver/model_association_manager_unittest.cc index 47ac4643..d6a3b2e3 100644 --- a/components/sync/driver/model_association_manager_unittest.cc +++ b/components/sync/driver/model_association_manager_unittest.cc
@@ -32,14 +32,21 @@ class MockModelAssociationManagerDelegate : public ModelAssociationManagerDelegate { public: - MockModelAssociationManagerDelegate() {} - ~MockModelAssociationManagerDelegate() override {} - MOCK_METHOD0(OnAllDataTypesReadyForConfigure, void()); - MOCK_METHOD1(OnSingleDataTypeAssociationDone, void(ModelType type)); - MOCK_METHOD2(OnSingleDataTypeWillStop, - void(ModelType, const SyncError& error)); - MOCK_METHOD1(OnModelAssociationDone, - void(const DataTypeManager::ConfigureResult& result)); + MockModelAssociationManagerDelegate() = default; + ~MockModelAssociationManagerDelegate() override = default; + MOCK_METHOD(void, OnAllDataTypesReadyForConfigure, (), (override)); + MOCK_METHOD(void, + OnSingleDataTypeAssociationDone, + (ModelType type), + (override)); + MOCK_METHOD(void, + OnSingleDataTypeWillStop, + (ModelType, const SyncError& error), + (override)); + MOCK_METHOD(void, + OnModelAssociationDone, + (const DataTypeManager::ConfigureResult& result), + (override)); }; MATCHER_P2(MatchesResult, status, requested_types, "") {
diff --git a/components/sync/driver/model_type_controller_unittest.cc b/components/sync/driver/model_type_controller_unittest.cc index 6fc1c66..996aa9d1 100644 --- a/components/sync/driver/model_type_controller_unittest.cc +++ b/components/sync/driver/model_type_controller_unittest.cc
@@ -47,12 +47,20 @@ class MockDelegate : public ModelTypeControllerDelegate { public: - MOCK_METHOD2(OnSyncStarting, - void(const DataTypeActivationRequest& request, - StartCallback callback)); - MOCK_METHOD1(OnSyncStopping, void(SyncStopMetadataFate metadata_fate)); - MOCK_METHOD1(GetAllNodesForDebugging, void(AllNodesCallback callback)); - MOCK_METHOD0(RecordMemoryUsageAndCountsHistograms, void()); + MOCK_METHOD(void, + OnSyncStarting, + (const DataTypeActivationRequest& request, + StartCallback callback), + (override)); + MOCK_METHOD(void, + OnSyncStopping, + (SyncStopMetadataFate metadata_fate), + (override)); + MOCK_METHOD(void, + GetAllNodesForDebugging, + (AllNodesCallback callback), + (override)); + MOCK_METHOD(void, RecordMemoryUsageAndCountsHistograms, (), (override)); }; // A simple processor that trackes connected state.
diff --git a/components/sync/driver/profile_sync_service.cc b/components/sync/driver/profile_sync_service.cc index 3f6007e7..2b7895e5 100644 --- a/components/sync/driver/profile_sync_service.cc +++ b/components/sync/driver/profile_sync_service.cc
@@ -146,12 +146,6 @@ network_time_update_callback); } -void EmitUmaMetricWithEmitTimeMinutes(const std::string& histogram_name) { - base::Time::Exploded now_exploded; - base::Time::Now().UTCExplode(&now_exploded); - base::UmaHistogramExactLinear(histogram_name, now_exploded.minute, 60); -} - std::string GenerateCacheGUID() { // Generate a GUID with 128 bits of randomness. const int kGuidBytes = 128 / 8; @@ -327,9 +321,6 @@ if (HasDisableReason(DISABLE_REASON_ENTERPRISE_POLICY) || (HasDisableReason(DISABLE_REASON_NOT_SIGNED_IN) && auth_manager_->IsActiveAccountInfoFullyLoaded())) { - // TODO(crbug/1031162): Remove once traffic investigation is closed. - EmitUmaMetricWithEmitTimeMinutes( - "Sync.PeakAnalysis.StopOnSyncPermanentlyDisabled"); StopImpl(CLEAR_DATA); } @@ -387,9 +378,6 @@ if (!IsSignedIn()) { // The account was signed out, so shut down. sync_disabled_by_admin_ = false; - // TODO(crbug/1031162): Remove once traffic investigation is closed. - EmitUmaMetricWithEmitTimeMinutes( - "Sync.PeakAnalysis.StopAfterAccountStateChanged"); StopImpl(CLEAR_DATA); DCHECK(!engine_); } else { @@ -425,9 +413,6 @@ // then shut down. This happens when the user signs out on the web, i.e. we're // in the "Sync paused" state. if (!IsEngineAllowedToRun()) { - // TODO(crbug/1031162): Remove once traffic investigation is closed. - EmitUmaMetricWithEmitTimeMinutes( - "Sync.PeakAnalysis.StopAfterCredentialsChanged"); // This will notify observers if appropriate. StopImpl(KEEP_DATA); return; @@ -1485,9 +1470,6 @@ void ProfileSyncService::OnSyncManagedPrefChange(bool is_sync_managed) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (is_sync_managed) { - // TODO(crbug/1031162): Remove once traffic investigation is closed. - EmitUmaMetricWithEmitTimeMinutes( - "Sync.PeakAnalysis.StopOnSyncManagedPrefChange"); StopImpl(CLEAR_DATA); } else { // Sync is no longer disabled by policy. Try starting it up if appropriate.
diff --git a/components/sync/driver/sync_api_component_factory_mock.h b/components/sync/driver/sync_api_component_factory_mock.h index 5b5b016..f19bc062 100644 --- a/components/sync/driver/sync_api_component_factory_mock.h +++ b/components/sync/driver/sync_api_component_factory_mock.h
@@ -23,22 +23,23 @@ public: SyncApiComponentFactoryMock(); ~SyncApiComponentFactoryMock() override; - - MOCK_METHOD6(CreateDataTypeManager, - std::unique_ptr<DataTypeManager>( - ModelTypeSet, - const WeakHandle<DataTypeDebugInfoListener>&, - const DataTypeController::TypeMap*, - const DataTypeEncryptionHandler*, - ModelTypeConfigurer*, - DataTypeManagerObserver*)); - MOCK_METHOD4(CreateSyncEngine, - std::unique_ptr<SyncEngine>( - const std::string& name, - invalidation::InvalidationService* invalidator, - syncer::SyncInvalidationsService* sync_invalidations_service, - const base::WeakPtr<SyncPrefs>& sync_prefs)); - MOCK_METHOD0(DeleteLegacyDirectoryFilesAndNigoriStorage, void()); + MOCK_METHOD(std::unique_ptr<DataTypeManager>, + CreateDataTypeManager, + (ModelTypeSet, + const WeakHandle<DataTypeDebugInfoListener>&, + const DataTypeController::TypeMap*, + const DataTypeEncryptionHandler*, + ModelTypeConfigurer*, + DataTypeManagerObserver*), + (override)); + MOCK_METHOD(std::unique_ptr<SyncEngine>, + CreateSyncEngine, + (const std::string& name, + invalidation::InvalidationService* invalidator, + syncer::SyncInvalidationsService* sync_invalidations_service, + const base::WeakPtr<SyncPrefs>& sync_prefs), + (override)); + MOCK_METHOD(void, DeleteLegacyDirectoryFilesAndNigoriStorage, (), (override)); }; } // namespace syncer
diff --git a/components/sync/driver/sync_client_mock.h b/components/sync/driver/sync_client_mock.h index 3f085e26..775d855a 100644 --- a/components/sync/driver/sync_client_mock.h +++ b/components/sync/driver/sync_client_mock.h
@@ -15,21 +15,34 @@ public: SyncClientMock(); ~SyncClientMock() override; - - MOCK_METHOD0(GetPrefService, PrefService*()); - MOCK_METHOD0(GetIdentityManager, signin::IdentityManager*()); - MOCK_METHOD0(GetLocalSyncBackendFolder, base::FilePath()); - MOCK_METHOD1(CreateDataTypeControllers, - DataTypeController::TypeVector(SyncService* sync_service)); - MOCK_METHOD0(GetPasswordStateChangedCallback, base::RepeatingClosure()); - - MOCK_METHOD0(GetInvalidationService, invalidation::InvalidationService*()); - MOCK_METHOD0(GetSyncInvalidationsService, - syncer::SyncInvalidationsService*()); - MOCK_METHOD0(GetTrustedVaultClient, TrustedVaultClient*()); - MOCK_METHOD0(GetExtensionsActivity, scoped_refptr<ExtensionsActivity>()); - MOCK_METHOD0(GetSyncApiComponentFactory, SyncApiComponentFactory*()); - MOCK_METHOD0(GetPreferenceProvider, SyncTypePreferenceProvider*()); + MOCK_METHOD(PrefService*, GetPrefService, (), (override)); + MOCK_METHOD(signin::IdentityManager*, GetIdentityManager, (), (override)); + MOCK_METHOD(base::FilePath, GetLocalSyncBackendFolder, (), (override)); + MOCK_METHOD(DataTypeController::TypeVector, + CreateDataTypeControllers, + (SyncService * sync_service), + (override)); + MOCK_METHOD(invalidation::InvalidationService*, + GetInvalidationService, + (), + (override)); + MOCK_METHOD(syncer::SyncInvalidationsService*, + GetSyncInvalidationsService, + (), + (override)); + MOCK_METHOD(TrustedVaultClient*, GetTrustedVaultClient, (), (override)); + MOCK_METHOD(scoped_refptr<ExtensionsActivity>, + GetExtensionsActivity, + (), + (override)); + MOCK_METHOD(SyncApiComponentFactory*, + GetSyncApiComponentFactory, + (), + (override)); + MOCK_METHOD(SyncTypePreferenceProvider*, + GetPreferenceProvider, + (), + (override)); private: DISALLOW_COPY_AND_ASSIGN(SyncClientMock);
diff --git a/components/sync/driver/sync_service_crypto_unittest.cc b/components/sync/driver/sync_service_crypto_unittest.cc index 4388b48..8d2ae25 100644 --- a/components/sync/driver/sync_service_crypto_unittest.cc +++ b/components/sync/driver/sync_service_crypto_unittest.cc
@@ -58,11 +58,19 @@ public: MockCryptoSyncPrefs() = default; ~MockCryptoSyncPrefs() override = default; - - MOCK_CONST_METHOD0(GetEncryptionBootstrapToken, std::string()); - MOCK_METHOD1(SetEncryptionBootstrapToken, void(const std::string&)); - MOCK_CONST_METHOD0(GetKeystoreEncryptionBootstrapToken, std::string()); - MOCK_METHOD1(SetKeystoreEncryptionBootstrapToken, void(const std::string&)); + MOCK_METHOD(std::string, GetEncryptionBootstrapToken, (), (const override)); + MOCK_METHOD(void, + SetEncryptionBootstrapToken, + (const std::string&), + (override)); + MOCK_METHOD(std::string, + GetKeystoreEncryptionBootstrapToken, + (), + (const override)); + MOCK_METHOD(void, + SetKeystoreEncryptionBootstrapToken, + (const std::string&), + (override)); }; // Object representing a server that contains the authoritative trusted vault
diff --git a/components/sync/driver/sync_user_settings_mock.h b/components/sync/driver/sync_user_settings_mock.h index f51b26b..ef087d24 100644 --- a/components/sync/driver/sync_user_settings_mock.h +++ b/components/sync/driver/sync_user_settings_mock.h
@@ -17,46 +17,62 @@ public: SyncUserSettingsMock(); ~SyncUserSettingsMock() override; - - MOCK_CONST_METHOD0(IsSyncRequested, bool()); - MOCK_METHOD1(SetSyncRequested, void(bool)); - - MOCK_CONST_METHOD0(IsSyncAllowedByPlatform, bool()); - MOCK_METHOD1(SetSyncAllowedByPlatform, void(bool)); - - MOCK_CONST_METHOD0(IsFirstSetupComplete, bool()); - MOCK_METHOD1(SetFirstSetupComplete, void(SyncFirstSetupCompleteSource)); - - MOCK_CONST_METHOD0(IsSyncEverythingEnabled, bool()); - MOCK_CONST_METHOD0(GetSelectedTypes, UserSelectableTypeSet()); - MOCK_METHOD2(SetSelectedTypes, void(bool, UserSelectableTypeSet)); - MOCK_CONST_METHOD0(GetRegisteredSelectableTypes, UserSelectableTypeSet()); + MOCK_METHOD(bool, IsSyncRequested, (), (const override)); + MOCK_METHOD(void, SetSyncRequested, (bool), (override)); + MOCK_METHOD(bool, IsSyncAllowedByPlatform, (), (const override)); + MOCK_METHOD(void, SetSyncAllowedByPlatform, (bool), (override)); + MOCK_METHOD(bool, IsFirstSetupComplete, (), (const override)); + MOCK_METHOD(void, + SetFirstSetupComplete, + (SyncFirstSetupCompleteSource), + (override)); + MOCK_METHOD(bool, IsSyncEverythingEnabled, (), (const override)); + MOCK_METHOD(UserSelectableTypeSet, GetSelectedTypes, (), (const override)); + MOCK_METHOD(void, + SetSelectedTypes, + (bool, UserSelectableTypeSet), + (override)); + MOCK_METHOD(UserSelectableTypeSet, + GetRegisteredSelectableTypes, + (), + (const override)); #if defined(OS_CHROMEOS) - MOCK_CONST_METHOD0(IsSyncAllOsTypesEnabled, bool()); - MOCK_CONST_METHOD0(GetSelectedOsTypes, UserSelectableOsTypeSet()); - MOCK_METHOD2(SetSelectedOsTypes, void(bool, UserSelectableOsTypeSet)); - MOCK_CONST_METHOD0(GetRegisteredSelectableOsTypes, UserSelectableOsTypeSet()); - - MOCK_CONST_METHOD0(IsOsSyncFeatureEnabled, bool()); - MOCK_METHOD1(SetOsSyncFeatureEnabled, void(bool)); + MOCK_METHOD(bool, IsSyncAllOsTypesEnabled, (), (const override)); + MOCK_METHOD(UserSelectableOsTypeSet, + GetSelectedOsTypes, + (), + (const override)); + MOCK_METHOD(void, + SetSelectedOsTypes, + (bool, UserSelectableOsTypeSet), + (override)); + MOCK_METHOD(UserSelectableOsTypeSet, + GetRegisteredSelectableOsTypes, + (), + (const override)); + MOCK_METHOD(bool, IsOsSyncFeatureEnabled, (), (const override)); + MOCK_METHOD(void, SetOsSyncFeatureEnabled, (bool), (override)); #endif - - MOCK_CONST_METHOD0(IsEncryptEverythingAllowed, bool()); - MOCK_CONST_METHOD0(IsEncryptEverythingEnabled, bool()); - - MOCK_CONST_METHOD0(GetEncryptedDataTypes, ModelTypeSet()); - MOCK_CONST_METHOD0(IsPassphraseRequired, bool()); - MOCK_CONST_METHOD0(IsPassphraseRequiredForPreferredDataTypes, bool()); - MOCK_CONST_METHOD0(IsTrustedVaultKeyRequired, bool()); - MOCK_CONST_METHOD0(IsTrustedVaultKeyRequiredForPreferredDataTypes, bool()); - MOCK_CONST_METHOD0(IsTrustedVaultRecoverabilityDegraded, bool()); - MOCK_CONST_METHOD0(IsUsingSecondaryPassphrase, bool()); - MOCK_CONST_METHOD0(GetExplicitPassphraseTime, base::Time()); - MOCK_CONST_METHOD0(GetPassphraseType, PassphraseType()); - - MOCK_METHOD1(SetEncryptionPassphrase, void(const std::string&)); - MOCK_METHOD1(SetDecryptionPassphrase, bool(const std::string&)); + MOCK_METHOD(bool, IsEncryptEverythingAllowed, (), (const override)); + MOCK_METHOD(bool, IsEncryptEverythingEnabled, (), (const override)); + MOCK_METHOD(ModelTypeSet, GetEncryptedDataTypes, (), (const override)); + MOCK_METHOD(bool, IsPassphraseRequired, (), (const override)); + MOCK_METHOD(bool, + IsPassphraseRequiredForPreferredDataTypes, + (), + (const override)); + MOCK_METHOD(bool, IsTrustedVaultKeyRequired, (), (const override)); + MOCK_METHOD(bool, + IsTrustedVaultKeyRequiredForPreferredDataTypes, + (), + (const override)); + MOCK_METHOD(bool, IsTrustedVaultRecoverabilityDegraded, (), (const override)); + MOCK_METHOD(bool, IsUsingSecondaryPassphrase, (), (const override)); + MOCK_METHOD(base::Time, GetExplicitPassphraseTime, (), (const override)); + MOCK_METHOD(PassphraseType, GetPassphraseType, (), (const override)); + MOCK_METHOD(void, SetEncryptionPassphrase, (const std::string&), (override)); + MOCK_METHOD(bool, SetDecryptionPassphrase, (const std::string&), (override)); }; } // namespace syncer
diff --git a/components/sync/engine/mock_sync_engine.h b/components/sync/engine/mock_sync_engine.h index f07de02..8c762c73 100644 --- a/components/sync/engine/mock_sync_engine.h +++ b/components/sync/engine/mock_sync_engine.h
@@ -25,37 +25,47 @@ ~MockSyncEngine() override; // ModelTypeConfigurer: - MOCK_METHOD1(ConfigureDataTypes, void(ConfigureParams)); - MOCK_METHOD2(ActivateDataType, - void(ModelType, std::unique_ptr<DataTypeActivationResponse>)); - MOCK_METHOD1(DeactivateDataType, void(ModelType)); - MOCK_METHOD1(ActivateProxyDataType, void(ModelType)); - MOCK_METHOD1(DeactivateProxyDataType, void(ModelType)); + MOCK_METHOD(void, ConfigureDataTypes, (ConfigureParams), (override)); + MOCK_METHOD(void, + ActivateDataType, + (ModelType, std::unique_ptr<DataTypeActivationResponse>), + (override)); + MOCK_METHOD(void, DeactivateDataType, (ModelType), (override)); + MOCK_METHOD(void, ActivateProxyDataType, (ModelType), (override)); + MOCK_METHOD(void, DeactivateProxyDataType, (ModelType), (override)); // SyncEngine: - MOCK_METHOD1(Initialize, void(InitParams)); - MOCK_CONST_METHOD0(IsInitialized, bool()); - MOCK_METHOD1(TriggerRefresh, void(const ModelTypeSet&)); - MOCK_METHOD1(UpdateCredentials, void(const SyncCredentials&)); - MOCK_METHOD0(InvalidateCredentials, void()); - MOCK_METHOD0(StartConfiguration, void()); - MOCK_METHOD0(StartSyncingWithServer, void()); - MOCK_METHOD1(SetEncryptionPassphrase, void(const std::string&)); - MOCK_METHOD1(SetDecryptionPassphrase, void(const std::string&)); - MOCK_METHOD2(AddTrustedVaultDecryptionKeys, - void(const std::vector<std::vector<uint8_t>>&, - base::OnceClosure)); - MOCK_METHOD0(StopSyncingForShutdown, void()); - MOCK_METHOD1(Shutdown, void(ShutdownReason)); - MOCK_CONST_METHOD0(GetDetailedStatus, const SyncStatus&()); - MOCK_CONST_METHOD1(HasUnsyncedItemsForTest, - void(base::OnceCallback<void(bool)>)); - MOCK_METHOD0(RequestBufferedProtocolEventsAndEnableForwarding, void()); - MOCK_METHOD0(DisableProtocolEventForwarding, void()); - MOCK_METHOD1(ClearServerData, void(base::OnceClosure)); - MOCK_METHOD3(OnCookieJarChanged, void(bool, bool, base::OnceClosure)); - MOCK_METHOD1(SetInvalidationsForSessionsEnabled, void(bool)); - MOCK_METHOD1(GetNigoriNodeForDebugging, void(AllNodesCallback)); + MOCK_METHOD(void, Initialize, (InitParams), (override)); + MOCK_METHOD(bool, IsInitialized, (), (const override)); + MOCK_METHOD(void, TriggerRefresh, (const ModelTypeSet&), (override)); + MOCK_METHOD(void, UpdateCredentials, (const SyncCredentials&), (override)); + MOCK_METHOD(void, InvalidateCredentials, (), (override)); + MOCK_METHOD(void, StartConfiguration, (), (override)); + MOCK_METHOD(void, StartSyncingWithServer, (), (override)); + MOCK_METHOD(void, SetEncryptionPassphrase, (const std::string&), (override)); + MOCK_METHOD(void, SetDecryptionPassphrase, (const std::string&), (override)); + MOCK_METHOD(void, + AddTrustedVaultDecryptionKeys, + (const std::vector<std::vector<uint8_t>>&, base::OnceClosure), + (override)); + MOCK_METHOD(void, StopSyncingForShutdown, (), (override)); + MOCK_METHOD(void, Shutdown, (ShutdownReason), (override)); + MOCK_METHOD(const SyncStatus&, GetDetailedStatus, (), (const override)); + MOCK_METHOD(void, + HasUnsyncedItemsForTest, + (base::OnceCallback<void(bool)>), + (const override)); + MOCK_METHOD(void, + RequestBufferedProtocolEventsAndEnableForwarding, + (), + (override)); + MOCK_METHOD(void, DisableProtocolEventForwarding, (), (override)); + MOCK_METHOD(void, + OnCookieJarChanged, + (bool, bool, base::OnceClosure), + (override)); + MOCK_METHOD(void, SetInvalidationsForSessionsEnabled, (bool), (override)); + MOCK_METHOD(void, GetNigoriNodeForDebugging, (AllNodesCallback), (override)); }; } // namespace syncer
diff --git a/components/sync/engine_impl/commit_processor_unittest.cc b/components/sync/engine_impl/commit_processor_unittest.cc index 9951eb8e..4c8820a 100644 --- a/components/sync/engine_impl/commit_processor_unittest.cc +++ b/components/sync/engine_impl/commit_processor_unittest.cc
@@ -56,9 +56,10 @@ public: MockCommitContributor() = default; ~MockCommitContributor() override = default; - - MOCK_METHOD1(GetContribution, - std::unique_ptr<CommitContribution>(size_t max_entries)); + MOCK_METHOD(std::unique_ptr<CommitContribution>, + GetContribution, + (size_t max_entries), + (override)); }; class CommitProcessorTest : public testing::Test {
diff --git a/components/sync/engine_impl/sync_manager_impl_unittest.cc b/components/sync/engine_impl/sync_manager_impl_unittest.cc index 83a726b..20d3e631 100644 --- a/components/sync/engine_impl/sync_manager_impl_unittest.cc +++ b/components/sync/engine_impl/sync_manager_impl_unittest.cc
@@ -98,35 +98,59 @@ class SyncManagerObserverMock : public SyncManager::Observer { public: - MOCK_METHOD1(OnSyncCycleCompleted, void(const SyncCycleSnapshot&)); // NOLINT - MOCK_METHOD3(OnInitializationComplete, - void(const WeakHandle<JsBackend>&, - const WeakHandle<DataTypeDebugInfoListener>&, - bool)); // NOLINT - MOCK_METHOD1(OnConnectionStatusChange, void(ConnectionStatus)); // NOLINT - MOCK_METHOD1(OnUpdatedToken, void(const std::string&)); // NOLINT - MOCK_METHOD1(OnActionableError, void(const SyncProtocolError&)); // NOLINT - MOCK_METHOD1(OnMigrationRequested, void(ModelTypeSet)); // NOLINT - MOCK_METHOD1(OnProtocolEvent, void(const ProtocolEvent&)); // NOLINT + MOCK_METHOD(void, + OnSyncCycleCompleted, + (const SyncCycleSnapshot&), + (override)); + // NOLINT + MOCK_METHOD(void, + OnInitializationComplete, + (const WeakHandle<JsBackend>&, + const WeakHandle<DataTypeDebugInfoListener>&, + bool), + (override)); + // NOLINT + MOCK_METHOD(void, OnConnectionStatusChange, (ConnectionStatus), (override)); + // NOLINT + MOCK_METHOD(void, OnActionableError, (const SyncProtocolError&), (override)); + // NOLINT + MOCK_METHOD(void, OnMigrationRequested, (ModelTypeSet), (override)); + // NOLINT + MOCK_METHOD(void, OnProtocolEvent, (const ProtocolEvent&), (override)); + // NOLINT }; class SyncEncryptionHandlerObserverMock : public SyncEncryptionHandler::Observer { public: - MOCK_METHOD2(OnPassphraseRequired, - void(const KeyDerivationParams&, - const sync_pb::EncryptedData&)); // NOLINT - MOCK_METHOD0(OnPassphraseAccepted, void()); // NOLINT - MOCK_METHOD0(OnTrustedVaultKeyRequired, void()); // NOLINT - MOCK_METHOD0(OnTrustedVaultKeyAccepted, void()); // NOLINT - MOCK_METHOD2(OnBootstrapTokenUpdated, - void(const std::string&, BootstrapTokenType type)); // NOLINT - MOCK_METHOD2(OnEncryptedTypesChanged, void(ModelTypeSet, bool)); // NOLINT - MOCK_METHOD2(OnCryptographerStateChanged, - void(Cryptographer*, bool)); // NOLINT - MOCK_METHOD2(OnPassphraseTypeChanged, - void(PassphraseType, - base::Time)); // NOLINT + MOCK_METHOD(void, + OnPassphraseRequired, + (const KeyDerivationParams&, const sync_pb::EncryptedData&), + (override)); + // NOLINT + MOCK_METHOD(void, OnPassphraseAccepted, (), (override)); + // NOLINT + MOCK_METHOD(void, OnTrustedVaultKeyRequired, (), (override)); + // NOLINT + MOCK_METHOD(void, OnTrustedVaultKeyAccepted, (), (override)); + // NOLINT + MOCK_METHOD(void, + OnBootstrapTokenUpdated, + (const std::string&, BootstrapTokenType type), + (override)); + // NOLINT + MOCK_METHOD(void, OnEncryptedTypesChanged, (ModelTypeSet, bool), (override)); + // NOLINT + MOCK_METHOD(void, + OnCryptographerStateChanged, + (Cryptographer*, bool), + (override)); + // NOLINT + MOCK_METHOD(void, + OnPassphraseTypeChanged, + (PassphraseType, base::Time), + (override)); + // NOLINT }; } // namespace @@ -241,14 +265,13 @@ class MockSyncScheduler : public FakeSyncScheduler { public: - MockSyncScheduler() : FakeSyncScheduler() {} - ~MockSyncScheduler() override {} - - MOCK_METHOD2(Start, void(SyncScheduler::Mode, base::Time)); + MockSyncScheduler() = default; + ~MockSyncScheduler() override = default; + MOCK_METHOD(void, Start, (SyncScheduler::Mode, base::Time), (override)); void ScheduleConfiguration(ConfigurationParams params) override { ScheduleConfiguration_(params); } - MOCK_METHOD1(ScheduleConfiguration_, void(ConfigurationParams&)); + MOCK_METHOD(void, ScheduleConfiguration_, (ConfigurationParams&), ()); }; class ComponentsFactory : public TestEngineComponentsFactory {
diff --git a/components/sync/engine_impl/sync_scheduler_impl_unittest.cc b/components/sync/engine_impl/sync_scheduler_impl_unittest.cc index d135413..5100ee0 100644 --- a/components/sync/engine_impl/sync_scheduler_impl_unittest.cc +++ b/components/sync/engine_impl/sync_scheduler_impl_unittest.cc
@@ -57,12 +57,17 @@ class MockSyncer : public Syncer { public: MockSyncer(); - MOCK_METHOD3(NormalSyncShare, bool(ModelTypeSet, NudgeTracker*, SyncCycle*)); - MOCK_METHOD3(ConfigureSyncShare, - bool(const ModelTypeSet&, - sync_pb::SyncEnums::GetUpdatesOrigin, - SyncCycle*)); - MOCK_METHOD2(PollSyncShare, bool(ModelTypeSet, SyncCycle*)); + MOCK_METHOD(bool, + NormalSyncShare, + (ModelTypeSet, NudgeTracker*, SyncCycle*), + (override)); + MOCK_METHOD(bool, + ConfigureSyncShare, + (const ModelTypeSet&, + sync_pb::SyncEnums::GetUpdatesOrigin, + SyncCycle*), + (override)); + MOCK_METHOD(bool, PollSyncShare, (ModelTypeSet, SyncCycle*), (override)); }; std::unique_ptr<DataTypeActivationResponse> MakeFakeActivationResponse( @@ -119,8 +124,7 @@ : BackoffDelayProvider( TimeDelta::FromSeconds(kInitialBackoffRetrySeconds), TimeDelta::FromSeconds(kInitialBackoffImmediateRetrySeconds)) {} - - MOCK_METHOD1(GetDelay, TimeDelta(const TimeDelta&)); + MOCK_METHOD(TimeDelta, GetDelay, (const TimeDelta&), (override)); }; void SetUp() override {
diff --git a/components/sync/invalidations/fcm_handler_unittest.cc b/components/sync/invalidations/fcm_handler_unittest.cc index 8d32db9..01f19d4c 100644 --- a/components/sync/invalidations/fcm_handler_unittest.cc +++ b/components/sync/invalidations/fcm_handler_unittest.cc
@@ -15,6 +15,7 @@ #include "base/test/task_environment.h" #include "components/gcm_driver/fake_gcm_driver.h" #include "components/gcm_driver/gcm_driver.h" +#include "components/gcm_driver/instance_id/instance_id.h" #include "components/gcm_driver/instance_id/instance_id_driver.h" #include "components/sync/invalidations/fcm_registration_token_observer.h" #include "components/sync/invalidations/invalidations_listener.h" @@ -43,48 +44,64 @@ public: MockInstanceID() : InstanceID("app_id", /*gcm_driver=*/nullptr) {} ~MockInstanceID() override = default; - - MOCK_METHOD1(GetID, void(GetIDCallback callback)); - MOCK_METHOD1(GetCreationTime, void(GetCreationTimeCallback callback)); - MOCK_METHOD6(GetToken, - void(const std::string& authorized_entity, - const std::string& scope, - base::TimeDelta time_to_live, - const std::map<std::string, std::string>& options, - std::set<Flags> flags, - GetTokenCallback callback)); - MOCK_METHOD4(ValidateToken, - void(const std::string& authorized_entity, - const std::string& scope, - const std::string& token, - ValidateTokenCallback callback)); + MOCK_METHOD(void, GetID, (GetIDCallback callback), (override)); + MOCK_METHOD(void, + GetCreationTime, + (GetCreationTimeCallback callback), + (override)); + MOCK_METHOD(void, + GetToken, + (const std::string& authorized_entity, + const std::string& scope, + base::TimeDelta time_to_live, + (const std::map<std::string, std::string>& options), + std::set<Flags> flags, + GetTokenCallback callback), + (override)); + MOCK_METHOD(void, + ValidateToken, + (const std::string& authorized_entity, + const std::string& scope, + const std::string& token, + ValidateTokenCallback callback), + (override)); protected: - MOCK_METHOD3(DeleteTokenImpl, - void(const std::string& authorized_entity, - const std::string& scope, - DeleteTokenCallback callback)); - MOCK_METHOD1(DeleteIDImpl, void(DeleteIDCallback callback)); + MOCK_METHOD(void, + DeleteTokenImpl, + (const std::string& authorized_entity, + const std::string& scope, + DeleteTokenCallback callback), + (override)); + MOCK_METHOD(void, DeleteIDImpl, (DeleteIDCallback callback), (override)); }; class MockInstanceIDDriver : public instance_id::InstanceIDDriver { public: MockInstanceIDDriver() : InstanceIDDriver(/*gcm_driver=*/nullptr) {} ~MockInstanceIDDriver() override = default; - - MOCK_METHOD1(GetInstanceID, InstanceID*(const std::string& app_id)); - MOCK_METHOD1(RemoveInstanceID, void(const std::string& app_id)); - MOCK_CONST_METHOD1(ExistsInstanceID, bool(const std::string& app_id)); + MOCK_METHOD(InstanceID*, + GetInstanceID, + (const std::string& app_id), + (override)); + MOCK_METHOD(void, RemoveInstanceID, (const std::string& app_id), (override)); + MOCK_METHOD(bool, + ExistsInstanceID, + (const std::string& app_id), + (const override)); }; class MockListener : public InvalidationsListener { public: - MOCK_METHOD1(OnInvalidationReceived, void(const std::string& payload)); + MOCK_METHOD(void, + OnInvalidationReceived, + (const std::string& payload), + (override)); }; class MockTokenObserver : public FCMRegistrationTokenObserver { public: - MOCK_METHOD0(OnFCMRegistrationTokenChanged, void()); + MOCK_METHOD(void, OnFCMRegistrationTokenChanged, (), (override)); }; class FCMHandlerTest : public testing::Test {
diff --git a/components/sync/invalidations/interested_data_types_manager_unittest.cc b/components/sync/invalidations/interested_data_types_manager_unittest.cc index c70797d..c1be756 100644 --- a/components/sync/invalidations/interested_data_types_manager_unittest.cc +++ b/components/sync/invalidations/interested_data_types_manager_unittest.cc
@@ -16,7 +16,10 @@ class MockDataTypesHandler : public InterestedDataTypesHandler { public: - MOCK_METHOD1(OnInterestedDataTypesChanged, void(base::OnceClosure callback)); + MOCK_METHOD(void, + OnInterestedDataTypesChanged, + (base::OnceClosure callback), + (override)); }; class InterestedDataTypesManagerTest : public testing::Test {
diff --git a/components/sync/js/js_test_util.h b/components/sync/js/js_test_util.h index 2a76cdd..56d532be 100644 --- a/components/sync/js/js_test_util.h +++ b/components/sync/js/js_test_util.h
@@ -45,8 +45,10 @@ ~MockJsBackend() override; WeakHandle<JsBackend> AsWeakHandle(); - - MOCK_METHOD1(SetJsEventHandler, void(const WeakHandle<JsEventHandler>&)); + MOCK_METHOD(void, + SetJsEventHandler, + (const WeakHandle<JsEventHandler>&), + (override)); }; class MockJsController : public JsController, @@ -54,9 +56,8 @@ public: MockJsController(); ~MockJsController() override; - - MOCK_METHOD1(AddJsEventHandler, void(JsEventHandler*)); - MOCK_METHOD1(RemoveJsEventHandler, void(JsEventHandler*)); + MOCK_METHOD(void, AddJsEventHandler, (JsEventHandler*), (override)); + MOCK_METHOD(void, RemoveJsEventHandler, (JsEventHandler*), (override)); }; class MockJsEventHandler : public JsEventHandler, @@ -66,9 +67,10 @@ ~MockJsEventHandler() override; WeakHandle<JsEventHandler> AsWeakHandle(); - - MOCK_METHOD2(HandleJsEvent, - void(const ::std::string&, const JsEventDetails&)); + MOCK_METHOD(void, + HandleJsEvent, + (const ::std::string&, const JsEventDetails&), + (override)); }; } // namespace syncer
diff --git a/components/sync/model/sync_error_factory_mock.h b/components/sync/model/sync_error_factory_mock.h index 8a339c6..6ffdd91 100644 --- a/components/sync/model/sync_error_factory_mock.h +++ b/components/sync/model/sync_error_factory_mock.h
@@ -16,10 +16,10 @@ public: SyncErrorFactoryMock(); ~SyncErrorFactoryMock() override; - - MOCK_METHOD2(CreateAndUploadError, - SyncError(const base::Location& location, - const std::string& message)); + MOCK_METHOD(SyncError, + CreateAndUploadError, + (const base::Location& location, const std::string& message), + (override)); }; } // namespace syncer
diff --git a/components/sync/model_impl/in_memory_metadata_change_list_unittest.cc b/components/sync/model_impl/in_memory_metadata_change_list_unittest.cc index 1c9edfe9..532bd8e 100644 --- a/components/sync/model_impl/in_memory_metadata_change_list_unittest.cc +++ b/components/sync/model_impl/in_memory_metadata_change_list_unittest.cc
@@ -18,13 +18,20 @@ class MockMetadataChangeList : public MetadataChangeList { public: - MOCK_METHOD1(UpdateModelTypeState, - void(const sync_pb::ModelTypeState& model_type_state)); - MOCK_METHOD0(ClearModelTypeState, void()); - MOCK_METHOD2(UpdateMetadata, - void(const std::string& storage_key, - const sync_pb::EntityMetadata& metadata)); - MOCK_METHOD1(ClearMetadata, void(const std::string& storage_key)); + MOCK_METHOD(void, + UpdateModelTypeState, + (const sync_pb::ModelTypeState& model_type_state), + (override)); + MOCK_METHOD(void, ClearModelTypeState, (), (override)); + MOCK_METHOD(void, + UpdateMetadata, + (const std::string& storage_key, + const sync_pb::EntityMetadata& metadata), + (override)); + MOCK_METHOD(void, + ClearMetadata, + (const std::string& storage_key), + (override)); }; TEST(InMemoryMetadataChangeListTest, ShouldTransferNothingIfEmptyChangeList) {
diff --git a/components/sync/model_impl/syncable_service_based_bridge_unittest.cc b/components/sync/model_impl/syncable_service_based_bridge_unittest.cc index 1419df4..aa574ce6f 100644 --- a/components/sync/model_impl/syncable_service_based_bridge_unittest.cc +++ b/components/sync/model_impl/syncable_service_based_bridge_unittest.cc
@@ -65,18 +65,21 @@ class MockSyncableService : public SyncableService { public: - MOCK_METHOD1(WaitUntilReadyToSync, void(base::OnceClosure done)); - MOCK_METHOD4(MergeDataAndStartSyncing, - base::Optional<syncer::ModelError>( - ModelType type, - const SyncDataList& initial_sync_data, - std::unique_ptr<SyncChangeProcessor> sync_processor, - std::unique_ptr<SyncErrorFactory> sync_error_factory)); - MOCK_METHOD1(StopSyncing, void(ModelType type)); - MOCK_METHOD2(ProcessSyncChanges, - base::Optional<ModelError>(const base::Location& from_here, - const SyncChangeList& change_list)); - MOCK_CONST_METHOD1(GetAllSyncData, SyncDataList(ModelType type)); + MOCK_METHOD(void, WaitUntilReadyToSync, (base::OnceClosure done), (override)); + MOCK_METHOD(base::Optional<syncer::ModelError>, + MergeDataAndStartSyncing, + (ModelType type, + const SyncDataList& initial_sync_data, + std::unique_ptr<SyncChangeProcessor> sync_processor, + std::unique_ptr<SyncErrorFactory> sync_error_factory), + (override)); + MOCK_METHOD(void, StopSyncing, (ModelType type), (override)); + MOCK_METHOD(base::Optional<ModelError>, + ProcessSyncChanges, + (const base::Location& from_here, + const SyncChangeList& change_list), + (override)); + MOCK_METHOD(SyncDataList, GetAllSyncData, (ModelType type), (const override)); }; class SyncableServiceBasedBridgeTest : public ::testing::Test {
diff --git a/components/sync/nigori/nigori_model_type_processor_unittest.cc b/components/sync/nigori/nigori_model_type_processor_unittest.cc index 6d5fb2e5..2a19e0dc 100644 --- a/components/sync/nigori/nigori_model_type_processor_unittest.cc +++ b/components/sync/nigori/nigori_model_type_processor_unittest.cc
@@ -90,25 +90,24 @@ class MockNigoriSyncBridge : public NigoriSyncBridge { public: MockNigoriSyncBridge() = default; - ~MockNigoriSyncBridge() = default; - - MOCK_METHOD1(MergeSyncData, - base::Optional<ModelError>(base::Optional<EntityData> data)); - MOCK_METHOD1(ApplySyncChanges, - base::Optional<ModelError>(base::Optional<EntityData> data)); - MOCK_METHOD0(GetData, std::unique_ptr<EntityData>()); - MOCK_METHOD2(ResolveConflict, - ConflictResolution(const EntityData& local_data, - const EntityData& remote_data)); - MOCK_METHOD0(ApplyDisableSyncChanges, void()); + ~MockNigoriSyncBridge() override = default; + MOCK_METHOD(base::Optional<ModelError>, + MergeSyncData, + (base::Optional<EntityData> data), + (override)); + MOCK_METHOD(base::Optional<ModelError>, + ApplySyncChanges, + (base::Optional<EntityData> data), + (override)); + MOCK_METHOD(std::unique_ptr<EntityData>, GetData, (), (override)); + MOCK_METHOD(void, ApplyDisableSyncChanges, (), (override)); }; class MockCommitQueue : public CommitQueue { public: MockCommitQueue() = default; - ~MockCommitQueue() = default; - - MOCK_METHOD0(NudgeForCommit, void()); + ~MockCommitQueue() override = default; + MOCK_METHOD(void, NudgeForCommit, (), (override)); }; class NigoriModelTypeProcessorTest : public testing::Test {
diff --git a/components/sync/nigori/nigori_sync_bridge_impl_unittest.cc b/components/sync/nigori/nigori_sync_bridge_impl_unittest.cc index 2065dd2..982a7ee 100644 --- a/components/sync/nigori/nigori_sync_bridge_impl_unittest.cc +++ b/components/sync/nigori/nigori_sync_bridge_impl_unittest.cc
@@ -282,43 +282,57 @@ public: MockNigoriLocalChangeProcessor() = default; ~MockNigoriLocalChangeProcessor() override = default; - - MOCK_METHOD2(ModelReadyToSync, void(NigoriSyncBridge*, NigoriMetadataBatch)); - MOCK_METHOD1(Put, void(std::unique_ptr<EntityData>)); - MOCK_METHOD0(IsEntityUnsynced, bool()); - MOCK_METHOD0(GetMetadata, NigoriMetadataBatch()); - MOCK_METHOD1(ReportError, void(const ModelError&)); - MOCK_METHOD0(GetControllerDelegate, - base::WeakPtr<ModelTypeControllerDelegate>()); - MOCK_METHOD0(IsTrackingMetadata, bool()); + MOCK_METHOD(void, + ModelReadyToSync, + (NigoriSyncBridge*, NigoriMetadataBatch), + (override)); + MOCK_METHOD(void, Put, (std::unique_ptr<EntityData>), (override)); + MOCK_METHOD(bool, IsEntityUnsynced, (), (override)); + MOCK_METHOD(NigoriMetadataBatch, GetMetadata, (), (override)); + MOCK_METHOD(void, ReportError, (const ModelError&), (override)); + MOCK_METHOD(base::WeakPtr<ModelTypeControllerDelegate>, + GetControllerDelegate, + (), + (override)); + MOCK_METHOD(bool, IsTrackingMetadata, (), (override)); }; class MockObserver : public SyncEncryptionHandler::Observer { public: MockObserver() = default; ~MockObserver() override = default; - - MOCK_METHOD2(OnPassphraseRequired, - void(const KeyDerivationParams&, const sync_pb::EncryptedData&)); - MOCK_METHOD0(OnPassphraseAccepted, void()); - MOCK_METHOD0(OnTrustedVaultKeyRequired, void()); - MOCK_METHOD0(OnTrustedVaultKeyAccepted, void()); - MOCK_METHOD2(OnBootstrapTokenUpdated, - void(const std::string&, BootstrapTokenType type)); - MOCK_METHOD2(OnEncryptedTypesChanged, void(ModelTypeSet, bool)); - MOCK_METHOD2(OnCryptographerStateChanged, - void(Cryptographer*, bool has_pending_keys)); - MOCK_METHOD2(OnPassphraseTypeChanged, void(PassphraseType, base::Time)); + MOCK_METHOD(void, + OnPassphraseRequired, + (const KeyDerivationParams&, const sync_pb::EncryptedData&), + (override)); + MOCK_METHOD(void, OnPassphraseAccepted, (), (override)); + MOCK_METHOD(void, OnTrustedVaultKeyRequired, (), (override)); + MOCK_METHOD(void, OnTrustedVaultKeyAccepted, (), (override)); + MOCK_METHOD(void, + OnBootstrapTokenUpdated, + (const std::string&, BootstrapTokenType type), + (override)); + MOCK_METHOD(void, OnEncryptedTypesChanged, (ModelTypeSet, bool), (override)); + MOCK_METHOD(void, + OnCryptographerStateChanged, + (Cryptographer*, bool has_pending_keys), + (override)); + MOCK_METHOD(void, + OnPassphraseTypeChanged, + (PassphraseType, base::Time), + (override)); }; class MockNigoriStorage : public NigoriStorage { public: MockNigoriStorage() = default; ~MockNigoriStorage() override = default; - - MOCK_METHOD1(StoreData, void(const sync_pb::NigoriLocalData&)); - MOCK_METHOD0(RestoreData, base::Optional<sync_pb::NigoriLocalData>()); - MOCK_METHOD0(ClearData, void()); + MOCK_METHOD(void, StoreData, (const sync_pb::NigoriLocalData&), (override)); + MOCK_METHOD(base::Optional<sync_pb::NigoriLocalData>, + RestoreData, + (), + (override)); + MOCK_METHOD(void, ClearData, (), (override)); }; class NigoriSyncBridgeImplTest : public testing::Test {
diff --git a/components/sync/test/model/mock_model_type_change_processor.h b/components/sync/test/model/mock_model_type_change_processor.h index 66fa6d5f..809ad30 100644 --- a/components/sync/test/model/mock_model_type_change_processor.h +++ b/components/sync/test/model/mock_model_type_change_processor.h
@@ -18,36 +18,60 @@ public: MockModelTypeChangeProcessor(); ~MockModelTypeChangeProcessor() override; - - MOCK_METHOD3(Put, - void(const std::string& storage_key, - std::unique_ptr<EntityData> entity_data, - MetadataChangeList* metadata_change_list)); - MOCK_METHOD2(Delete, - void(const std::string& storage_key, - MetadataChangeList* metadata_change_list)); - MOCK_METHOD3(UpdateStorageKey, - void(const EntityData& entity_data, - const std::string& storage_key, - MetadataChangeList* metadata_change_list)); - MOCK_METHOD1(UntrackEntityForStorageKey, - void(const std::string& storage_key)); - MOCK_METHOD1(UntrackEntityForClientTagHash, - void(const ClientTagHash& client_tag_hash)); - MOCK_METHOD1(IsEntityUnsynced, bool(const std::string& storage_key)); - MOCK_CONST_METHOD1(GetEntityCreationTime, - base::Time(const std::string& storage_key)); - MOCK_CONST_METHOD1(GetEntityModificationTime, - base::Time(const std::string& storage_key)); - MOCK_METHOD1(OnModelStarting, void(ModelTypeSyncBridge* bridge)); - MOCK_METHOD1(ModelReadyToSync, void(std::unique_ptr<MetadataBatch> batch)); - MOCK_METHOD0(IsTrackingMetadata, bool()); - MOCK_METHOD0(TrackedAccountId, std::string()); - MOCK_METHOD0(TrackedCacheGuid, std::string()); - MOCK_METHOD1(ReportError, void(const ModelError& error)); - MOCK_CONST_METHOD0(GetError, base::Optional<ModelError>()); - MOCK_METHOD0(GetControllerDelegate, - base::WeakPtr<ModelTypeControllerDelegate>()); + MOCK_METHOD(void, + Put, + (const std::string& storage_key, + std::unique_ptr<EntityData> entity_data, + MetadataChangeList* metadata_change_list), + (override)); + MOCK_METHOD(void, + Delete, + (const std::string& storage_key, + MetadataChangeList* metadata_change_list), + (override)); + MOCK_METHOD(void, + UpdateStorageKey, + (const EntityData& entity_data, + const std::string& storage_key, + MetadataChangeList* metadata_change_list), + (override)); + MOCK_METHOD(void, + UntrackEntityForStorageKey, + (const std::string& storage_key), + (override)); + MOCK_METHOD(void, + UntrackEntityForClientTagHash, + (const ClientTagHash& client_tag_hash), + (override)); + MOCK_METHOD(bool, + IsEntityUnsynced, + (const std::string& storage_key), + (override)); + MOCK_METHOD(base::Time, + GetEntityCreationTime, + (const std::string& storage_key), + (const override)); + MOCK_METHOD(base::Time, + GetEntityModificationTime, + (const std::string& storage_key), + (const override)); + MOCK_METHOD(void, + OnModelStarting, + (ModelTypeSyncBridge * bridge), + (override)); + MOCK_METHOD(void, + ModelReadyToSync, + (std::unique_ptr<MetadataBatch> batch), + (override)); + MOCK_METHOD(bool, IsTrackingMetadata, (), (override)); + MOCK_METHOD(std::string, TrackedAccountId, (), (override)); + MOCK_METHOD(std::string, TrackedCacheGuid, (), (override)); + MOCK_METHOD(void, ReportError, (const ModelError& error), (override)); + MOCK_METHOD(base::Optional<ModelError>, GetError, (), (const override)); + MOCK_METHOD(base::WeakPtr<ModelTypeControllerDelegate>, + GetControllerDelegate, + (), + (override)); // Returns a processor that forwards all calls to // |this|. |*this| must outlive the returned processor.
diff --git a/components/sync/trusted_vault/standalone_trusted_vault_backend_unittest.cc b/components/sync/trusted_vault/standalone_trusted_vault_backend_unittest.cc index 6d472df..e9c1a71 100644 --- a/components/sync/trusted_vault/standalone_trusted_vault_backend_unittest.cc +++ b/components/sync/trusted_vault/standalone_trusted_vault_backend_unittest.cc
@@ -49,27 +49,29 @@ public: MockDelegate() = default; ~MockDelegate() override = default; - - MOCK_METHOD0(NotifyRecoverabilityDegradedChanged, void()); + MOCK_METHOD(void, NotifyRecoverabilityDegradedChanged, (), (override)); }; class MockTrustedVaultConnection : public TrustedVaultConnection { public: MockTrustedVaultConnection() = default; ~MockTrustedVaultConnection() override = default; - - MOCK_METHOD5(RegisterAuthenticationFactor, - void(const CoreAccountInfo&, - const std::vector<uint8_t>&, - int, - const SecureBoxPublicKey&, - RegisterAuthenticationFactorCallback)); - MOCK_METHOD5(DownloadKeys, - void(const CoreAccountInfo&, - const std::vector<uint8_t>&, - int, - std::unique_ptr<SecureBoxKeyPair>, - DownloadKeysCallback)); + MOCK_METHOD(void, + RegisterAuthenticationFactor, + (const CoreAccountInfo&, + const std::vector<uint8_t>&, + int, + const SecureBoxPublicKey&, + RegisterAuthenticationFactorCallback), + (override)); + MOCK_METHOD(void, + DownloadKeys, + (const CoreAccountInfo&, + const std::vector<uint8_t>&, + int, + std::unique_ptr<SecureBoxKeyPair>, + DownloadKeysCallback), + (override)); }; class StandaloneTrustedVaultBackendTest : public testing::Test {
diff --git a/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc b/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc index 9651f2e..0a590c3f 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc +++ b/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc
@@ -153,7 +153,7 @@ class MockCommitQueue : public syncer::CommitQueue { public: - MOCK_METHOD0(NudgeForCommit, void()); + MOCK_METHOD(void, NudgeForCommit, (), (override)); }; class ProxyCommitQueue : public syncer::CommitQueue {
diff --git a/components/sync_device_info/local_device_info_provider_impl_unittest.cc b/components/sync_device_info/local_device_info_provider_impl_unittest.cc index dbeceac..68f52076 100644 --- a/components/sync_device_info/local_device_info_provider_impl_unittest.cc +++ b/components/sync_device_info/local_device_info_provider_impl_unittest.cc
@@ -41,12 +41,14 @@ MockDeviceInfoSyncClient() = default; ~MockDeviceInfoSyncClient() = default; - MOCK_CONST_METHOD0(GetSigninScopedDeviceId, std::string()); - MOCK_CONST_METHOD0(GetSendTabToSelfReceivingEnabled, bool()); - MOCK_CONST_METHOD0(GetLocalSharingInfo, - base::Optional<DeviceInfo::SharingInfo>()); - MOCK_CONST_METHOD0(GetFCMRegistrationToken, std::string()); - MOCK_CONST_METHOD0(GetInterestedDataTypes, ModelTypeSet()); + MOCK_METHOD(std::string, GetSigninScopedDeviceId, (), (const override)); + MOCK_METHOD(bool, GetSendTabToSelfReceivingEnabled, (), (const override)); + MOCK_METHOD(base::Optional<DeviceInfo::SharingInfo>, + GetLocalSharingInfo, + (), + (const override)); + MOCK_METHOD(std::string, GetFCMRegistrationToken, (), (const override)); + MOCK_METHOD(ModelTypeSet, GetInterestedDataTypes, (), (const override)); private: DISALLOW_COPY_AND_ASSIGN(MockDeviceInfoSyncClient);
diff --git a/components/sync_sessions/local_session_event_handler_impl_unittest.cc b/components/sync_sessions/local_session_event_handler_impl_unittest.cc index 1a89835..9e73ed0 100644 --- a/components/sync_sessions/local_session_event_handler_impl_unittest.cc +++ b/components/sync_sessions/local_session_event_handler_impl_unittest.cc
@@ -58,23 +58,28 @@ class MockWriteBatch : public LocalSessionEventHandlerImpl::WriteBatch { public: - MockWriteBatch() {} - ~MockWriteBatch() override {} - - MOCK_METHOD1(Delete, void(int tab_node_id)); - MOCK_METHOD1(Put, void(std::unique_ptr<sync_pb::SessionSpecifics> specifics)); - MOCK_METHOD0(Commit, void()); + MockWriteBatch() = default; + ~MockWriteBatch() override = default; + MOCK_METHOD(void, Delete, (int tab_node_id), (override)); + MOCK_METHOD(void, + Put, + (std::unique_ptr<sync_pb::SessionSpecifics> specifics), + (override)); + MOCK_METHOD(void, Commit, (), (override)); }; class MockDelegate : public LocalSessionEventHandlerImpl::Delegate { public: - ~MockDelegate() override {} - - MOCK_METHOD0(CreateLocalSessionWriteBatch, - std::unique_ptr<LocalSessionEventHandlerImpl::WriteBatch>()); - MOCK_METHOD1(IsTabNodeUnsynced, bool(int tab_node_id)); - MOCK_METHOD2(TrackLocalNavigationId, - void(base::Time timestamp, int unique_id)); + ~MockDelegate() override = default; + MOCK_METHOD(std::unique_ptr<LocalSessionEventHandlerImpl::WriteBatch>, + CreateLocalSessionWriteBatch, + (), + (override)); + MOCK_METHOD(bool, IsTabNodeUnsynced, (int tab_node_id), (override)); + MOCK_METHOD(void, + TrackLocalNavigationId, + (base::Time timestamp, int unique_id), + (override)); }; class LocalSessionEventHandlerImplTest : public testing::Test {
diff --git a/components/sync_sessions/mock_sync_sessions_client.h b/components/sync_sessions/mock_sync_sessions_client.h index fa2bd545..52e4f6b 100644 --- a/components/sync_sessions/mock_sync_sessions_client.h +++ b/components/sync_sessions/mock_sync_sessions_client.h
@@ -16,14 +16,21 @@ // By default, ShouldSyncURL() always returns true. MockSyncSessionsClient(); ~MockSyncSessionsClient() override; - - MOCK_METHOD0(GetSessionSyncPrefs, SessionSyncPrefs*()); - MOCK_METHOD0(GetStoreFactory, syncer::RepeatingModelTypeStoreFactory()); - MOCK_METHOD0(ClearAllOnDemandFavicons, void()); - MOCK_CONST_METHOD1(ShouldSyncURL, bool(const GURL& url)); - MOCK_METHOD0(GetSyncedWindowDelegatesGetter, SyncedWindowDelegatesGetter*()); - MOCK_METHOD0(GetLocalSessionEventRouter, LocalSessionEventRouter*()); - MOCK_METHOD0(IsProxyTabsSyncRunning, bool()); + MOCK_METHOD(SessionSyncPrefs*, GetSessionSyncPrefs, (), (override)); + MOCK_METHOD(syncer::RepeatingModelTypeStoreFactory, + GetStoreFactory, + (), + (override)); + MOCK_METHOD(void, ClearAllOnDemandFavicons, (), (override)); + MOCK_METHOD(bool, ShouldSyncURL, (const GURL& url), (const override)); + MOCK_METHOD(SyncedWindowDelegatesGetter*, + GetSyncedWindowDelegatesGetter, + (), + (override)); + MOCK_METHOD(LocalSessionEventRouter*, + GetLocalSessionEventRouter, + (), + (override)); }; } // namespace sync_sessions
diff --git a/components/sync_sessions/session_store_unittest.cc b/components/sync_sessions/session_store_unittest.cc index ab8b00e..00aef86 100644 --- a/components/sync_sessions/session_store_unittest.cc +++ b/components/sync_sessions/session_store_unittest.cc
@@ -57,10 +57,12 @@ // b) conveniently exposes the last instantiated session store. class MockOpenCallback { public: - MOCK_METHOD3(Run, - void(const base::Optional<syncer::ModelError>& error, - SessionStore* store, - MetadataBatch* metadata_batch)); + MOCK_METHOD(void, + Run, + (const base::Optional<syncer::ModelError>& error, + SessionStore* store, + MetadataBatch* metadata_batch), + ()); SessionStore::OpenCallback Get() { return base::BindOnce(
diff --git a/components/test/data/autofill_assistant/html/autofill_assistant_target_website.html b/components/test/data/autofill_assistant/html/autofill_assistant_target_website.html index 9e77f308..74b46a4 100644 --- a/components/test/data/autofill_assistant/html/autofill_assistant_target_website.html +++ b/components/test/data/autofill_assistant/html/autofill_assistant_target_website.html
@@ -137,7 +137,7 @@ <body onload="moveTouchAreaTwoAndThree()"> <!-- Touch areas can be accessed without needing scroll. --> <div> - <p id="touch_area_one" ontouchend="removeTouchArea('touch_area_one')"> + <p id="touch_area_one" ontouchend="removeTouchArea('touch_area_one')" onmouseup="removeTouchArea('touch_area_one')"> Touchable Area One</p> <br> </div> @@ -175,7 +175,7 @@ <br> </div> <div> - <p id="touch_area_six" ontouchend="removeTouchArea('touch_area_six')"> + <p id="touch_area_six" ontouchend="removeTouchArea('touch_area_six')" onclick="removeTouchArea('touch_area_six')"> Touchable Area Six</p> <br> </div>
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index 5f08cdc..5daaddd6 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -382,6 +382,7 @@ deps = [ "//base", "//gpu/config", + "//third_party/libyuv", ] if (is_win) {
diff --git a/components/viz/service/display_embedder/DEPS b/components/viz/service/display_embedder/DEPS index 28c8b9f..306d174 100644 --- a/components/viz/service/display_embedder/DEPS +++ b/components/viz/service/display_embedder/DEPS
@@ -33,6 +33,7 @@ "+third_party/dawn/src/include", "+third_party/khronos/GLES2/gl2.h", "+third_party/khronos/GLES2/gl2ext.h", + "+third_party/libyuv", "+third_party/skia", "+ui/accelerated_widget_mac", "+ui/display",
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 0ac653c..7a32e1c 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -42,6 +42,7 @@ #include "gpu/ipc/common/gpu_surface_lookup.h" #include "gpu/vulkan/buildflags.h" #include "skia/buildflags.h" +#include "third_party/libyuv/include/libyuv/planar_functions.h" #include "third_party/skia/include/core/SkDeferredDisplayList.h" #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -134,21 +135,15 @@ int u_out_stride, uint8_t* v_out, int v_out_stride) const override { - const auto CopyPlane = [](const uint8_t* src, int src_stride, int width, - int height, uint8_t* out, int out_stride) { - for (int i = 0; i < height; ++i, src += src_stride, out += out_stride) { - memcpy(out, src, width); - } - }; auto* data0 = static_cast<const uint8_t*>(result_->data(0)); auto* data1 = static_cast<const uint8_t*>(result_->data(1)); auto* data2 = static_cast<const uint8_t*>(result_->data(2)); - CopyPlane(data0, result_->rowBytes(0), width(0), height(0), y_out, - y_out_stride); - CopyPlane(data1, result_->rowBytes(1), width(1), height(1), u_out, - u_out_stride); - CopyPlane(data2, result_->rowBytes(2), width(2), height(2), v_out, - v_out_stride); + libyuv::CopyPlane(data0, result_->rowBytes(0), y_out, y_out_stride, + width(0), height(0)); + libyuv::CopyPlane(data1, result_->rowBytes(1), u_out, u_out_stride, + width(1), height(1)); + libyuv::CopyPlane(data2, result_->rowBytes(2), v_out, v_out_stride, + width(2), height(2)); return true; }
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc index 4497eb0..35232960 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -5048,4 +5048,29 @@ EXPECT_EQ("POST", root_frame_host()->last_http_method()); } +// Check Chrome won't attempt automatically loading the /favicon.ico if it would +// be blocked by CSP. +IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, + DefaultFaviconVersusCSP) { + auto navigate = [&](std::string csp) { + EXPECT_TRUE(NavigateToURL( + shell(), embedded_test_server()->GetURL( + "/set-header?Content-Security-Policy: " + csp))); + // DidStopLoading() and UpdateFaviconURL() are sent together from the same + // task. However we have waited only for DidStopLoading(). Make a round trip + // with the renderer to ensure UpdateFaviconURL() to be received. + EXPECT_TRUE(ExecJs(root_frame_host(), "")); + }; + + // Blocked by CSP. + navigate("img-src 'none'"); + EXPECT_EQ(0u, web_contents()->GetFaviconURLs().size()); + + // Allowed by CSP. + navigate("img-src *"); + EXPECT_EQ(1u, web_contents()->GetFaviconURLs().size()); + EXPECT_EQ("/favicon.ico", + web_contents()->GetFaviconURLs()[0]->icon_url.path()); +} + } // namespace content
diff --git a/content/browser/service_worker/service_worker_disk_cache.cc b/content/browser/service_worker/service_worker_disk_cache.cc index 7a3020e1..a0b27259 100644 --- a/content/browser/service_worker/service_worker_disk_cache.cc +++ b/content/browser/service_worker/service_worker_disk_cache.cc
@@ -4,14 +4,407 @@ #include "content/browser/service_worker/service_worker_disk_cache.h" +#include <limits> #include <utility> -#include "net/base/io_buffer.h" -#include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/callback.h" +#include "base/callback_helpers.h" +#include "base/check.h" +#include "base/files/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/single_thread_task_runner.h" +#include "base/stl_util.h" +#include "base/strings/string_number_conversions.h" +#include "net/base/cache_type.h" +#include "net/base/completion_repeating_callback.h" +#include "net/base/net_errors.h" namespace content { -ServiceWorkerDiskCache::ServiceWorkerDiskCache() - : AppCacheDiskCache(/*use_simple_cache=*/true) {} +// A callback shim that provides storage for the 'backend_ptr' value +// and will delete a resulting ptr if completion occurs after the +// callback has been canceled. +class ServiceWorkerDiskCache::CreateBackendCallbackShim + : public base::RefCounted<CreateBackendCallbackShim> { + public: + explicit CreateBackendCallbackShim(ServiceWorkerDiskCache* object) + : service_worker_disk_cache_(object) {} + + void Cancel() { service_worker_disk_cache_ = nullptr; } + + void Callback(int return_value) { + if (service_worker_disk_cache_) + service_worker_disk_cache_->OnCreateBackendComplete(return_value); + } + + std::unique_ptr<disk_cache::Backend> backend_ptr_; // Accessed directly. + + private: + friend class base::RefCounted<CreateBackendCallbackShim>; + + ~CreateBackendCallbackShim() = default; + + ServiceWorkerDiskCache* service_worker_disk_cache_; // Unowned pointer. +}; + +ServiceWorkerDiskCacheEntry::ServiceWorkerDiskCacheEntry( + disk_cache::Entry* disk_cache_entry, + ServiceWorkerDiskCache* cache) + : disk_cache_entry_(disk_cache_entry), cache_(cache) { + DCHECK(disk_cache_entry); + DCHECK(cache); + cache_->AddOpenEntry(this); +} + +ServiceWorkerDiskCacheEntry::~ServiceWorkerDiskCacheEntry() { + if (cache_) + cache_->RemoveOpenEntry(this); +} + +int ServiceWorkerDiskCacheEntry::Read(int index, + int64_t offset, + net::IOBuffer* buf, + int buf_len, + net::CompletionOnceCallback callback) { + if (offset < 0 || offset > std::numeric_limits<int32_t>::max()) + return net::ERR_INVALID_ARGUMENT; + if (!disk_cache_entry_) + return net::ERR_ABORTED; + return disk_cache_entry_->ReadData(index, static_cast<int>(offset), buf, + buf_len, std::move(callback)); +} + +int ServiceWorkerDiskCacheEntry::Write(int index, + int64_t offset, + net::IOBuffer* buf, + int buf_len, + net::CompletionOnceCallback callback) { + if (offset < 0 || offset > std::numeric_limits<int32_t>::max()) + return net::ERR_INVALID_ARGUMENT; + if (!disk_cache_entry_) + return net::ERR_ABORTED; + const bool kTruncate = true; + return disk_cache_entry_->WriteData(index, static_cast<int>(offset), buf, + buf_len, std::move(callback), kTruncate); +} + +int64_t ServiceWorkerDiskCacheEntry::GetSize(int index) { + return disk_cache_entry_ ? disk_cache_entry_->GetDataSize(index) : 0L; +} + +void ServiceWorkerDiskCacheEntry::Close() { + if (disk_cache_entry_) + disk_cache_entry_->Close(); + delete this; +} + +void ServiceWorkerDiskCacheEntry::Abandon() { + cache_ = nullptr; + disk_cache_entry_->Close(); + disk_cache_entry_ = nullptr; +} + +namespace { + +// Separate object to hold state for each Create, Delete, or Doom call +// while the call is in-flight and to produce an EntryImpl upon completion. +class ActiveCall : public base::RefCounted<ActiveCall> { + public: + ActiveCall(const base::WeakPtr<ServiceWorkerDiskCache>& owner, + ServiceWorkerDiskCacheEntry** entry, + net::CompletionOnceCallback callback) + : owner_(owner), entry_(entry), callback_(std::move(callback)) { + DCHECK(owner_); + } + + static net::Error CreateEntry( + const base::WeakPtr<ServiceWorkerDiskCache>& owner, + int64_t key, + ServiceWorkerDiskCacheEntry** entry, + net::CompletionOnceCallback callback) { + scoped_refptr<ActiveCall> active_call = + base::MakeRefCounted<ActiveCall>(owner, entry, std::move(callback)); + disk_cache::EntryResult result = owner->disk_cache()->CreateEntry( + base::NumberToString(key), net::HIGHEST, + base::BindOnce(&ActiveCall::OnAsyncCompletion, active_call)); + return active_call->HandleImmediateReturnValue(std::move(result)); + } + + static net::Error OpenEntry( + const base::WeakPtr<ServiceWorkerDiskCache>& owner, + int64_t key, + ServiceWorkerDiskCacheEntry** entry, + net::CompletionOnceCallback callback) { + scoped_refptr<ActiveCall> active_call = + base::MakeRefCounted<ActiveCall>(owner, entry, std::move(callback)); + disk_cache::EntryResult result = owner->disk_cache()->OpenEntry( + base::NumberToString(key), net::HIGHEST, + base::BindOnce(&ActiveCall::OnAsyncCompletion, active_call)); + return active_call->HandleImmediateReturnValue(std::move(result)); + } + + static net::Error DoomEntry( + const base::WeakPtr<ServiceWorkerDiskCache>& owner, + int64_t key, + net::CompletionOnceCallback callback) { + return owner->disk_cache()->DoomEntry(base::NumberToString(key), + net::HIGHEST, std::move(callback)); + } + + private: + friend class base::RefCounted<ActiveCall>; + + ~ActiveCall() = default; + + net::Error HandleImmediateReturnValue(disk_cache::EntryResult result) { + net::Error rv = result.net_error(); + if (rv == net::ERR_IO_PENDING) { + // OnAsyncCompletion will be called later. + return rv; + } + + if (rv == net::OK) { + *entry_ = + new ServiceWorkerDiskCacheEntry(result.ReleaseEntry(), owner_.get()); + } + + return rv; + } + + void OnAsyncCompletion(disk_cache::EntryResult result) { + int rv = result.net_error(); + if (rv == net::OK) { + if (owner_) { + *entry_ = new ServiceWorkerDiskCacheEntry(result.ReleaseEntry(), + owner_.get()); + } else { + result.ReleaseEntry()->Close(); + rv = net::ERR_ABORTED; + } + } + std::move(callback_).Run(rv); + } + + base::WeakPtr<ServiceWorkerDiskCache> owner_; + ServiceWorkerDiskCacheEntry** entry_; + net::CompletionOnceCallback callback_; +}; + +} // namespace + +ServiceWorkerDiskCache::ServiceWorkerDiskCache() = default; + +ServiceWorkerDiskCache::~ServiceWorkerDiskCache() { + Disable(); +} + +net::Error ServiceWorkerDiskCache::InitWithDiskBackend( + const base::FilePath& disk_cache_directory, + bool force, + base::OnceClosure post_cleanup_callback, + net::CompletionOnceCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return Init(net::APP_CACHE, disk_cache_directory, + std::numeric_limits<int64_t>::max(), force, + std::move(post_cleanup_callback), std::move(callback)); +} + +net::Error ServiceWorkerDiskCache::InitWithMemBackend( + int64_t mem_cache_size, + net::CompletionOnceCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return Init(net::MEMORY_CACHE, base::FilePath(), mem_cache_size, false, + base::OnceClosure(), std::move(callback)); +} + +void ServiceWorkerDiskCache::Disable() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (is_disabled_) + return; + + is_disabled_ = true; + + if (create_backend_callback_.get()) { + create_backend_callback_->Cancel(); + create_backend_callback_ = nullptr; + OnCreateBackendComplete(net::ERR_ABORTED); + } + + // We need to close open file handles in order to reinitialize the + // service worker system on the fly. File handles held in both entries and in + // the main disk_cache::Backend class need to be released. + for (ServiceWorkerDiskCacheEntry* entry : open_entries_) { + entry->Abandon(); + } + open_entries_.clear(); + disk_cache_.reset(); +} + +net::Error ServiceWorkerDiskCache::CreateEntry( + int64_t key, + ServiceWorkerDiskCacheEntry** entry, + net::CompletionOnceCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(entry); + DCHECK(!callback.is_null()); + if (is_disabled_) + return net::ERR_ABORTED; + + if (is_initializing_or_waiting_to_initialize()) { + pending_calls_.emplace_back(PendingCallType::kCreate, key, entry, + std::move(callback)); + return net::ERR_IO_PENDING; + } + + if (!disk_cache_) + return net::ERR_FAILED; + + return ActiveCall::CreateEntry(weak_factory_.GetWeakPtr(), key, entry, + std::move(callback)); +} + +net::Error ServiceWorkerDiskCache::OpenEntry( + int64_t key, + ServiceWorkerDiskCacheEntry** entry, + net::CompletionOnceCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(entry); + DCHECK(!callback.is_null()); + if (is_disabled_) + return net::ERR_ABORTED; + + if (is_initializing_or_waiting_to_initialize()) { + pending_calls_.emplace_back(PendingCallType::kOpen, key, entry, + std::move(callback)); + return net::ERR_IO_PENDING; + } + + if (!disk_cache_) + return net::ERR_FAILED; + + return ActiveCall::OpenEntry(weak_factory_.GetWeakPtr(), key, entry, + std::move(callback)); +} + +net::Error ServiceWorkerDiskCache::DoomEntry( + int64_t key, + net::CompletionOnceCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!callback.is_null()); + if (is_disabled_) + return net::ERR_ABORTED; + + if (is_initializing_or_waiting_to_initialize()) { + pending_calls_.emplace_back(PendingCallType::kDoom, key, nullptr, + std::move(callback)); + return net::ERR_IO_PENDING; + } + + if (!disk_cache_) + return net::ERR_FAILED; + + return ActiveCall::DoomEntry(weak_factory_.GetWeakPtr(), key, + std::move(callback)); +} + +base::WeakPtr<ServiceWorkerDiskCache> ServiceWorkerDiskCache::GetWeakPtr() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return weak_factory_.GetWeakPtr(); +} + +ServiceWorkerDiskCache::PendingCall::PendingCall( + PendingCallType call_type, + int64_t key, + ServiceWorkerDiskCacheEntry** entry, + net::CompletionOnceCallback callback) + : call_type(call_type), + key(key), + entry(entry), + callback(std::move(callback)) {} + +ServiceWorkerDiskCache::PendingCall::PendingCall(PendingCall&& other) = default; + +ServiceWorkerDiskCache::PendingCall::~PendingCall() = default; + +net::Error ServiceWorkerDiskCache::Init(net::CacheType cache_type, + const base::FilePath& cache_directory, + int64_t cache_size, + bool force, + base::OnceClosure post_cleanup_callback, + net::CompletionOnceCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!is_initializing_or_waiting_to_initialize() && !disk_cache_.get()); + is_disabled_ = false; + create_backend_callback_ = + base::MakeRefCounted<CreateBackendCallbackShim>(this); + disk_cache::ResetHandling reset_handling = + force ? disk_cache::ResetHandling::kResetOnError + : disk_cache::ResetHandling::kNeverReset; + + net::Error return_value = disk_cache::CreateCacheBackend( + cache_type, net::CACHE_BACKEND_SIMPLE, cache_directory, cache_size, + reset_handling, nullptr, &(create_backend_callback_->backend_ptr_), + std::move(post_cleanup_callback), + base::BindOnce(&CreateBackendCallbackShim::Callback, + create_backend_callback_)); + if (return_value == net::ERR_IO_PENDING) + init_callback_ = std::move(callback); + else + OnCreateBackendComplete(return_value); + return return_value; +} + +void ServiceWorkerDiskCache::OnCreateBackendComplete(int return_value) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (return_value == net::OK) { + disk_cache_ = std::move(create_backend_callback_->backend_ptr_); + } + create_backend_callback_ = nullptr; + + // Invoke our clients callback function. + if (!init_callback_.is_null()) { + std::move(init_callback_).Run(return_value); + } + + // Service pending calls that were queued up while we were initializing. + for (auto& call : pending_calls_) { + // This is safe, because the callback will only be called once. + net::CompletionRepeatingCallback copyable_callback = + base::AdaptCallbackForRepeating(std::move(call.callback)); + return_value = net::ERR_FAILED; + switch (call.call_type) { + case PendingCallType::kCreate: + return_value = CreateEntry(call.key, call.entry, copyable_callback); + break; + case PendingCallType::kOpen: + return_value = OpenEntry(call.key, call.entry, copyable_callback); + break; + case PendingCallType::kDoom: + return_value = DoomEntry(call.key, copyable_callback); + break; + } + // disk_cache::{Create,Open,Doom}Entry() call their callbacks iff they + // return net::ERR_IO_PENDING. In this case, the callback was not called. + // However, the corresponding ServiceWorkerDiskCache wrapper returned + // net::ERR_IO_PENDING as it queued up the pending call. To follow the + // disk_cache API contract, we need to call the callback ourselves here. + if (return_value != net::ERR_IO_PENDING) + copyable_callback.Run(return_value); + } + pending_calls_.clear(); +} + +void ServiceWorkerDiskCache::AddOpenEntry(ServiceWorkerDiskCacheEntry* entry) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + open_entries_.insert(entry); +} + +void ServiceWorkerDiskCache::RemoveOpenEntry( + ServiceWorkerDiskCacheEntry* entry) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + open_entries_.erase(entry); +} } // namespace content
diff --git a/content/browser/service_worker/service_worker_disk_cache.h b/content/browser/service_worker/service_worker_disk_cache.h index bed72d7..1d2ef6a 100644 --- a/content/browser/service_worker/service_worker_disk_cache.h +++ b/content/browser/service_worker/service_worker_disk_cache.h
@@ -5,20 +5,161 @@ #ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_H_ #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_H_ -#include "content/browser/appcache/appcache_disk_cache.h" +#include <stdint.h> + +#include <memory> +#include <set> +#include <vector> + +#include "base/callback_forward.h" +#include "base/memory/ref_counted.h" +#include "base/sequence_checker.h" #include "content/common/content_export.h" +#include "net/base/completion_once_callback.h" +#include "net/disk_cache/disk_cache.h" namespace content { -// Wholesale reusage of the appcache code for response reading, -// writing, and storage. See the corresponding class in that -// library for doc comments and other details. -// TODO(michaeln): If this reuse sticks, refactor/move the -// resused classes to a more common location. +// TODO(crbug.com/586174): Use disk_cache::EntryResult for better lifetime +// management of disk cache entries. Using EntryResult will eliminate allocating +// raw pointers and static methods in service worker resource readers/writers. -class CONTENT_EXPORT ServiceWorkerDiskCache : public AppCacheDiskCache { +class ServiceWorkerDiskCache; + +// Thin wrapper around disk_cache::Entry. +class CONTENT_EXPORT ServiceWorkerDiskCacheEntry { + public: + // The newly created entry takes ownership of `disk_cache_entry` and closes it + // on destruction. |cache| must outlive the newly created entry. + ServiceWorkerDiskCacheEntry(disk_cache::Entry* disk_cache_entry, + ServiceWorkerDiskCache* cache); + + // See `disk_cache::Entry::ReadData()`. + int Read(int index, + int64_t offset, + net::IOBuffer* buf, + int buf_len, + net::CompletionOnceCallback callback); + + // See `disk_cache::Entry::WriteData()`. + int Write(int index, + int64_t offset, + net::IOBuffer* buf, + int buf_len, + net::CompletionOnceCallback callback); + int64_t GetSize(int index); + // Closes the disk cache and destroyes the instance. + void Close(); + + // Should only be called by ServiceWorkerDiskCache. + void Abandon(); + + private: + // Call Close() instead of calling this directly. + ~ServiceWorkerDiskCacheEntry(); + + // The disk_cache::Entry is owned by this entry and closed on destruction. + disk_cache::Entry* disk_cache_entry_; + + // The cache that this entry belongs to. + ServiceWorkerDiskCache* cache_; +}; + +// net::DiskCache wrapper for the cache used by service worker resources. +// +// Provides ways to create/open/doom service worker disk cache entries. +class CONTENT_EXPORT ServiceWorkerDiskCache { public: ServiceWorkerDiskCache(); + ~ServiceWorkerDiskCache(); + + // Initializes the object to use disk backed storage. + net::Error InitWithDiskBackend(const base::FilePath& disk_cache_directory, + bool force, + base::OnceClosure post_cleanup_callback, + net::CompletionOnceCallback callback); + + // Initializes the object to use memory only storage. + // This is used for Chrome's incognito browsing. + net::Error InitWithMemBackend(int64_t disk_cache_size, + net::CompletionOnceCallback callback); + + void Disable(); + bool is_disabled() const { return is_disabled_; } + + net::Error CreateEntry(int64_t key, + ServiceWorkerDiskCacheEntry** entry, + net::CompletionOnceCallback callback); + net::Error OpenEntry(int64_t key, + ServiceWorkerDiskCacheEntry** entry, + net::CompletionOnceCallback callback); + net::Error DoomEntry(int64_t key, net::CompletionOnceCallback callback); + + base::WeakPtr<ServiceWorkerDiskCache> GetWeakPtr(); + + void set_is_waiting_to_initialize(bool is_waiting_to_initialize) { + is_waiting_to_initialize_ = is_waiting_to_initialize; + } + + disk_cache::Backend* disk_cache() { return disk_cache_.get(); } + + private: + class CreateBackendCallbackShim; + friend class ServiceWorkerDiskCacheEntry; + + // PendingCalls allow CreateEntry, OpenEntry, and DoomEntry to be called + // immediately after construction, without waiting for the + // underlying disk_cache::Backend to be fully constructed. Early + // calls are queued up and serviced once the disk_cache::Backend is + // really ready to go. + enum class PendingCallType { kCreate, kOpen, kDoom }; + struct PendingCall { + PendingCall(PendingCallType call_type, + int64_t key, + ServiceWorkerDiskCacheEntry** entry, + net::CompletionOnceCallback callback); + PendingCall(PendingCall&& other); + PendingCall(const PendingCall&) = delete; + PendingCall& operator=(const PendingCall&) = delete; + PendingCall& operator=(PendingCall&&) = delete; + + ~PendingCall(); + + const PendingCallType call_type; + const int64_t key; + ServiceWorkerDiskCacheEntry** const entry; + net::CompletionOnceCallback callback; + }; + + bool is_initializing_or_waiting_to_initialize() const { + return create_backend_callback_.get() != nullptr || + is_waiting_to_initialize_; + } + + net::Error Init(net::CacheType cache_type, + const base::FilePath& directory, + int64_t cache_size, + bool force, + base::OnceClosure post_cleanup_callback, + net::CompletionOnceCallback callback); + void OnCreateBackendComplete(int return_value); + + // Called by ServiceWorkerDiskCacheEntry constructor. + void AddOpenEntry(ServiceWorkerDiskCacheEntry* entry); + // Called by ServiceWorkerDiskCacheEntry destructor. + void RemoveOpenEntry(ServiceWorkerDiskCacheEntry* entry); + + bool is_disabled_ = false; + bool is_waiting_to_initialize_ = false; + net::CompletionOnceCallback init_callback_; + scoped_refptr<CreateBackendCallbackShim> create_backend_callback_; + std::vector<PendingCall> pending_calls_; + std::set<ServiceWorkerDiskCacheEntry*> open_entries_; + std::unique_ptr<disk_cache::Backend> disk_cache_; + + SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory<ServiceWorkerDiskCache> weak_factory_{this}; }; } // namespace content
diff --git a/content/browser/service_worker/service_worker_resource_ops.cc b/content/browser/service_worker/service_worker_resource_ops.cc index fec55e39..cf0dd3a2 100644 --- a/content/browser/service_worker/service_worker_resource_ops.cc +++ b/content/browser/service_worker/service_worker_resource_ops.cc
@@ -124,8 +124,9 @@ return std::move(buffer_); } -DiskEntryCreator::DiskEntryCreator(int64_t resource_id, - base::WeakPtr<AppCacheDiskCache> disk_cache) +DiskEntryCreator::DiskEntryCreator( + int64_t resource_id, + base::WeakPtr<ServiceWorkerDiskCache> disk_cache) : resource_id_(resource_id), disk_cache_(std::move(disk_cache)) { DCHECK_NE(resource_id_, blink::mojom::kInvalidServiceWorkerResourceId); DCHECK(disk_cache_); @@ -154,7 +155,7 @@ return; } - AppCacheDiskCacheEntry** entry_ptr = new AppCacheDiskCacheEntry*; + ServiceWorkerDiskCacheEntry** entry_ptr = new ServiceWorkerDiskCacheEntry*; creation_phase_ = CreationPhase::kInitialAttempt; int rv = disk_cache_->CreateEntry( resource_id_, entry_ptr, @@ -168,7 +169,7 @@ // static void DiskEntryCreator::DidCreateEntryForFirstAttempt( base::WeakPtr<DiskEntryCreator> entry_creator, - AppCacheDiskCacheEntry** entry, + ServiceWorkerDiskCacheEntry** entry, int rv) { if (!entry_creator) { delete entry; @@ -223,7 +224,7 @@ } entry_creator->creation_phase_ = CreationPhase::kSecondAttempt; - auto** entry_ptr = new AppCacheDiskCacheEntry*; + auto** entry_ptr = new ServiceWorkerDiskCacheEntry*; rv = entry_creator->disk_cache_->CreateEntry( entry_creator->resource_id_, entry_ptr, base::BindOnce(&DiskEntryCreator::DidCreateEntryForSecondAttempt, @@ -236,7 +237,7 @@ // static void DiskEntryCreator::DidCreateEntryForSecondAttempt( base::WeakPtr<DiskEntryCreator> entry_creator, - AppCacheDiskCacheEntry** entry, + ServiceWorkerDiskCacheEntry** entry, int rv) { if (!entry_creator) { delete entry; @@ -272,8 +273,9 @@ std::move(ensure_entry_is_created_callback_).Run(); } -DiskEntryOpener::DiskEntryOpener(int64_t resource_id, - base::WeakPtr<AppCacheDiskCache> disk_cache) +DiskEntryOpener::DiskEntryOpener( + int64_t resource_id, + base::WeakPtr<ServiceWorkerDiskCache> disk_cache) : resource_id_(resource_id), disk_cache_(std::move(disk_cache)) { DCHECK_NE(resource_id_, blink::mojom::kInvalidServiceWorkerResourceId); DCHECK(disk_cache_); @@ -290,13 +292,13 @@ ensure_entry_is_opened_callback_ = std::move(callback); int rv; - AppCacheDiskCacheEntry** entry_ptr = nullptr; + ServiceWorkerDiskCacheEntry** entry_ptr = nullptr; if (entry_) { rv = net::OK; } else if (!disk_cache_) { rv = net::ERR_FAILED; } else { - entry_ptr = new AppCacheDiskCacheEntry*; + entry_ptr = new ServiceWorkerDiskCacheEntry*; rv = disk_cache_->OpenEntry( resource_id_, entry_ptr, base::BindOnce(&DiskEntryOpener::DidOpenEntry, @@ -310,7 +312,7 @@ // static void DiskEntryOpener::DidOpenEntry(base::WeakPtr<DiskEntryOpener> entry_opener, - AppCacheDiskCacheEntry** entry, + ServiceWorkerDiskCacheEntry** entry, int rv) { if (!entry_opener) { delete entry; @@ -500,7 +502,7 @@ ServiceWorkerResourceReaderImpl::ServiceWorkerResourceReaderImpl( int64_t resource_id, - base::WeakPtr<AppCacheDiskCache> disk_cache) + base::WeakPtr<ServiceWorkerDiskCache> disk_cache) : entry_opener_(resource_id, std::move(disk_cache)) {} ServiceWorkerResourceReaderImpl::~ServiceWorkerResourceReaderImpl() = default; @@ -691,7 +693,7 @@ ServiceWorkerResourceWriterImpl::ServiceWorkerResourceWriterImpl( int64_t resource_id, - base::WeakPtr<AppCacheDiskCache> disk_cache) + base::WeakPtr<ServiceWorkerDiskCache> disk_cache) : entry_creator_(resource_id, std::move(disk_cache)) {} ServiceWorkerResourceWriterImpl::~ServiceWorkerResourceWriterImpl() = default; @@ -807,7 +809,7 @@ ServiceWorkerResourceMetadataWriterImpl:: ServiceWorkerResourceMetadataWriterImpl( int64_t resource_id, - base::WeakPtr<AppCacheDiskCache> disk_cache) + base::WeakPtr<ServiceWorkerDiskCache> disk_cache) : entry_opener_(resource_id, std::move(disk_cache)) {} ServiceWorkerResourceMetadataWriterImpl::
diff --git a/content/browser/service_worker/service_worker_resource_ops.h b/content/browser/service_worker/service_worker_resource_ops.h index 8edad23..87a6f993 100644 --- a/content/browser/service_worker/service_worker_resource_ops.h +++ b/content/browser/service_worker/service_worker_resource_ops.h
@@ -17,14 +17,14 @@ class DiskEntryCreator { public: DiskEntryCreator(int64_t resource_id, - base::WeakPtr<AppCacheDiskCache> disk_cache); + base::WeakPtr<ServiceWorkerDiskCache> disk_cache); ~DiskEntryCreator(); DiskEntryCreator(const DiskEntryCreator&) = delete; DiskEntryCreator& operator=(const DiskEntryCreator&) = delete; // Can be nullptr when a disk cache error occurs. - AppCacheDiskCacheEntry* entry() { + ServiceWorkerDiskCacheEntry* entry() { DCHECK_EQ(creation_phase_, CreationPhase::kDone); return entry_; } @@ -53,26 +53,26 @@ }; // Callbacks of EnsureEntryIsCreated(). These are static to manage the - // ownership of AppCacheDiskCacheEntry correctly. + // ownership of ServiceWorkerDiskCacheEntry correctly. // TODO(crbug.com/586174): Refactor service worker's disk cache to use // disk_cache::EntryResult to make these callbacks non-static. static void DidCreateEntryForFirstAttempt( base::WeakPtr<DiskEntryCreator> entry_creator, - AppCacheDiskCacheEntry** entry, + ServiceWorkerDiskCacheEntry** entry, int rv); static void DidDoomExistingEntry( base::WeakPtr<DiskEntryCreator> entry_creator, int rv); static void DidCreateEntryForSecondAttempt( base::WeakPtr<DiskEntryCreator> entry_creator, - AppCacheDiskCacheEntry** entry, + ServiceWorkerDiskCacheEntry** entry, int rv); void RunEnsureEntryIsCreatedCallback(); const int64_t resource_id_; - base::WeakPtr<AppCacheDiskCache> disk_cache_; - AppCacheDiskCacheEntry* entry_ = nullptr; + base::WeakPtr<ServiceWorkerDiskCache> disk_cache_; + ServiceWorkerDiskCacheEntry* entry_ = nullptr; CreationPhase creation_phase_ = CreationPhase::kNoAttempt; @@ -86,14 +86,14 @@ class DiskEntryOpener { public: DiskEntryOpener(int64_t resource_id, - base::WeakPtr<AppCacheDiskCache> disk_cache); + base::WeakPtr<ServiceWorkerDiskCache> disk_cache); ~DiskEntryOpener(); DiskEntryOpener(const DiskEntryOpener&) = delete; DiskEntryOpener& operator=(const DiskEntryOpener&) = delete; // Can be nullptr when a disk cache error occurs. - AppCacheDiskCacheEntry* entry() { return entry_; } + ServiceWorkerDiskCacheEntry* entry() { return entry_; } // Calls the callback when entry() is opened and can be used. // @@ -106,12 +106,12 @@ // TODO(crbug.com/586174): Refactor service worker's disk cache to use // disk_cache::EntryResult to make this callback non-static. static void DidOpenEntry(base::WeakPtr<DiskEntryOpener> entry_creator, - AppCacheDiskCacheEntry** entry, + ServiceWorkerDiskCacheEntry** entry, int rv); const int64_t resource_id_; - base::WeakPtr<AppCacheDiskCache> disk_cache_; - AppCacheDiskCacheEntry* entry_ = nullptr; + base::WeakPtr<ServiceWorkerDiskCache> disk_cache_; + ServiceWorkerDiskCacheEntry* entry_ = nullptr; // Stored as a data member to handle //net-style maybe-async methods. base::OnceClosure ensure_entry_is_opened_callback_; @@ -123,8 +123,9 @@ class ServiceWorkerResourceReaderImpl : public storage::mojom::ServiceWorkerResourceReader { public: - ServiceWorkerResourceReaderImpl(int64_t resource_id, - base::WeakPtr<AppCacheDiskCache> disk_cache); + ServiceWorkerResourceReaderImpl( + int64_t resource_id, + base::WeakPtr<ServiceWorkerDiskCache> disk_cache); ServiceWorkerResourceReaderImpl(const ServiceWorkerResourceReaderImpl&) = delete; @@ -189,8 +190,9 @@ class ServiceWorkerResourceWriterImpl : public storage::mojom::ServiceWorkerResourceWriter { public: - ServiceWorkerResourceWriterImpl(int64_t resource_id, - base::WeakPtr<AppCacheDiskCache> disk_cache); + ServiceWorkerResourceWriterImpl( + int64_t resource_id, + base::WeakPtr<ServiceWorkerDiskCache> disk_cache); ServiceWorkerResourceWriterImpl(const ServiceWorkerResourceWriterImpl&) = delete; @@ -249,7 +251,7 @@ public: ServiceWorkerResourceMetadataWriterImpl( int64_t resource_id, - base::WeakPtr<AppCacheDiskCache> disk_cache); + base::WeakPtr<ServiceWorkerDiskCache> disk_cache); ServiceWorkerResourceMetadataWriterImpl( const ServiceWorkerResourceMetadataWriterImpl&) = delete;
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index d7ade410..f8f5b9b0 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -9,7 +9,7 @@ // declarations instead of including more headers. If that is infeasible, adjust // the limit. For more info, see // https://chromium.googlesource.com/chromium/src/+/HEAD/docs/wmax_tokens.md -#pragma clang max_tokens_here 890000 +#pragma clang max_tokens_here 910000 #include <utility>
diff --git a/docs/clang_tidy.md b/docs/clang_tidy.md index 834051989..2cf7aab 100644 --- a/docs/clang_tidy.md +++ b/docs/clang_tidy.md
@@ -75,7 +75,7 @@ ``` $ cd ${chromium}/src -$ ${chromium_build}/scripts/slave/recipe_modules/tricium_clang_tidy/resources/tricium_clang_tidy.py \ +$ ${chromium_build}/recipes/recipe_modules/tricium_clang_tidy/resources/tricium_clang_tidy.py \ --base_path $PWD \ --out_dir out/Linux \ --findings_file all_findings.json \ @@ -212,7 +212,7 @@ ``` 4. Run clang-tidy. ``` -<PATH_TO_LLVM_SRC>/clang-tidy/tool/run-clang-tidy.py \ +<PATH_TO_LLVM_SRC>/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py \ -p . \# Set the root project directory, where compile_commands.json is. # Set the clang-tidy binary path, if it's not in your $PATH. -clang-tidy-binary <PATH_TO_LLVM_BUILD>/bin/clang-tidy \ @@ -220,11 +220,11 @@ # and you are using the `fix` behavior of clang-tidy. -clang-apply-replacements-binary \ <PATH_TO_LLVM_BUILD>/bin/clang-apply-replacements \ - # The checks to employ in the build. Use `-*` to omit default checks. + # The checks to employ in the build. Use `-*,...` to omit default checks. -checks=<CHECKS> \ -header-filter=<FILTER> \# Optional, limit results to only certain files. -fix \# Optional, used if you want to have clang-tidy auto-fix errors. - chrome/browser # The path to the files you want to check. + 'chrome/browser/.*' # A regex of the files you want to check. Copy-Paste Friendly (though you'll still need to stub in the variables): <PATH_TO_LLVM_SRC>/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py \ @@ -235,12 +235,12 @@ -checks=<CHECKS> \ -header-filter=<FILTER> \ -fix \ - chrome/browser + 'chrome/browser/.*' ``` -\*It's not clear which, if any, `gn` flags may cause issues for -`clang-tidy`. I've had no problems building a component release build, -both with and without goma. if you run into issues, let us know! +Note that the source file regex must match how the build specified the file. +This means that on Windows, you must use (escaped) backslashes even from a bash +shell. ### Questions
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn index bf9d51b..9156e93 100644 --- a/ios/chrome/app/BUILD.gn +++ b/ios/chrome/app/BUILD.gn
@@ -214,6 +214,7 @@ "//ios/chrome/browser/history", "//ios/chrome/browser/main", "//ios/chrome/browser/memory", + "//ios/chrome/browser/metrics:metrics", "//ios/chrome/browser/metrics:metrics_internal", "//ios/chrome/browser/net", "//ios/chrome/browser/ntp:features",
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index 5287606..e93ca9b 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -69,6 +69,7 @@ #import "ios/chrome/browser/main/browser_list_factory.h" #import "ios/chrome/browser/memory/memory_debugger_manager.h" #include "ios/chrome/browser/metrics/first_user_action_recorder.h" +#import "ios/chrome/browser/metrics/window_configuration_recorder.h" #import "ios/chrome/browser/net/cookie_util.h" #import "ios/chrome/browser/omaha/omaha_service.h" #include "ios/chrome/browser/pref_names.h" @@ -257,6 +258,8 @@ // Variable backing metricsMediator property. __weak MetricsMediator* _metricsMediator; + WindowConfigurationRecorder* _windowConfigurationRecorder; + // Hander for the startup tasks, deferred or not. StartupTasks* _startupTasks; } @@ -527,6 +530,8 @@ self.appState.mainBrowserState); } + _windowConfigurationRecorder = [[WindowConfigurationRecorder alloc] init]; + return needRestoration; }
diff --git a/ios/chrome/browser/metrics/BUILD.gn b/ios/chrome/browser/metrics/BUILD.gn index 56658c3..5f10b7d 100644 --- a/ios/chrome/browser/metrics/BUILD.gn +++ b/ios/chrome/browser/metrics/BUILD.gn
@@ -41,6 +41,8 @@ "mobile_session_shutdown_metrics_provider.mm", "pageload_foreground_duration_tab_helper.h", "pageload_foreground_duration_tab_helper.mm", + "window_configuration_recorder.h", + "window_configuration_recorder.mm", ] public_deps = [ "//components/ukm/ios:ukm_url_recorder" ] deps = [ @@ -79,6 +81,7 @@ "//ios/chrome/browser/tabs", "//ios/chrome/browser/translate", "//ios/chrome/browser/ui/overscroll_actions", + "//ios/chrome/browser/ui/util:multiwindow_util", "//ios/chrome/browser/ui/whats_new:utils", "//ios/chrome/browser/variations", "//ios/chrome/browser/variations:ios_chrome_ui_string_overrider_factory",
diff --git a/ios/chrome/browser/metrics/window_configuration_recorder.h b/ios/chrome/browser/metrics/window_configuration_recorder.h new file mode 100644 index 0000000..e541856 --- /dev/null +++ b/ios/chrome/browser/metrics/window_configuration_recorder.h
@@ -0,0 +1,64 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_METRICS_WINDOW_CONFIGURATION_RECORDER_H_ +#define IOS_CHROME_BROWSER_METRICS_WINDOW_CONFIGURATION_RECORDER_H_ + +#import <UIKit/UIKit.h> + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class WindowConfiguration { + kUnspecified = 0, + // Chrome is showing one window, fullscreen. + kFullscreen, + // Chrome is showing two windows, one fullscreen and one slide-over. + kFullscreenWithSlideover, + // Chrome is showing one standard-width window, and another app has + // a window alongside it. + kSharedStandard, + // As above, and Chrome also has a slide-over window. + kSharedStandardWithSlideover, + // Chrome is showing one compact-width window, and another app has + // a window alongside it. + kSharedCompact, + // As above, and Chrome also has a slide-over window. + kSharedCompactWithSlideover, + // Chrome has only one foreground window, and it's in slide-over mode. + kSlideoverOnly, + // Chrome has two windows, both standard-width + kStandardBesideStandard, + // As above, and Chrome also has a third window in slide-over mode. + kStandardBesideStandardWithSlideover, + // Chrome has two windows, one standard-width and one compact-width. + kStandardBesideCompact, + // As above, and Chrome also has a third window in slide-over mode. + kStandardBesideCompactWithSlideover, + // Chrome has two windows, both compact-width + kCompactBesideCompact, + // As above, and Chrome also has a third window in slide-over mode. + kCompactBesideCompactWithSlideover, + // NOTE: add new configurations above this line. + kMaxValue = kCompactBesideCompactWithSlideover +}; + +// Reports time spent for each MultiWindow configuration. +// It looks at the window configuration every minute, and increments the +// histogram bucket for that configuration. Suspends when app is +// backgrounded and restarts when foregrounded. +@interface WindowConfigurationRecorder : NSObject + +// State of recording. +@property(nonatomic) BOOL recording; + +@end + +@interface WindowConfigurationRecorder (VisibleForTesting) + +// Computes configuration from given screen and windows. +- (WindowConfiguration)configurationForScreen:(UIScreen*)screen + windows:(NSArray<UIWindow*>*)windows; +@end + +#endif // IOS_CHROME_BROWSER_METRICS_WINDOW_CONFIGURATION_RECORDER_H_
diff --git a/ios/chrome/browser/metrics/window_configuration_recorder.mm b/ios/chrome/browser/metrics/window_configuration_recorder.mm new file mode 100644 index 0000000..efc62b2 --- /dev/null +++ b/ios/chrome/browser/metrics/window_configuration_recorder.mm
@@ -0,0 +1,221 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/metrics/window_configuration_recorder.h" + +#include "base/check.h" +#include "base/mac/foundation_util.h" +#include "base/metrics/histogram_functions.h" +#include "base/timer/timer.h" +#import "ios/chrome/browser/ui/util/multi_window_support.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface WindowConfigurationRecorder () + +// Called by the recording_timer_ to record current config. +- (void)recordConfiguration; + +@end + +namespace { + +// Delay between a recording of a new configuration. +static constexpr base::TimeDelta kRecordDelay = + base::TimeDelta::FromSeconds(20); + +// Timer callback for recording configuration after a delay. +void RecordWindowGeometryMetrics(WindowConfigurationRecorder* recorder) { + [recorder recordConfiguration]; +} + +// Returns all Foreground active windows that are Chrome windows. +NSArray<UIWindow*>* ForegroundWindowsForApplication( + UIApplication* application) { + NSMutableArray<UIWindow*>* windows = [NSMutableArray arrayWithCapacity:3]; + + if (IsSceneStartupSupported()) { + if (@available(iOS 13, *)) { + for (UIScene* scene in application.connectedScenes) { + if (scene.activationState != UISceneActivationStateForegroundActive) + continue; + + UIWindowScene* windowScene = base::mac::ObjCCast<UIWindowScene>(scene); + for (UIWindow* window in windowScene.windows) { + // Skip other windows (like keyboard) that keep showing up. + if (![window isKindOfClass:NSClassFromString(@"ChromeOverlayWindow")]) + continue; + + [windows addObject:window]; + break; // Stop after one window per scene. This may be wrong. + } + } + } + } + return [windows copy]; +} +} // namespace + +@implementation WindowConfigurationRecorder { + // Repeating delay timer. + base::RepeatingTimer recording_timer_; +} + +- (instancetype)init { + if (self == [super init]) { + // When the app becomes active, set recording on. + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(applicationDidBecomeActive) + name:UIApplicationDidBecomeActiveNotification + object:nil]; + + // When the app resigns active, turn recording off. + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(applicationDidEnterBackground) + name:UIApplicationDidEnterBackgroundNotification + object:nil]; + + [self scheduleRecordConfiguration]; + } + return self; +} + +// Called when notified of UIApplicationDidBecomeActiveNotification. +- (void)applicationDidBecomeActive { + self.recording = YES; + [self scheduleRecordConfiguration]; +} + +// Called when notified of UIApplicationDidEnterBackgroundNotification +- (void)applicationDidEnterBackground { + self.recording = NO; + recording_timer_.Stop(); +} + +// Called to set or reset the timer. +- (void)scheduleRecordConfiguration { + if (recording_timer_.IsRunning()) { + recording_timer_.Reset(); + } else { + recording_timer_.Start( + FROM_HERE, kRecordDelay, + base::BindRepeating(&RecordWindowGeometryMetrics, self)); + } +} + +// Called when the timer actually fires. +- (void)recordConfiguration { + [self recordGeometryForScreen:[UIScreen mainScreen] + windows:ForegroundWindowsForApplication( + UIApplication.sharedApplication)]; +} + +// Computes configuration for given screen and windows and records it. +- (void)recordGeometryForScreen:(UIScreen*)screen + windows:(NSArray<UIWindow*>*)windows { + WindowConfiguration configuration = [self configurationForScreen:screen + windows:windows]; + base::UmaHistogramEnumeration("IOS.MultiWindow.Configuration", configuration); +} + +#pragma mark - Visible For Testing + +- (WindowConfiguration)configurationForScreen:(UIScreen*)screen + windows:(NSArray<UIWindow*>*)windows { + NSMutableArray<UIWindow*>* fullscreenWindows = [[NSMutableArray alloc] init]; + NSMutableArray<UIWindow*>* slideoverWindows = [[NSMutableArray alloc] init]; + NSMutableArray<UIWindow*>* sharedWindows = [[NSMutableArray alloc] init]; + + CGRect screenRect = screen.bounds; + for (UIWindow* window in windows) { + CGRect windowRect = window.frame; + + // Is the window full screen? + if (CGRectEqualToRect(screenRect, windowRect)) { + [fullscreenWindows addObject:window]; + continue; + } + // Is the window in slideover? Slideover windows are always both shorter + // and narrower than the screen. + if (screenRect.size.width > windowRect.size.width && + screenRect.size.height > windowRect.size.height) { + [slideoverWindows addObject:window]; + continue; + } + + // Otherwise, the window is shared. This shouldn't happen if there's + // a fullscreen window. + [sharedWindows addObject:window]; + } + + WindowConfiguration configuration = WindowConfiguration::kUnspecified; + + if (sharedWindows.count == 0) { + if (fullscreenWindows.count > 0) { + configuration = slideoverWindows.count > 0 + ? WindowConfiguration::kFullscreenWithSlideover + : WindowConfiguration::kFullscreen; + } else if (slideoverWindows.count > 0) { + configuration = WindowConfiguration::kSlideoverOnly; + } else { + // Configuration remains unspecificed -- were there no windows? + } + } else if (sharedWindows.count == 1) { + // Single Shared window cases. + UIUserInterfaceSizeClass sharedWindowSize = + sharedWindows[0].traitCollection.horizontalSizeClass; + if (sharedWindowSize == UIUserInterfaceSizeClassRegular) { + configuration = slideoverWindows.count > 0 + ? WindowConfiguration::kSharedStandardWithSlideover + : WindowConfiguration::kSharedStandard; + } else if (sharedWindowSize == UIUserInterfaceSizeClassCompact) { + configuration = slideoverWindows.count > 0 + ? WindowConfiguration::kSharedCompactWithSlideover + : WindowConfiguration::kSharedCompact; + } else { + // Configuration remains unspecified -- shared window has an unspecified + // size class. + } + } else if (sharedWindows.count == 2) { + UIUserInterfaceSizeClass firstWindowSize = + sharedWindows[0].traitCollection.horizontalSizeClass; + UIUserInterfaceSizeClass secondWindowSize = + sharedWindows[1].traitCollection.horizontalSizeClass; + + if (firstWindowSize == UIUserInterfaceSizeClassRegular && + secondWindowSize == UIUserInterfaceSizeClassRegular) { + configuration = + slideoverWindows.count > 0 + ? WindowConfiguration::kStandardBesideStandardWithSlideover + : WindowConfiguration::kStandardBesideStandard; + } else if (firstWindowSize == UIUserInterfaceSizeClassCompact && + secondWindowSize == UIUserInterfaceSizeClassCompact) { + configuration = + slideoverWindows.count > 0 + ? WindowConfiguration::kCompactBesideCompactWithSlideover + : WindowConfiguration::kCompactBesideCompact; + } else if (firstWindowSize != UIUserInterfaceSizeClassUnspecified && + secondWindowSize != UIUserInterfaceSizeClassUnspecified) { + // Since the sizes are neither both standard, nor both compact, nor is + // either of them unspecified, one must be standard and the other compact. + configuration = + slideoverWindows.count > 0 + ? WindowConfiguration::kStandardBesideCompactWithSlideover + : WindowConfiguration::kStandardBesideCompact; + } else { + // Configuration remains unspecified -- one of the two shared windows has + // an unspecified size class. + } + } else { + // Configuration remains unspecified -- more than two shared windows. + } + + return configuration; +} + +@end
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.h b/ios/chrome/browser/sync/ios_chrome_sync_client.h index 3cbac92..6364596 100644 --- a/ios/chrome/browser/sync/ios_chrome_sync_client.h +++ b/ios/chrome/browser/sync/ios_chrome_sync_client.h
@@ -62,8 +62,6 @@ ChromeBrowserState* const browser_state_; // The sync api component factory in use by this client. - // TODO(crbug.com/915154): Revert to SyncApiComponentFactory once common - // controller creation is moved elsewhere. std::unique_ptr<browser_sync::ProfileSyncComponentsFactoryImpl> component_factory_;
diff --git a/ios/chrome/browser/sync/sync_setup_service_mock.h b/ios/chrome/browser/sync/sync_setup_service_mock.h index a703e5f..928497a 100644 --- a/ios/chrome/browser/sync/sync_setup_service_mock.h +++ b/ios/chrome/browser/sync/sync_setup_service_mock.h
@@ -14,23 +14,17 @@ public: SyncSetupServiceMock(syncer::SyncService* sync_service); ~SyncSetupServiceMock(); - - MOCK_CONST_METHOD0(IsSyncEnabled, bool()); - - MOCK_CONST_METHOD0(IsSyncingAllDataTypes, bool()); - - MOCK_METHOD0(GetSyncServiceState, SyncServiceState()); - - MOCK_CONST_METHOD1(IsDataTypePreferred, bool(syncer::ModelType)); - - MOCK_CONST_METHOD1(IsDataTypeActive, bool(syncer::ModelType)); - - MOCK_METHOD0(HasFinishedInitialSetup, bool()); - - MOCK_METHOD0(PrepareForFirstSyncSetup, void()); - - MOCK_METHOD1(SetFirstSetupComplete, - void(syncer::SyncFirstSetupCompleteSource)); + MOCK_METHOD(bool, IsSyncEnabled, (), (const override)); + MOCK_METHOD(bool, IsSyncingAllDataTypes, (), (const override)); + MOCK_METHOD(SyncServiceState, GetSyncServiceState, (), (override)); + MOCK_METHOD(bool, IsDataTypePreferred, (syncer::ModelType), (const override)); + MOCK_METHOD(bool, IsDataTypeActive, (syncer::ModelType), (const override)); + MOCK_METHOD(bool, HasFinishedInitialSetup, (), (override)); + MOCK_METHOD(void, PrepareForFirstSyncSetup, (), (override)); + MOCK_METHOD(void, + SetFirstSetupComplete, + (syncer::SyncFirstSetupCompleteSource), + (override)); // Allow the real SyncSetupService::HasFinishedInitialSetup() to be used when // mocking HasFinishedInitialSetup().
diff --git a/ios/web_view/internal/sync/web_view_sync_client.h b/ios/web_view/internal/sync/web_view_sync_client.h index 81515f2..7aeac6a 100644 --- a/ios/web_view/internal/sync/web_view_sync_client.h +++ b/ios/web_view/internal/sync/web_view_sync_client.h
@@ -74,8 +74,6 @@ invalidation::InvalidationService* invalidation_service_; syncer::SyncInvalidationsService* sync_invalidations_service_; - // TODO(crbug.com/915154): Revert to SyncApiComponentFactory once common - // controller creation is moved elsewhere. std::unique_ptr<browser_sync::ProfileSyncComponentsFactoryImpl> component_factory_;
diff --git a/media/capture/video/mac/video_capture_device_avfoundation_mac.mm b/media/capture/video/mac/video_capture_device_avfoundation_mac.mm index 79c09d6..67d0ecbd 100644 --- a/media/capture/video/mac/video_capture_device_avfoundation_mac.mm +++ b/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
@@ -58,10 +58,8 @@ : public media::VideoCaptureDevice::Client::Buffer::ScopedAccessPermission { public: CMSampleBufferScopedAccessPermission(CMSampleBufferRef buffer) - : buffer_(buffer, base::scoped_policy::RETAIN) { - buffer_.reset(); - } - ~CMSampleBufferScopedAccessPermission() override {} + : buffer_(buffer, base::scoped_policy::RETAIN) {} + ~CMSampleBufferScopedAccessPermission() override { buffer_.reset(); } private: base::ScopedCFTypeRef<CMSampleBufferRef> buffer_;
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 6d7a9b6..42a454f 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -558,7 +558,7 @@ ], "experiments": [ { - "name": "Enabled_20200917", + "name": "Enabled_20201015", "enable_features": [ "AssistPersonalInfo", "AssistPersonalInfoAddress",
diff --git a/third_party/blink/public/common/privacy_budget/identifiable_surface.h b/third_party/blink/public/common/privacy_budget/identifiable_surface.h index c9b52d6..1d0ba2ca 100644 --- a/third_party/blink/public/common/privacy_budget/identifiable_surface.h +++ b/third_party/blink/public/common/privacy_budget/identifiable_surface.h
@@ -229,8 +229,8 @@ }; enum class ScrollbarSurface : uint64_t { - kBodyOffsetWidth = 0, - kBodyOffsetHeight = 1, + kScrollingElementWidth = 0, + kScrollingElementHeight = 1, kElemScrollbarWidth = 2, kElemScrollbarHeight = 3, };
diff --git a/third_party/blink/public/public_features.gni b/third_party/blink/public/public_features.gni index 45096cb2..d7a4699 100644 --- a/third_party/blink/public/public_features.gni +++ b/third_party/blink/public/public_features.gni
@@ -27,4 +27,4 @@ enable_unhandled_tap = is_android # Use Minikin hyphenation engine. -use_minikin_hyphenation = is_android +use_minikin_hyphenation = !is_mac
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py index 34b5c49..cda3024 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
@@ -2943,6 +2943,13 @@ // CSSStyleDeclaration is abusing named properties. // Do not intercept. Fallback to OrdinaryDefineOwnProperty. """)) + elif cg_context.interface.identifier in ("HTMLEmbedElement", + "HTMLObjectElement"): + body.append( + TextNode("""\ +// HTMLEmbedElement and HTMLObjectElement are abusing named properties. +// Do not intercept. Fallback to OrdinaryDefineOwnProperty. +""")) elif not cg_context.interface.indexed_and_named_properties.named_setter: body.append( TextNode("""\ @@ -2986,17 +2993,7 @@ } return; } -""")) - if cg_context.interface.identifier in ("HTMLEmbedElement", - "HTMLObjectElement"): - body.append( - TextNode("""\ -// HTMLEmbedElement and HTMLObjectElement's named properties implementation -// depend on the default fallback behavior. So, just fallback. -""")) - else: - body.append( - TextNode("""\ + // step 2.2.2.2. Invoke the named property setter with P and Desc.[[Value]]. ${class_name}::NamedPropertySetterCallback( ${v8_property_name}, ${v8_property_desc}.value(), ${info});
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 6ed50f59..3039c40 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -33,7 +33,7 @@ // instead of including more headers. If that is infeasible, adjust the limit. // For more info, see // https://chromium.googlesource.com/chromium/src/+/HEAD/docs/wmax_tokens.md -#pragma clang max_tokens_here 950000 +#pragma clang max_tokens_here 960000 #include <memory> #include <utility> @@ -391,6 +391,26 @@ second->NotifyPriorityScrollAnchorStatusChanged(); } +// Before fetching the default URL, make sure it won't be blocked by CSP. The +// webpage didn't requested "/favicon.ico", it is automatic. Developers +// shouldn't suffer from any errors provoked by Chrome. +// See https://crbug.com/820846 +bool DefaultFaviconAllowedByCSP(const Document* document, const IconURL& icon) { + ExecutionContext* context = document->GetExecutionContext(); + if (!context) { + // LocalFrame::UpdateFaviconURL() is sometimes called after a LocalFrame + // swap. When this happens, the document has lost its ExecutionContext and + // the favicon won't be loaded anyway. The output of this function doesn't + // matter anymore. + return false; + } + + return context->GetContentSecurityPolicy()->AllowImageFromSource( + icon.icon_url_, icon.icon_url_, RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, + ContentSecurityPolicy::CheckHeaderType::kCheckAll); +} + } // namespace class DocumentOutliveTimeReporter : public BlinkGCObserver { @@ -7081,7 +7101,9 @@ } else if (url_.ProtocolIsInHTTPFamily() && icon_types_mask & 1 << static_cast<int>( mojom::blink::FaviconIconType::kFavicon)) { - icon_urls.push_back(IconURL::DefaultFavicon(url_)); + IconURL default_favicon = IconURL::DefaultFavicon(url_); + if (DefaultFaviconAllowedByCSP(this, default_favicon)) + icon_urls.push_back(std::move(default_favicon)); } if (first_touch_icon.icon_type_ != mojom::blink::FaviconIconType::kInvalid)
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 06c24ca..ee8341a 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -33,6 +33,8 @@ #include <utility> #include "cc/input/snap_selection_strategy.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h" #include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/dictionary.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -1273,6 +1275,70 @@ return 0; } +void Element::RecordScrollbarSizeForStudy(int measurement, + bool is_width, + bool is_offset) { + if (!IdentifiabilityStudySettings::Get()->IsTypeAllowed( + IdentifiableSurface::Type::kScrollbarSize)) + return; + + // Check for presence of a scrollbar. + PaintLayerScrollableArea* area; + if (this == GetDocument().ScrollingElementNoLayout()) { + auto* view = GetDocument().View(); + if (!view) + return; + area = view->LayoutViewport(); + } else { + auto* layout = GetLayoutBox(); + if (!layout) + return; + area = layout->GetScrollableArea(); + } + if (!area || area->HasOverlayOverflowControls()) + return; + + Scrollbar* scrollbar = + is_width ? area->VerticalScrollbar() : area->HorizontalScrollbar(); + // We intentionally exclude platform overlay scrollbars since their size + // cannot be detected in JavaScript using the methods below. + if (!scrollbar) + return; + + IdentifiableSurface::ScrollbarSurface surface; + int scrollbar_size; + + // There are two common ways to detect the size of a scrollbar in a DOM + // window. They are: + // 1. Compute the difference of the window.inner[Width|Height] and the + // corresponding document.scrollingElement.offset[Width|Height]. + // 2. Any HTML element that insets the layout to fit a scrollbar, so it is + // measurable by a JavaScript program on a site. + if (this == GetDocument().scrollingElement()) { + LocalDOMWindow* dom_window = GetDocument().domWindow(); + scrollbar_size = + (is_width ? dom_window->innerWidth() : dom_window->innerHeight()) - + measurement; + surface = + is_width + ? IdentifiableSurface::ScrollbarSurface::kScrollingElementWidth + : IdentifiableSurface::ScrollbarSurface::kScrollingElementHeight; + } else if (is_offset) { + scrollbar_size = measurement - (is_width ? clientWidth() : clientHeight()); + surface = is_width + ? IdentifiableSurface::ScrollbarSurface::kElemScrollbarWidth + : IdentifiableSurface::ScrollbarSurface::kElemScrollbarHeight; + } else { + return; + } + + blink::IdentifiabilityMetricBuilder(GetDocument().UkmSourceID()) + .Set(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kScrollbarSize, surface), + scrollbar_size) + .Record(GetDocument().UkmRecorder()); +} + int Element::clientWidth() { // When in strict mode, clientWidth for the document element should return the // width of the containing frame. @@ -1293,29 +1359,40 @@ // OverflowClipRect() may return infinite along a particular axis if // |layout_view| is not a scroll-container. DCHECK(layout_view->IsScrollContainer()); - return AdjustForAbsoluteZoom::AdjustLayoutUnit( - layout_view->OverflowClipRect(PhysicalOffset()).Width(), - layout_view->StyleRef()) - .Round(); + int result = + AdjustForAbsoluteZoom::AdjustLayoutUnit( + layout_view->OverflowClipRect(PhysicalOffset()).Width(), + layout_view->StyleRef()) + .Round(); + RecordScrollbarSizeForStudy(result, /* is_width= */ true, + /* is_offset= */ false); + return result; } - return AdjustForAbsoluteZoom::AdjustLayoutUnit( - LayoutUnit(layout_view->GetLayoutSize().Width()), - layout_view->StyleRef()) - .Round(); + int result = AdjustForAbsoluteZoom::AdjustLayoutUnit( + LayoutUnit(layout_view->GetLayoutSize().Width()), + layout_view->StyleRef()) + .Round(); + RecordScrollbarSizeForStudy(result, /* is_width= */ true, + /* is_offset= */ false); + return result; } } GetDocument().UpdateStyleAndLayoutForNode(this, DocumentUpdateReason::kJavaScript); - if (LayoutBox* layout_object = GetLayoutBox()) - return AdjustForAbsoluteZoom::AdjustLayoutUnit( - LayoutUnit( - layout_object - ->PixelSnappedClientWidthWithTableSpecialBehavior()), - layout_object->StyleRef()) - .Round(); - return 0; + int result = 0; + if (LayoutBox* layout_object = GetLayoutBox()) { + result = + AdjustForAbsoluteZoom::AdjustLayoutUnit( + LayoutUnit(layout_object + ->PixelSnappedClientWidthWithTableSpecialBehavior()), + layout_object->StyleRef()) + .Round(); + RecordScrollbarSizeForStudy(result, /* is_width= */ true, + /* is_offset= */ false); + } + return result; } int Element::clientHeight() { @@ -1339,29 +1416,40 @@ // OverflowClipRect() may return infinite along a particular axis if // |layout_view| is not a scroll-container. DCHECK(layout_view->IsScrollContainer()); - return AdjustForAbsoluteZoom::AdjustLayoutUnit( - layout_view->OverflowClipRect(PhysicalOffset()).Height(), - layout_view->StyleRef()) - .Round(); + int result = + AdjustForAbsoluteZoom::AdjustLayoutUnit( + layout_view->OverflowClipRect(PhysicalOffset()).Height(), + layout_view->StyleRef()) + .Round(); + RecordScrollbarSizeForStudy(result, /* is_width= */ false, + /* is_offset= */ false); + return result; } - return AdjustForAbsoluteZoom::AdjustLayoutUnit( - LayoutUnit(layout_view->GetLayoutSize().Height()), - layout_view->StyleRef()) - .Round(); + int result = AdjustForAbsoluteZoom::AdjustLayoutUnit( + LayoutUnit(layout_view->GetLayoutSize().Height()), + layout_view->StyleRef()) + .Round(); + RecordScrollbarSizeForStudy(result, /* is_width= */ false, + /* is_offset= */ false); + return result; } } GetDocument().UpdateStyleAndLayoutForNode(this, DocumentUpdateReason::kJavaScript); - if (LayoutBox* layout_object = GetLayoutBox()) - return AdjustForAbsoluteZoom::AdjustLayoutUnit( - LayoutUnit( - layout_object - ->PixelSnappedClientHeightWithTableSpecialBehavior()), - layout_object->StyleRef()) - .Round(); - return 0; + int result = 0; + if (LayoutBox* layout_object = GetLayoutBox()) { + result = AdjustForAbsoluteZoom::AdjustLayoutUnit( + LayoutUnit( + layout_object + ->PixelSnappedClientHeightWithTableSpecialBehavior()), + layout_object->StyleRef()) + .Round(); + RecordScrollbarSizeForStudy(result, /* is_width= */ false, + /* is_offset= */ false); + } + return result; } LayoutBox* Element::GetLayoutBoxForScrolling() const {
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index 3229ad32..2d141739 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -934,6 +934,10 @@ const ElementData* GetElementData() const { return element_data_.Get(); } UniqueElementData& EnsureUniqueElementData(); + void RecordScrollbarSizeForStudy(int measurement, + bool is_width, + bool is_offset); + void AddPropertyToPresentationAttributeStyle(MutableCSSPropertyValueSet*, CSSPropertyID, CSSValueID identifier);
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc index 4c5c62b..c1ee60f 100644 --- a/third_party/blink/renderer/core/html/html_element.cc +++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -26,8 +26,6 @@ #include "third_party/blink/renderer/core/html/html_element.h" #include "base/stl_util.h" -#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h" -#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h" #include "third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h" #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h" #include "third_party/blink/renderer/bindings/core/v8/string_treat_null_as_empty_string_or_trusted_script.h" @@ -1497,67 +1495,6 @@ return 0; } -void HTMLElement::RecordScrollbarSizeForStudy(int offset_measurement, - bool is_width) { - if (!IdentifiabilityStudySettings::Get()->IsTypeAllowed( - IdentifiableSurface::Type::kScrollbarSize)) - return; - - // Check for presence of a scrollbar. - PaintLayerScrollableArea* area; - if (this == GetDocument().ScrollingElementNoLayout()) { - auto* view = GetDocument().View(); - if (!view) - return; - area = view->LayoutViewport(); - } else { - auto* layout = GetLayoutBox(); - if (!layout) - return; - area = layout->GetScrollableArea(); - } - if (!area || area->HasOverlayOverflowControls()) - return; - - Scrollbar* scrollbar = - is_width ? area->VerticalScrollbar() : area->HorizontalScrollbar(); - // We intentionally exclude platform overlay scrollbars since their size - // cannot be detected in JavaScript using the methods below. - if (!scrollbar) - return; - - IdentifiableSurface::ScrollbarSurface surface; - int scrollbar_size; - - // There are two common ways to detect the size of a scrollbar in a DOM - // window. They are: - // 1. Compute the difference of the window.inner[Width|Height] and the - // corresponding document.scrollingElement.offset[Width|Height]. - // 2. Any HTML element that insets the layout to fit a scrollbar, so it is - // measurable by a JavaScript program on a site. - if (this == GetDocument().scrollingElement()) { - LocalDOMWindow* dom_window = GetDocument().domWindow(); - scrollbar_size = - (is_width ? dom_window->innerWidth() : dom_window->innerHeight()) - - offset_measurement; - surface = is_width - ? IdentifiableSurface::ScrollbarSurface::kBodyOffsetWidth - : IdentifiableSurface::ScrollbarSurface::kBodyOffsetHeight; - } else { - scrollbar_size = - offset_measurement - (is_width ? clientWidth() : clientHeight()); - surface = is_width - ? IdentifiableSurface::ScrollbarSurface::kElemScrollbarWidth - : IdentifiableSurface::ScrollbarSurface::kElemScrollbarHeight; - } - - blink::IdentifiabilityMetricBuilder(GetDocument().UkmSourceID()) - .Set(blink::IdentifiableSurface::FromTypeAndToken( - blink::IdentifiableSurface::Type::kScrollbarSize, surface), - scrollbar_size) - .Record(GetDocument().UkmRecorder()); -} - int HTMLElement::offsetWidthForBinding() { GetDocument().EnsurePaintLocationDataValidForNode( this, DocumentUpdateReason::kJavaScript); @@ -1569,7 +1506,8 @@ LayoutUnit(layout_object->PixelSnappedOffsetWidth(offset_parent)), layout_object->StyleRef()) .Round(); - RecordScrollbarSizeForStudy(result, /* isWidth= */ true); + RecordScrollbarSizeForStudy(result, /* isWidth= */ true, + /* is_offset= */ true); } return result; } @@ -1586,7 +1524,8 @@ LayoutUnit(layout_object->PixelSnappedOffsetHeight(offset_parent)), layout_object->StyleRef()) .Round(); - RecordScrollbarSizeForStudy(result, /* isWidth= */ false); + RecordScrollbarSizeForStudy(result, /* is_width= */ false, + /* is_offset= */ true); } return result; }
diff --git a/third_party/blink/renderer/core/html/html_element.h b/third_party/blink/renderer/core/html/html_element.h index 94cba571..0f54c2fa 100644 --- a/third_party/blink/renderer/core/html/html_element.h +++ b/third_party/blink/renderer/core/html/html_element.h
@@ -212,8 +212,6 @@ void HandleKeypressEvent(KeyboardEvent&); - void RecordScrollbarSizeForStudy(int, bool); - static AttributeTriggers* TriggersForAttributeName( const QualifiedName& attr_name);
diff --git a/third_party/blink/renderer/core/layout/layout_text_control.cc b/third_party/blink/renderer/core/layout/layout_text_control.cc index b0847fa..274b3a3 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control.cc +++ b/third_party/blink/renderer/core/layout/layout_text_control.cc
@@ -54,7 +54,13 @@ const ComputedStyle* old_style) { NOT_DESTROYED(); LayoutBlockFlow::StyleDidChange(diff, old_style); - TextControlInnerEditorElement* inner_editor = InnerEditorElement(); + StyleDidChange(InnerEditorElement(), old_style, StyleRef()); +} + +// static +void LayoutTextControl::StyleDidChange(HTMLElement* inner_editor, + const ComputedStyle* old_style, + const ComputedStyle& new_style) { if (!inner_editor) return; LayoutBlock* inner_editor_layout_object = @@ -65,7 +71,7 @@ // (See TextControlInnerEditorElement::CreateInnerEditorStyle()). { StyleEngine::AllowMarkStyleDirtyFromRecalcScope scope( - GetDocument().GetStyleEngine()); + inner_editor->GetDocument().GetStyleEngine()); inner_editor->SetNeedsStyleRecalc( kLocalStyleChange, StyleChangeReasonForTracing::Create(style_change_reason::kControl)); @@ -75,7 +81,7 @@ // (see: GetUncachedSelectionStyle in SelectionPaintingUtils.cpp) so ensure // the inner editor selection is invalidated anytime style changes and a // ::selection style is or was present on LayoutTextControl. - if (StyleRef().HasPseudoElementStyle(kPseudoIdSelection) || + if (new_style.HasPseudoElementStyle(kPseudoIdSelection) || (old_style && old_style->HasPseudoElementStyle(kPseudoIdSelection))) { inner_editor_layout_object->InvalidateSelectedChildrenOnStyleChange(); }
diff --git a/third_party/blink/renderer/core/layout/layout_text_control.h b/third_party/blink/renderer/core/layout/layout_text_control.h index a26a2d46..602bae9 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control.h +++ b/third_party/blink/renderer/core/layout/layout_text_control.h
@@ -49,6 +49,9 @@ return true; } + static void StyleDidChange(HTMLElement* inner_editor, + const ComputedStyle* old_style, + const ComputedStyle& new_style); static int ScrollbarThickness(const LayoutBox& box); static float GetAvgCharWidth(const ComputedStyle& style); static bool HasValidAvgCharWidth(const Font& font);
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_test.cc b/third_party/blink/renderer/core/layout/layout_text_control_test.cc index b844616..f1efd17d 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control_test.cc +++ b/third_party/blink/renderer/core/layout/layout_text_control_test.cc
@@ -5,28 +5,60 @@ #include "third_party/blink/renderer/core/layout/layout_text_control.h" #include "build/build_config.h" -#include "third_party/blink/renderer/core/html/forms/html_input_element.h" +#include "third_party/blink/renderer/core/html/forms/text_control_element.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" +#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" namespace blink { namespace { -class LayoutTextControlTest : public RenderingTest { +class LayoutTextControlTest : public testing::WithParamInterface<bool>, + public RenderingTest { + public: + LayoutTextControlTest() + : scoped_text_area_flag_(GetParam()), + scoped_text_field_flag_(GetParam()) {} + protected: - HTMLInputElement* GetHTMLInputElementById(const char* id) { - return To<HTMLInputElement>(GetDocument().getElementById(id)); + TextControlElement* GetTextControlElementById(const char* id) { + return To<TextControlElement>(GetDocument().getElementById(id)); } - // Return the LayoutText from inside an HTMLInputElement's user agent shadow - // tree. - LayoutText* GetInnerLayoutText(HTMLInputElement* input) { + // Return the LayoutText from inside a text control's user agent shadow tree. + LayoutText* GetInnerLayoutText(TextControlElement* control) { return ToLayoutText( - input->InnerEditorElement()->GetLayoutObject()->SlowFirstChild()); + control->InnerEditorElement()->GetLayoutObject()->SlowFirstChild()); } + + // Focus on |control|, select 1-3 characters, get the first LayoutText, and + // check if selection invalidation state is clean. + LayoutText* SetupLayoutTextWithCleanSelection(TextControlElement* control) { + control->focus(); + control->SetSelectionRange(1, 3); + UpdateAllLifecyclePhasesForTest(); + auto* selected_text = GetInnerLayoutText(control); + EXPECT_FALSE(selected_text->ShouldInvalidateSelection()); + return selected_text; + } + + void CheckSelectionInvalidationChanges(const LayoutText& selected_text) { + GetDocument().View()->UpdateLifecycleToLayoutClean( + DocumentUpdateReason::kTest); + EXPECT_TRUE(selected_text.ShouldInvalidateSelection()); + + UpdateAllLifecyclePhasesForTest(); + EXPECT_FALSE(selected_text.ShouldInvalidateSelection()); + } + + private: + ScopedLayoutNGTextAreaForTest scoped_text_area_flag_; + ScopedLayoutNGTextFieldForTest scoped_text_field_flag_; }; -TEST_F(LayoutTextControlTest, - ChangingPseudoSelectionStyleShouldInvalidateSelection) { +INSTANTIATE_TEST_SUITE_P(All, LayoutTextControlTest, testing::Bool()); + +TEST_P(LayoutTextControlTest, + ChangingPseudoSelectionStyleShouldInvalidateSelectionSingle) { SetBodyInnerHTML(R"HTML( <style> input::selection { background-color: blue; } @@ -35,25 +67,32 @@ <input id="input" type="text" value="AAAAAAAAAAAA"> )HTML"); - auto* inputElement = GetHTMLInputElementById("input"); - inputElement->focus(); - inputElement->SetSelectionRange(1, 3); - UpdateAllLifecyclePhasesForTest(); + auto* text_control = GetTextControlElementById("input"); + auto* selected_text = SetupLayoutTextWithCleanSelection(text_control); - auto* selectedText = GetInnerLayoutText(inputElement); - EXPECT_FALSE(selectedText->ShouldInvalidateSelection()); - - inputElement->setAttribute(html_names::kClassAttr, "pseudoSelection"); - GetDocument().View()->UpdateLifecycleToLayoutClean( - DocumentUpdateReason::kTest); - EXPECT_TRUE(selectedText->ShouldInvalidateSelection()); - - UpdateAllLifecyclePhasesForTest(); - EXPECT_FALSE(selectedText->ShouldInvalidateSelection()); + text_control->setAttribute(html_names::kClassAttr, "pseudoSelection"); + CheckSelectionInvalidationChanges(*selected_text); } -TEST_F(LayoutTextControlTest, - AddingPseudoSelectionStyleShouldInvalidateSelection) { +TEST_P(LayoutTextControlTest, + ChangingPseudoSelectionStyleShouldInvalidateSelectionMulti) { + SetBodyInnerHTML(R"HTML( + <style> + textarea::selection { background-color: blue; } + .pseudoSelection::selection { background-color: green; } + </style> + <textarea id="textarea">AAAAAAAAAAAA</textarea> + )HTML"); + + auto* text_control = GetTextControlElementById("textarea"); + auto* selected_text = SetupLayoutTextWithCleanSelection(text_control); + + text_control->setAttribute(html_names::kClassAttr, "pseudoSelection"); + CheckSelectionInvalidationChanges(*selected_text); +} + +TEST_P(LayoutTextControlTest, + AddingPseudoSelectionStyleShouldInvalidateSelectionSingle) { SetBodyInnerHTML(R"HTML( <style> .pseudoSelection::selection { background-color: green; } @@ -61,25 +100,31 @@ <input id="input" type="text" value="AAAAAAAAAAAA"> )HTML"); - auto* inputElement = GetHTMLInputElementById("input"); - inputElement->focus(); - inputElement->SetSelectionRange(1, 3); - UpdateAllLifecyclePhasesForTest(); + auto* text_control = GetTextControlElementById("input"); + auto* selected_text = SetupLayoutTextWithCleanSelection(text_control); - auto* selectedText = GetInnerLayoutText(inputElement); - EXPECT_FALSE(selectedText->ShouldInvalidateSelection()); - - inputElement->setAttribute(html_names::kClassAttr, "pseudoSelection"); - GetDocument().View()->UpdateLifecycleToLayoutClean( - DocumentUpdateReason::kTest); - EXPECT_TRUE(selectedText->ShouldInvalidateSelection()); - - UpdateAllLifecyclePhasesForTest(); - EXPECT_FALSE(selectedText->ShouldInvalidateSelection()); + text_control->setAttribute(html_names::kClassAttr, "pseudoSelection"); + CheckSelectionInvalidationChanges(*selected_text); } -TEST_F(LayoutTextControlTest, - RemovingPseudoSelectionStyleShouldInvalidateSelection) { +TEST_P(LayoutTextControlTest, + AddingPseudoSelectionStyleShouldInvalidateSelectionMulti) { + SetBodyInnerHTML(R"HTML( + <style> + .pseudoSelection::selection { background-color: green; } + </style> + <textarea id="textarea" >AAAAAAAAAAAA</textarea> + )HTML"); + + auto* text_control = GetTextControlElementById("textarea"); + auto* selected_text = SetupLayoutTextWithCleanSelection(text_control); + + text_control->setAttribute(html_names::kClassAttr, "pseudoSelection"); + CheckSelectionInvalidationChanges(*selected_text); +} + +TEST_P(LayoutTextControlTest, + RemovingPseudoSelectionStyleShouldInvalidateSelectionSingle) { SetBodyInnerHTML(R"HTML( <style> .pseudoSelection::selection { background-color: green; } @@ -87,30 +132,36 @@ <input id="input" type="text" class="pseudoSelection" value="AAAAAAAAAAAA"> )HTML"); - auto* inputElement = GetHTMLInputElementById("input"); - inputElement->focus(); - inputElement->SetSelectionRange(1, 3); - UpdateAllLifecyclePhasesForTest(); + auto* text_control = GetTextControlElementById("input"); + auto* selected_text = SetupLayoutTextWithCleanSelection(text_control); - auto* selectedText = GetInnerLayoutText(inputElement); - EXPECT_FALSE(selectedText->ShouldInvalidateSelection()); - - inputElement->removeAttribute(html_names::kClassAttr); - GetDocument().View()->UpdateLifecycleToLayoutClean( - DocumentUpdateReason::kTest); - EXPECT_TRUE(selectedText->ShouldInvalidateSelection()); - - UpdateAllLifecyclePhasesForTest(); - EXPECT_FALSE(selectedText->ShouldInvalidateSelection()); + text_control->removeAttribute(html_names::kClassAttr); + CheckSelectionInvalidationChanges(*selected_text); } -TEST_F(LayoutTextControlTest, HitTestSearchInput) { +TEST_P(LayoutTextControlTest, + RemovingPseudoSelectionStyleShouldInvalidateSelectionMulti) { + SetBodyInnerHTML(R"HTML( + <style> + .pseudoSelection::selection { background-color: green; } + </style> + <textarea id="textarea" class="pseudoSelection">AAAAAAAAAAAA</textarea> + )HTML"); + + auto* text_control = GetTextControlElementById("textarea"); + auto* selected_text = SetupLayoutTextWithCleanSelection(text_control); + + text_control->removeAttribute(html_names::kClassAttr); + CheckSelectionInvalidationChanges(*selected_text); +} + +TEST_P(LayoutTextControlTest, HitTestSearchInput) { SetBodyInnerHTML(R"HTML( <input id="input" type="search" style="border-width: 20px; font-size: 30px; padding: 0"> )HTML"); - auto* input = GetHTMLInputElementById("input"); + auto* input = GetTextControlElementById("input"); HitTestResult result; HitTestLocation location(PhysicalOffset(40, 30)); EXPECT_TRUE(input->GetLayoutObject()->HitTestAllPhases(result, location,
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc index 7e73c11..0903a2cb 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc
@@ -256,4 +256,14 @@ } #endif +std::ostream& operator<<(std::ostream& ostream, const NGLineInfo& line_info) { + // Feel free to add more NGLneInfo members. + ostream << "NGLineInfo available_width_=" << line_info.AvailableWidth() + << " width_=" << line_info.Width() << " Results=[\n"; + for (const auto& result : line_info.Results()) { + ostream << "\t" << result.item->ToString() << "\n"; + } + return ostream << "]"; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h index 9ab17dd2..df14bd22 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h
@@ -298,6 +298,8 @@ bool is_ruby_text_ = false; }; +std::ostream& operator<<(std::ostream& ostream, const NGLineInfo& line_info); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_ITEM_RESULT_H_
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.cc index 0af95963..093c5a6 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.cc
@@ -194,7 +194,9 @@ if (items->size() < 2U) return LayoutUnit(); const NGInlineItemResult& text_item = items->back(); - DCHECK_EQ(text_item.item->Type(), NGInlineItem::kText); + if (text_item.item->Type() == NGInlineItem::kControl) + return LayoutUnit(); + DCHECK(text_item.item->Type() == NGInlineItem::kText); wtf_size_t i = items->size() - 2; while ((*items)[i].item->Type() != NGInlineItem::kAtomicInline) { const auto type = (*items)[i].item->Type();
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.cc index e743bb0..4469ef6 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.cc
@@ -12,11 +12,23 @@ LayoutNGTextControlMultiLine::LayoutNGTextControlMultiLine(Element* element) : LayoutNGBlockFlow(element) {} +HTMLElement* LayoutNGTextControlMultiLine::InnerEditorElement() const { + return To<TextControlElement>(GetNode())->InnerEditorElement(); +} + bool LayoutNGTextControlMultiLine::IsOfType(LayoutObjectType type) const { return type == kLayoutObjectNGTextControlMultiLine || LayoutNGBlockFlow::IsOfType(type); } +void LayoutNGTextControlMultiLine::StyleDidChange( + StyleDifference style_diff, + const ComputedStyle* old_style) { + LayoutNGBlockFlow::StyleDidChange(style_diff, old_style); + LayoutTextControl::StyleDidChange(InnerEditorElement(), old_style, + StyleRef()); +} + bool LayoutNGTextControlMultiLine::NodeAtPoint( HitTestResult& result, const HitTestLocation& hit_test_location, @@ -30,8 +42,7 @@ if (stop_node && stop_node->NodeForHitTest() == result.InnerNode()) return true; - HTMLElement* inner_editor = - To<TextControlElement>(GetNode())->InnerEditorElement(); + HTMLElement* inner_editor = InnerEditorElement(); if (result.InnerNode() == GetNode() || result.InnerNode() == inner_editor) { LayoutTextControl::HitInnerEditorElement( *this, *inner_editor, result, hit_test_location, accumulated_offset);
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.h b/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.h index 94cfad8..054541a 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.h +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.h
@@ -15,6 +15,8 @@ explicit LayoutNGTextControlMultiLine(Element* element); private: + HTMLElement* InnerEditorElement() const; + bool IsOfType(LayoutObjectType) const override; const char* GetName() const override { @@ -27,6 +29,8 @@ return true; } + void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override; + bool NodeAtPoint(HitTestResult& result, const HitTestLocation& hit_test_location, const PhysicalOffset& accumulated_offset,
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_single_line.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_single_line.cc index 72a4b3f..98bff21 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_single_line.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_single_line.cc
@@ -4,14 +4,29 @@ #include "third_party/blink/renderer/core/layout/ng/layout_ng_text_control_single_line.h" +#include "third_party/blink/renderer/core/html/forms/text_control_element.h" +#include "third_party/blink/renderer/core/layout/layout_text_control.h" + namespace blink { LayoutNGTextControlSingleLine::LayoutNGTextControlSingleLine(Element* element) : LayoutNGBlockFlow(element) {} +HTMLElement* LayoutNGTextControlSingleLine::InnerEditorElement() const { + return To<TextControlElement>(GetNode())->InnerEditorElement(); +} + bool LayoutNGTextControlSingleLine::IsOfType(LayoutObjectType type) const { return type == kLayoutObjectNGTextControlSingleLine || LayoutNGBlockFlow::IsOfType(type); } +void LayoutNGTextControlSingleLine::StyleDidChange( + StyleDifference style_diff, + const ComputedStyle* old_style) { + LayoutNGBlockFlow::StyleDidChange(style_diff, old_style); + LayoutTextControl::StyleDidChange(InnerEditorElement(), old_style, + StyleRef()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_single_line.h b/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_single_line.h index 0573297..1a532ba8 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_single_line.h +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_single_line.h
@@ -15,6 +15,8 @@ explicit LayoutNGTextControlSingleLine(Element* element); private: + HTMLElement* InnerEditorElement() const; + bool IsOfType(LayoutObjectType) const override; const char* GetName() const override { @@ -26,6 +28,8 @@ NOT_DESTROYED(); return true; } + + void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h index 80ed156..557b849 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
@@ -192,6 +192,10 @@ block_end_annotation_space_ = space; } + void SetHasDescendantThatDependsOnPercentageBlockSize() { + has_descendant_that_depends_on_percentage_block_size_ = true; + } + const NGConstraintSpace* ConstraintSpace() const { return space_; } #if DCHECK_IS_ON()
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc index e99e2831..496b3ca 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc
@@ -131,6 +131,16 @@ NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), &container_builder_).Run(); + const auto& style = Style(); + if (style.LogicalHeight().IsPercentOrCalc() || + style.LogicalMinHeight().IsPercentOrCalc() || + style.LogicalMaxHeight().IsPercentOrCalc()) { + // The height of the fieldset content box depends on the percent-height of + // the fieldset. So we should assume the fieldset has a percent-height + // descendant. + container_builder_.SetHasDescendantThatDependsOnPercentageBlockSize(); + } + return container_builder_.ToBoxFragment(); }
diff --git a/third_party/blink/renderer/platform/instrumentation/partition_alloc_memory_dump_provider.cc b/third_party/blink/renderer/platform/instrumentation/partition_alloc_memory_dump_provider.cc index 63fbf013..50ac292 100644 --- a/third_party/blink/renderer/platform/instrumentation/partition_alloc_memory_dump_provider.cc +++ b/third_party/blink/renderer/platform/instrumentation/partition_alloc_memory_dump_provider.cc
@@ -135,15 +135,15 @@ allocator_dump->AddScalar("discardable_size", "bytes", memory_stats->discardable_bytes); // TODO(bartekn): Rename the scalar names. - allocator_dump->AddScalar("total_pages_size", "bytes", + allocator_dump->AddScalar("total_slot_span_size", "bytes", memory_stats->allocated_slot_span_size); - allocator_dump->AddScalar("active_pages", "objects", + allocator_dump->AddScalar("active_slot_spans", "objects", memory_stats->num_active_slot_spans); - allocator_dump->AddScalar("full_pages", "objects", + allocator_dump->AddScalar("full_slot_spans", "objects", memory_stats->num_full_slot_spans); - allocator_dump->AddScalar("empty_pages", "objects", + allocator_dump->AddScalar("empty_slot_spans", "objects", memory_stats->num_empty_slot_spans); - allocator_dump->AddScalar("decommitted_pages", "objects", + allocator_dump->AddScalar("decommitted_slot_spans", "objects", memory_stats->num_decommitted_slot_spans); }
diff --git a/third_party/blink/renderer/platform/text/hyphenation_test.cc b/third_party/blink/renderer/platform/text/hyphenation_test.cc index 1cd3d876..2354c16 100644 --- a/third_party/blink/renderer/platform/text/hyphenation_test.cc +++ b/third_party/blink/renderer/platform/text/hyphenation_test.cc
@@ -70,14 +70,13 @@ } #if defined(USE_MINIKIN_HYPHENATION) || defined(OS_MAC) -// TODO(crbug.com/851413): Reenable this test. -#if defined(OS_ANDROID) -#define MAYBE_HyphenLocations DISABLED_HyphenLocations -#else -#define MAYBE_HyphenLocations HyphenLocations -#endif -TEST_F(HyphenationTest, MAYBE_HyphenLocations) { +TEST_F(HyphenationTest, HyphenLocations) { scoped_refptr<Hyphenation> hyphenation = GetHyphenation("en-us"); +#if defined(OS_ANDROID) + // Hyphenation is available only for Android M MR1 or later. + if (!hyphenation) + return; +#endif ASSERT_TRUE(hyphenation) << "Cannot find the hyphenation engine"; // Get all hyphenation points by |HyphenLocations|.
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 7af9af2..3d38dfd 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -145,7 +145,7 @@ virtual/composite-after-paint/scrollingcoordinator/* [ Pass ] # --- End CompositeAfterPaint Tests -- -# --- BEGIN OOP-R Canvas tests --- +# --- BEGIN OOP-R Canvas tests --- crbug.com/1081534 [ Win7 ] virtual/oopr-canvas2d/fast/canvas/canvas-composite-video-shadow.html [ Pass Failure ] crbug.com/1081534 [ Win ] virtual/oopr-canvas2d/fast/canvas/canvas-clearRect-first.html [ Failure ] crbug.com/1081534 [ Win ] virtual/oopr-canvas2d/fast/canvas/canvas-clearRect-with-clip.html [ Failure ] @@ -875,7 +875,6 @@ crbug.com/591099 css3/filters/composited-layer-child-bounds-after-composited-to-sw-shadow-change.html [ Failure ] crbug.com/591099 external/wpt/css/css-text/boundary-shaping/boundary-shaping-009.html [ Failure ] -crbug.com/591099 external/wpt/css/css-text/hyphens/shy-styling-001.html [ Failure ] crbug.com/591099 external/wpt/css/css-text/shaping/shaping-009.html [ Failure ] crbug.com/591099 external/wpt/css/css-text/shaping/shaping-010.html [ Failure ] crbug.com/591099 external/wpt/css/css-text/shaping/shaping-011.html [ Failure ] @@ -928,7 +927,6 @@ # LayoutNG failures that needs to be triaged crbug.com/591099 virtual/text-antialias/selection/selection-rect-line-height-too-small.html [ Failure ] -crbug.com/591099 external/wpt/css/css-text/hyphens/hyphens-out-of-flow-002.html [ Failure ] crbug.com/591099 fast/css-intrinsic-dimensions/width-avoid-floats.html [ Failure ] crbug.com/591099 [ Linux ] fast/selectors/shadow-host-div-with-span.html [ Failure ] crbug.com/591099 [ Win ] fast/selectors/shadow-host-div-with-span.html [ Failure ] @@ -969,9 +967,6 @@ crbug.com/591099 [ Mac ] fast/multicol/vertical-rl/float-big-line.html [ Failure ] crbug.com/591099 [ Mac ] fast/multicol/vertical-rl/float-content-break.html [ Failure ] crbug.com/591099 [ Mac ] fast/multicol/vertical-rl/float-edge.html [ Failure ] -crbug.com/591099 [ Mac ] virtual/text-antialias/hyphens/hyphen-min-preferred-width-mock.html [ Failure ] -crbug.com/591099 [ Mac ] virtual/text-antialias/hyphens/hyphens-auto-mock.html [ Failure ] -crbug.com/591099 [ Mac ] virtual/text-antialias/hyphens/midword-break-priority.html [ Failure ] crbug.com/591099 [ Mac ] paint/invalidation/box/hover-pseudo-borders.html [ Failure ] crbug.com/591099 [ Mac ] fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-auto.html [ Failure ] crbug.com/591099 [ Mac ] paint/invalidation/flexbox/remove-inline-block-descendant-of-flex.html [ Failure ] @@ -1563,30 +1558,6 @@ crbug.com/1056027 [ Fuchsia ] virtual/text-antialias/small-caps-aat.html [ Skip ] crbug.com/1057339 [ Fuchsia ] virtual/text-antialias/international/rtl-mark.html [ Skip ] -# `hyphens: auto` not supported on Win/Linux/ChromeOS -crbug.com/652964 [ Linux ] virtual/text-antialias/hyphens/hyphen-min-preferred-width-mock.html [ Skip ] -crbug.com/652964 [ Win ] virtual/text-antialias/hyphens/hyphen-min-preferred-width-mock.html [ Skip ] -crbug.com/652964 [ Linux ] virtual/text-antialias/hyphens/hyphens-align.html [ Skip ] -crbug.com/652964 [ Win ] virtual/text-antialias/hyphens/hyphens-align.html [ Skip ] -crbug.com/652964 [ Linux ] virtual/text-antialias/hyphens/hyphens-auto.html [ Skip ] -crbug.com/652964 [ Win ] virtual/text-antialias/hyphens/hyphens-auto.html [ Skip ] -crbug.com/652964 [ Linux ] virtual/text-antialias/hyphens/hyphens-auto-mock.html [ Skip ] -crbug.com/652964 [ Win ] virtual/text-antialias/hyphens/hyphens-auto-mock.html [ Skip ] -crbug.com/652964 [ Linux ] virtual/text-antialias/hyphens/hyphens-auto-nowrap.html [ Skip ] -crbug.com/652964 [ Win ] virtual/text-antialias/hyphens/hyphens-auto-nowrap.html [ Skip ] -crbug.com/652964 [ Linux ] virtual/text-antialias/hyphens/hyphens-locale.html [ Skip ] -crbug.com/652964 [ Win ] virtual/text-antialias/hyphens/hyphens-locale.html [ Skip ] -crbug.com/652964 [ Linux ] virtual/text-antialias/hyphens/hyphens-orphaned-word.html [ Skip ] -crbug.com/652964 [ Win ] virtual/text-antialias/hyphens/hyphens-orphaned-word.html [ Skip ] -crbug.com/652964 [ Linux ] virtual/text-antialias/hyphens/midword-break-priority.html [ Skip ] -crbug.com/652964 [ Win ] virtual/text-antialias/hyphens/midword-break-priority.html [ Skip ] -crbug.com/652964 [ Linux ] external/wpt/css/css-text/hyphens/hyphens-auto-010.html [ Skip ] -crbug.com/652964 [ Win ] external/wpt/css/css-text/hyphens/hyphens-auto-010.html [ Skip ] -crbug.com/652964 [ Linux ] external/wpt/css/css-text/hyphens/hyphens-auto-inline-010.html [ Skip ] -crbug.com/652964 [ Win ] external/wpt/css/css-text/hyphens/hyphens-auto-inline-010.html [ Skip ] -crbug.com/652964 [ Linux ] external/wpt/css/css-text/hyphens/hyphens-none-013.html [ Skip ] -crbug.com/652964 [ Win ] external/wpt/css/css-text/hyphens/hyphens-none-013.html [ Skip ] - crbug.com/305376 external/wpt/css/css-overflow/webkit-line-clamp-018.html [ Failure ] crbug.com/305376 external/wpt/css/css-overflow/webkit-line-clamp-024.html [ Failure ] crbug.com/1007065 external/wpt/css/css-overflow/overflow-codependent-scrollbars.html [ Failure ] @@ -1660,11 +1631,20 @@ crbug.com/1022182 virtual/module-top-level-await/external/wpt/html/webappapis/dynamic-markup-insertion/document-write/module-tla-promise.html [ Pass ] crbug.com/676270 [ Mac ] external/wpt/css/css-text/hyphens/hyphens-auto-001.html [ Failure ] -crbug.com/1022415 [ Mac ] external/wpt/css/css-text/hyphens/hyphens-auto-010.html [ Failure ] +crbug.com/1022415 external/wpt/css/css-text/hyphens/hyphens-auto-010.html [ Failure ] +crbug.com/1022415 [ Linux ] external/wpt/css/css-text/hyphens/hyphens-auto-inline-010.html [ Failure ] +crbug.com/1022415 [ Win ] external/wpt/css/css-text/hyphens/hyphens-auto-inline-010.html [ Failure ] crbug.com/963369 external/wpt/css/css-text/hyphens/hyphens-out-of-flow-001.html [ Failure ] -crbug.com/958672 external/wpt/css/css-text/hyphens/hyphens-shaping-002.html [ Failure ] -crbug.com/958672 external/wpt/css/css-text/hyphens/hyphens-span-001.html [ Failure ] -crbug.com/958672 [ Mac ] external/wpt/css/css-text/hyphens/hyphens-span-002.html [ Failure ] +crbug.com/963369 external/wpt/css/css-text/hyphens/hyphens-out-of-flow-002.html [ Failure ] +crbug.com/639223 external/wpt/css/css-text/hyphens/hyphens-shaping-002.html [ Failure ] +crbug.com/639223 external/wpt/css/css-text/hyphens/hyphens-span-001.html [ Failure ] +crbug.com/639223 [ Mac ] external/wpt/css/css-text/hyphens/hyphens-span-002.html [ Failure ] +crbug.com/639223 external/wpt/css/css-text/hyphens/shy-styling-001.html [ Failure ] +crbug.com/870219 virtual/text-antialias/hyphens/hyphen-min-preferred-width-mock.html [ Failure ] +crbug.com/870219 [ Win ] virtual/text-antialias/hyphens/hyphens-auto.html [ Failure ] +crbug.com/870219 virtual/text-antialias/hyphens/hyphens-auto-mock.html [ Failure ] +crbug.com/1139693 virtual/text-antialias/hyphens/midword-break-priority.html [ Failure ] + crbug.com/626703 external/wpt/css/css-text/letter-spacing/letter-spacing-control-chars-001.html [ Failure ] crbug.com/921318 external/wpt/css/css-text/tab-size/tab-size-spacing-001.html [ Failure ] crbug.com/970200 external/wpt/css/css-text/text-indent/text-indent-tab-positions-001.html [ Failure ] @@ -6139,6 +6119,9 @@ crbug.com/1011811 http/tests/devtools/network/download.js [ Pass Failure ] crbug.com/1011811 http/tests/devtools/sxg/sxg-disable-cache.js [ Pass Failure ] +crbug.com/1080609 virtual/threaded/external/wpt/scroll-animations/element-based-offset.html [ Pass Failure ] +crbug.com/1080609 virtual/threaded/external/wpt/scroll-animations/element-based-offset-clamp.html [ Pass Failure ] + # Fails when test moved to use full compositor pipe. crbug.com/1085832 [ Fuchsia ] images/size-failure.html [ Timeout ] @@ -6475,3 +6458,5 @@ crbug.com/1138589 [ Mac10.15 ] fast/events/mouse-cursor-image-set-svg.html [ Failure ] crbug.com/1138591 [ Mac10.15 ] http/tests/dom/raf-throttling-out-of-view-cross-origin-page.html [ Failure ] +# WebRTC: Payload demuxing times out in Plan B. This is expected. +crbug.com/1139052 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/unbundled-pt-demuxing.https.html [ Timeout ]
diff --git a/third_party/blink/web_tests/android/ChromiumWPTExpectations b/third_party/blink/web_tests/android/ChromiumWPTExpectations index ae18897..69e57b7 100644 --- a/third_party/blink/web_tests/android/ChromiumWPTExpectations +++ b/third_party/blink/web_tests/android/ChromiumWPTExpectations
@@ -2753,8 +2753,9 @@ crbug.com/1050754 external/wpt/import-maps/acquire-import-maps-flag/dynamic-import/success.tentative.html [ Timeout ] crbug.com/1050754 external/wpt/import-maps/acquire-import-maps-flag/script-tag/success.tentative.html [ Timeout ] crbug.com/1050754 external/wpt/import-maps/acquire-import-maps-flag/worker-request/success.tentative.html [ Timeout ] -crbug.com/1050754 external/wpt/import-maps/common/parsing.tentative.html [ Failure ] -crbug.com/1050754 external/wpt/import-maps/common/resolving.tentative.html [ Failure ] +crbug.com/1050754 external/wpt/import-maps/common/parsing.tentative.https.html [ Failure ] +crbug.com/1050754 external/wpt/import-maps/common/resolving.tentative.https.html [ Failure ] +crbug.com/1050754 external/wpt/import-maps/common/resolving-internal.tentative.https.html [ Failure ] crbug.com/1050754 external/wpt/import-maps/core/bare.sub.tentative.html [ Failure ] crbug.com/1050754 external/wpt/import-maps/core/data.sub.tentative.html [ Failure ] crbug.com/1050754 external/wpt/import-maps/core/http.sub.tentative.html [ Failure ]
diff --git a/third_party/blink/web_tests/android/WeblayerWPTExpectations b/third_party/blink/web_tests/android/WeblayerWPTExpectations index 1541aca..28c9e1c 100644 --- a/third_party/blink/web_tests/android/WeblayerWPTExpectations +++ b/third_party/blink/web_tests/android/WeblayerWPTExpectations
@@ -2657,8 +2657,9 @@ crbug.com/1050754 external/wpt/import-maps/acquire-import-maps-flag/dynamic-import/success.tentative.html [ Timeout ] crbug.com/1050754 external/wpt/import-maps/acquire-import-maps-flag/script-tag/success.tentative.html [ Timeout ] crbug.com/1050754 external/wpt/import-maps/acquire-import-maps-flag/worker-request/success.tentative.html [ Timeout ] -crbug.com/1050754 external/wpt/import-maps/common/parsing.tentative.html [ Failure ] -crbug.com/1050754 external/wpt/import-maps/common/resolving.tentative.html [ Failure ] +crbug.com/1050754 external/wpt/import-maps/common/parsing.tentative.https.html [ Failure ] +crbug.com/1050754 external/wpt/import-maps/common/resolving.tentative.https.html [ Failure ] +crbug.com/1050754 external/wpt/import-maps/common/resolving-internal.tentative.https.html [ Failure ] crbug.com/1050754 external/wpt/import-maps/core/bare.sub.tentative.html [ Failure ] crbug.com/1050754 external/wpt/import-maps/core/data.sub.tentative.html [ Failure ] crbug.com/1050754 external/wpt/import-maps/core/http.sub.tentative.html [ Failure ]
diff --git a/third_party/blink/web_tests/android/WebviewWPTExpectations b/third_party/blink/web_tests/android/WebviewWPTExpectations index 667e397..405b546 100644 --- a/third_party/blink/web_tests/android/WebviewWPTExpectations +++ b/third_party/blink/web_tests/android/WebviewWPTExpectations
@@ -2870,8 +2870,9 @@ crbug.com/1050754 external/wpt/import-maps/acquire-import-maps-flag/dynamic-import/success.tentative.html [ Timeout ] crbug.com/1050754 external/wpt/import-maps/acquire-import-maps-flag/script-tag/success.tentative.html [ Timeout ] crbug.com/1050754 external/wpt/import-maps/acquire-import-maps-flag/worker-request/success.tentative.html [ Timeout ] -crbug.com/1050754 external/wpt/import-maps/common/parsing.tentative.html [ Failure ] -crbug.com/1050754 external/wpt/import-maps/common/resolving.tentative.html [ Failure ] +crbug.com/1050754 external/wpt/import-maps/common/parsing.tentative.https.html [ Failure ] +crbug.com/1050754 external/wpt/import-maps/common/resolving.tentative.https.html [ Failure ] +crbug.com/1050754 external/wpt/import-maps/common/resolving-internal.tentative.https.html [ Failure ] crbug.com/1050754 external/wpt/import-maps/core/bare.sub.tentative.html [ Failure ] crbug.com/1050754 external/wpt/import-maps/core/data.sub.tentative.html [ Failure ] crbug.com/1050754 external/wpt/import-maps/core/http.sub.tentative.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 7336e02e7..6c9c8b2 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -59793,7 +59793,7 @@ ] ], "align-items-007.html": [ - "01e8f001a8a39c8726cf9a9453dfad07d0e1b83a", + "704c82fc6ad92410ff50ba4e5bbe02913ab33fe9", [ null, [ @@ -61706,7 +61706,7 @@ ] ], "flex-minimum-height-flex-items-007.xht": [ - "e0e612627482d576acb6dd0857cc9f78f7cfa9e4", + "790ecb9141e40ecd583d0541cabb52939d5cfa37", [ null, [ @@ -196009,12 +196009,6 @@ [] ], "aspect-ratio": { - "parsing": { - "contain-intrinsic-size-valid-expected.txt": [ - "034b6db192f1fbc3b4c4b544602a6672b325f695", - [] - ] - }, "reference": { "ref-filled-green-100x20-rect.html": [ "5d8ebce4ec5a42533cb82829b778e1f65029d7e4", @@ -210124,7 +210118,7 @@ [] ], "density-corrected-size-bg-ref.html": [ - "758ca8edc60adccf491f7db3aa40dbba9d75798b", + "154c1344444c45180628d858ed053434fbd9cab2", [] ], "density-corrected-size-img-ref.html": [ @@ -219332,7 +219326,7 @@ [] ], "drawing-text-to-the-canvas.yaml": [ - "550746bbc230f13ae55367751965370d1f42be21", + "a00caef1764fcced8f51673e08e4738d95df6a4f", [] ], "fill-and-stroke-styles.yaml": [ @@ -219426,7 +219420,7 @@ [] ], "text.yaml": [ - "d204a562c2fdc74bc37b2aaff8dd0799ff849521", + "280f4335ae2bae7bfa09ff1d87951f2bcfe3af53", [] ], "the-canvas-state.yaml": [ @@ -232807,7 +232801,7 @@ [] ], "mediasource-worker-util.js": [ - "e0c4bdc0e10bb5707f7af75bf6cafa293a6f7b9b", + "4cee4862fa4e6c39c43fee7af1a332e8a7cd7ce2", [] ] }, @@ -284759,7 +284753,14 @@ ] ], "flex-aspect-ratio-img-column-011.html": [ - "66cb0e015f6618eb7cc3daee99f29ddbf7ed4729", + "6a0adb70dfd4886d25036104c1d72be90b564718", + [ + null, + {} + ] + ], + "flex-aspect-ratio-img-column-017.html": [ + "b2b97f0a31cfc7e67a67946b1cbad6ef0fbdbda8", [ null, {} @@ -295153,21 +295154,21 @@ "aspect-ratio": { "parsing": { "contain-intrinsic-size-computed.html": [ - "76fb5842ae691de4025795bc80777a61ceebbb6e", + "6a1f08a8a205222100a06d2fc3ff918564a3140a", [ null, {} ] ], "contain-intrinsic-size-invalid.html": [ - "e13c3ad07e1c25777cc9533407c0e57f6c6e5ddb", + "d85df5a844850d354621e835134a5c81d8b77ea7", [ null, {} ] ], "contain-intrinsic-size-valid.html": [ - "12f035d26f1e0d19e12fde8f981c05f36afb2c0e", + "7860e7556eca33c3f043bb553cefb9f71ae1b506", [ null, {} @@ -334402,6 +334403,20 @@ {} ] ], + "2d.text.drawing.style.fontKerning.html": [ + "b422b311276e854f5b9f0633bfba52fc7bc967c2", + [ + null, + {} + ] + ], + "2d.text.drawing.style.fontKerning.with.uppercase.html": [ + "db4adf73f09bf895e95b3e81b20962772ee7799e", + [ + null, + {} + ] + ], "2d.text.drawing.style.spacing.html": [ "a4ec083311ba0cdb32babf9b4e3351111c29ade5", [ @@ -348808,6 +348823,34 @@ {} ] ], + "2d.text.drawing.style.fontKerning.html": [ + "88b56c7562d388762d837a00e0f8389b8709c0d8", + [ + null, + {} + ] + ], + "2d.text.drawing.style.fontKerning.with.uppercase.html": [ + "5e394dba50a74da6c4ef07c40af1e4cbb7163df2", + [ + null, + {} + ] + ], + "2d.text.drawing.style.fontKerning.with.uppercase.worker.js": [ + "df3cd661884c38058326dd2e61084a9312fb952c", + [ + "html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.with.uppercase.worker.html", + {} + ] + ], + "2d.text.drawing.style.fontKerning.worker.js": [ + "d26bdec6ccf09e2153e393fadb594cf99e972fa7", + [ + "html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.worker.html", + {} + ] + ], "2d.text.drawing.style.spacing.html": [ "d3cf89ad7be91fda67b7f5e005533293b1581e0e", [ @@ -372580,15 +372623,22 @@ ] ], "dedicated-worker": { - "mediasource-worker-attach.html": [ - "b09f05c248531029b9b787597af1ae84e0b65ccd", + "mediasource-worker-objecturl.html": [ + "382a9a4f3632a53cd2a94dab121fe34a07d9238d", [ null, {} ] ], - "mediasource-worker-objecturl.html": [ - "382a9a4f3632a53cd2a94dab121fe34a07d9238d", + "mediasource-worker-play-terminate-worker.html": [ + "d1c1c3d3fe8b0feba9eebb8c4796e904c0bcbf2f", + [ + null, + {} + ] + ], + "mediasource-worker-play.html": [ + "200f8a851bfc396861ad93b501bcebd7209dffd6", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/is-where-error-recovery.tentative.html b/third_party/blink/web_tests/external/wpt/css/selectors/is-where-error-recovery.html similarity index 95% rename from third_party/blink/web_tests/external/wpt/css/selectors/is-where-error-recovery.tentative.html rename to third_party/blink/web_tests/external/wpt/css/selectors/is-where-error-recovery.html index 31f5b8cc..1d6e870e 100644 --- a/third_party/blink/web_tests/external/wpt/css/selectors/is-where-error-recovery.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/selectors/is-where-error-recovery.html
@@ -4,6 +4,7 @@ <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3676"> <link rel="help" href="https://drafts.csswg.org/selectors-4/#matches"> <link rel="help" href="https://drafts.csswg.org/selectors-4/#zero-matches"> +<link rel="help" href="https://drafts.csswg.org/selectors-4/#typedef-forgiving-selector-list"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <style id="test-sheet">
diff --git a/third_party/blink/web_tests/external/wpt/density-size-correction/density-corrected-size-bg-ref.html b/third_party/blink/web_tests/external/wpt/density-size-correction/density-corrected-size-bg-ref.html index 758ca8ed..154c1344 100644 --- a/third_party/blink/web_tests/external/wpt/density-size-correction/density-corrected-size-bg-ref.html +++ b/third_party/blink/web_tests/external/wpt/density-size-correction/density-corrected-size-bg-ref.html
@@ -6,26 +6,24 @@ <body> <style> body { - --lores: url(resources/exif-resolution-valid-lores.jpg); - --hires: url(resources/exif-resolution-valid-hires.jpg); --default: url(resources/exif-resolution-none.jpg); - --non-uniform: url(resources/exif-resolution-valid-non-uniform.jpg); } .default-bg {background-image: var(--default); } - .lores-bg {background-image: var(--lores); } - .hires-bg {background-image: var(--hires); } + .lores-bg {background-image: var(--default); background-size: 200px 100px; } + .hires-bg {background-image: var(--default); background-size: 50px 25px; } .invalid-bg {background-image: var(--invalid); } - .non-uniform-bg {background-image: var(--non-uniform); } + .non-uniform-bg {background-image: var(--default); background-size: 50px 100px; } .box { width: 200px; height: 200px; display: inline-block; } .tiled {background-repeat: repeat; } .stretch {background-repeat: no-repeat; background-size: contain; } + .non-uniform-bg.stretch { background-size: 100px 200px; } </style> <div class="default-bg tiled box"></div> <div class="lores-bg tiled box"></div> <div class="hires-bg tiled box"></div> <div class="non-uniform-bg tiled box"></div> <br/> - <div class="lores-bg stretch box"></div> + <div class="default-bg stretch box"></div> <div class="default-bg stretch box"></div> <div class="non-uniform-bg stretch box"></div> </body>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-percent-height.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-percent-height.html new file mode 100644 index 0000000..bbe40785 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-percent-height.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<table cellspacing="0" cellpadding="0" style="width:100px; height:60px;"> + <tr> + <td> + <fieldset style="border:none; padding:0; height:100%; margin:0; margin-top:13px;"> + <div><div id="elm"></div></div> + </fieldset> + </td> + </tr> +</table> +<script> +// crbug.com/1138204. Though the specification doesn't mention this behavior, +// there must be no doubt about the expected behavior. +test(() => { + const fieldset = document.querySelector('fieldset'); + const initialHeight = fieldset.offsetHeight; + document.querySelector('#elm').style.display = 'none'; + assert_equals(fieldset.offsetHeight, initialHeight); +}, 'Fieldset with a percent height should not increase the height on every reflow.'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/common/common-test-service-worker.js b/third_party/blink/web_tests/external/wpt/import-maps/common/common-test-service-worker.js new file mode 100644 index 0000000..6985c90 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/import-maps/common/common-test-service-worker.js
@@ -0,0 +1,28 @@ +let serveImporterScript = false; + +self.addEventListener('message', event => { + serveImporterScript = true; + event.source.postMessage('Done'); +}); + +self.addEventListener('fetch', event => { + if (event.request.url.indexOf('common-test-helper-iframe.js') >= 0) { + return; + } + if (serveImporterScript) { + serveImporterScript = false; + event.respondWith( + new Response( + 'window.importHelper = (specifier) => import(specifier);', + {headers: {'Content-Type': 'text/javascript'}} + )); + } else { + event.respondWith( + new Response( + 'export const response = ' + + JSON.stringify({url: event.request.url}) + ';', + {headers: {'Access-Control-Allow-Origin': '*', + 'Content-Type': 'text/javascript'}} + )); + } +});
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/common/parsing.tentative.html b/third_party/blink/web_tests/external/wpt/import-maps/common/parsing.tentative.https.html similarity index 61% rename from third_party/blink/web_tests/external/wpt/import-maps/common/parsing.tentative.html rename to third_party/blink/web_tests/external/wpt/import-maps/common/parsing.tentative.https.html index d3334d7..0dc9e24 100644 --- a/third_party/blink/web_tests/external/wpt/import-maps/common/parsing.tentative.html +++ b/third_party/blink/web_tests/external/wpt/import-maps/common/parsing.tentative.https.html
@@ -2,9 +2,16 @@ <meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> +<script> +// All parsing tests requires Chromium's internal methods. +globalThis.useInternalMethods = true; +</script> <body> <script type="module"> -import { runTestsFromJSON } from "./resources/common-test-helper.js"; +import { runTestsFromJSON, setupGlobalCleanup } from "./resources/common-test-helper.js"; + +const promises = []; for (const json of [ 'resources/parsing-addresses-absolute.json', @@ -19,8 +26,13 @@ 'resources/parsing-specifier-keys.json', 'resources/parsing-trailing-slashes.json', ]) { - promise_test(() => - runTestsFromJSON(json), + promise_test(() => { + const promise = runTestsFromJSON(json); + promises.push(promise); + return promise; + }, "Test helper: fetching and sanity checking test JSON: " + json); } + +Promise.all(promises).then(setupGlobalCleanup); </script>
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/common/resolving-internal.tentative.https.html b/third_party/blink/web_tests/external/wpt/import-maps/common/resolving-internal.tentative.https.html new file mode 100644 index 0000000..a9f7c82 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/import-maps/common/resolving-internal.tentative.https.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> +<script> +// This test file is for resolution tests that require Chromium's internal +// methods. +// For tests that don't use Chromium's internal methods, see +// resolving.tentative.https.html. +globalThis.useInternalMethods = true; +</script> +<body> +<script type="module"> +import { runTestsFromJSON, setupGlobalCleanup } from "./resources/common-test-helper.js"; + +const promises = []; + +for (const json of [ + 'resources/empty-import-map-internal.json', +]) { + promise_test(() => { + const promise = runTestsFromJSON(json); + promises.push(promise); + return promise; + }, + "Test helper: fetching and sanity checking test JSON: " + json); +} + +Promise.all(promises).then(setupGlobalCleanup); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/common/resolving.tentative.html b/third_party/blink/web_tests/external/wpt/import-maps/common/resolving.tentative.https.html similarity index 62% rename from third_party/blink/web_tests/external/wpt/import-maps/common/resolving.tentative.html rename to third_party/blink/web_tests/external/wpt/import-maps/common/resolving.tentative.https.html index 8dd3e3a2..abb30e0 100644 --- a/third_party/blink/web_tests/external/wpt/import-maps/common/resolving.tentative.html +++ b/third_party/blink/web_tests/external/wpt/import-maps/common/resolving.tentative.https.html
@@ -2,9 +2,12 @@ <meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> <body> <script type="module"> -import { runTestsFromJSON } from "./resources/common-test-helper.js"; +import { runTestsFromJSON, setupGlobalCleanup } from "./resources/common-test-helper.js"; + +const promises = []; for (const json of [ 'resources/scopes.json', @@ -17,8 +20,13 @@ 'resources/overlapping-entries.json', 'resources/resolving-null.json', ]) { - promise_test(() => - runTestsFromJSON(json), + promise_test(() => { + const promise = runTestsFromJSON(json); + promises.push(promise); + return promise; + }, "Test helper: fetching and sanity checking test JSON: " + json); } + +Promise.all(promises).then(setupGlobalCleanup); </script>
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/common/resources/common-test-helper-iframe.js b/third_party/blink/web_tests/external/wpt/import-maps/common/resources/common-test-helper-iframe.js new file mode 100644 index 0000000..597955f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/import-maps/common/resources/common-test-helper-iframe.js
@@ -0,0 +1,103 @@ +// Handle errors around fetching, parsing and registering import maps. +const onScriptError = event => { + window.registrationResult = {type: 'FetchError', error: event.error}; + return false; +}; +window.windowErrorHandler = event => { + window.registrationResult = {type: 'ParseError', error: event.error}; + return false; +}; +window.addEventListener('error', window.windowErrorHandler); + +// Handle specifier resolution requests from the parent frame. +// For failures, we post error names and messages instead of error +// objects themselves and re-create error objects later, to avoid +// issues around serializing error objects which is a quite new feature. +window.addEventListener('message', event => { + if (event.data.action === 'prepareResolve') { + // To get the result of #resolve-a-module-specifier given a script + // (with base URL = |baseURL|) and |specifier|, the service worker + // first serves an importer script with response URL = |baseURL|: + // window.importHelper = (specifier) => import(specifier); + // This is to use |baseURL| as the referringScript's base URL. + + // Step 1. Signal the service worker to serve + // the importer script for the next fetch request. + parent.worker.postMessage('serveImporterScript'); + } else if (event.data.action === 'resolve') { + if (event.data.expectedURL === null || + new URL(event.data.expectedURL).protocol === 'https:') { + // Testing without internal methods: + // If the resolution is expected to fail (null case here), + // we can test the failure just by catching the exception. + // If the expected URL is HTTPS, we can test the result by + // intercepting requests by service workers. + + // Step 3. Evaluate the importer script as a classic script, + // in order to prevent |baseURL| from being mapped by import maps. + const script = document.createElement('script'); + script.onload = () => { + // Step 4. Trigger dynamic import from |baseURL|. + importHelper(event.data.specifier) + .then(module => { + // Step 5. Service worker responds with a JSON containing + // the request URL for the dynamic import + // (= the result of #resolve-a-module-specifier). + parent.postMessage({type: 'ResolutionSuccess', + result: module.response.url}, + '*'); + }) + .catch(e => { + parent.postMessage( + {type: 'Failure', result: e.name, message: e.message}, + '*'); + }); + }; + script.src = event.data.baseURL; + document.body.appendChild(script); + } else { + // Testing with internal methods. + // For example, the resolution results are data: URLs. + if (!event.data.useInternalMethods) { + parent.postMessage( + {type: 'Failure', + result: 'Error', + message: 'internals.resolveModuleSpecifier is not available'}, + '*'); + return; + } + try { + const result = internals.resolveModuleSpecifier( + event.data.specifier, + event.data.baseURL, + document); + parent.postMessage( + {type: 'ResolutionSuccess', result: result}, '*'); + } catch (e) { + parent.postMessage( + {type: 'Failure', result: e.name, message: e.message}, '*'); + } + } + } else if (event.data.action === 'getParsedImportMap') { + if (!event.data.useInternalMethods) { + parent.postMessage( + {type: 'Failure', + result: 'Error', + message: 'internals.getParsedImportMap is not available'}, + '*'); + } + try { + parent.postMessage({ + type: 'GetParsedImportMapSuccess', + result: internals.getParsedImportMap(document)}, '*'); + } catch (e) { + parent.postMessage( + {type: 'Failure', result: e.name, message: e.message}, '*'); + } + } else { + parent.postMessage({ + type: 'Failure', + result: 'Error', + message: 'Invalid Action: ' + event.data.action}, '*'); + } +});
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/common/resources/common-test-helper.js b/third_party/blink/web_tests/external/wpt/import-maps/common/resources/common-test-helper.js index f7269db..2bf9918 100644 --- a/third_party/blink/web_tests/external/wpt/import-maps/common/resources/common-test-helper.js +++ b/third_party/blink/web_tests/external/wpt/import-maps/common/resources/common-test-helper.js
@@ -1,5 +1,27 @@ setup({allow_uncaught_exception : true}); +// Set window.useInternalMethods = true when needed && available. + +let registration; +const scope = './scope/'; + +// Global setup: this must be the first promise_test. +promise_test(async (t) => { + const script = 'common-test-service-worker.js'; + + registration = + await service_worker_unregister_and_register(t, script, scope); + window.worker = registration.installing; + await wait_for_state(t, window.worker, 'activated'); +}, 'global setup'); + +export function setupGlobalCleanup() { + // Global cleanup: the final promise_test. + promise_test(() => { + return registration.unregister(); + }, 'global cleanup'); +} + // Creates a new Document (via <iframe>) and add an inline import map. function parse(importMap, importMapBaseURL) { return new Promise(resolve => { @@ -15,79 +37,51 @@ {once: true}); const testHTML = ` - <script> - // Handle errors around fetching, parsing and registering import maps. - let registrationResult; - const onScriptError = event => { - registrationResult = {type: 'FetchError', error: event.error}; - return false; - }; - const windowErrorHandler = event => { - registrationResult = {type: 'ParseError', error: event.error}; - return false; - }; - window.addEventListener('error', windowErrorHandler); - window.addEventListener('load', event => { - if (!registrationResult) { - registrationResult = {type: 'Success'}; - } - window.removeEventListener('error', windowErrorHandler); - parent.postMessage(registrationResult, '*'); - }); - - // Handle specifier resolution requests from the parent frame. - window.addEventListener('message', event => { - try { - if (event.data.action === 'resolve') { - // URL resolution is tested using Chromium's internals. - // TODO(hiroshige): Remove the Chromium-specific dependency. - const result = internals.resolveModuleSpecifier( - event.data.specifier, - event.data.baseURL, - document); - parent.postMessage({type: 'ResolutionSuccess', result: result}, '*'); - } else if (event.data.action === 'getParsedImportMap') { - parent.postMessage({ - type: 'GetParsedImportMapSuccess', - result: internals.getParsedImportMap(document)}, '*'); - } else { - parent.postMessage({ - type: 'Failure', - result: "Invalid Action: " + event.data.action}, '*'); - } - } catch (e) { - // We post error names instead of error objects themselves and - // re-create error objects later, to avoid issues around serializing - // error objects which is a quite new feature. - parent.postMessage({type: 'Failure', result: e.name}, '*'); - } - }); - </script> + <body> + <script src="${location.origin}/import-maps/common/resources/common-test-helper-iframe.js"></script> <script type="importmap" onerror="onScriptError(event)"> ${importMapString} </script> + <script type="module"> + if (!window.registrationResult) { + window.registrationResult = {type: 'Success'}; + } + window.removeEventListener('error', window.windowErrorHandler); + parent.postMessage(window.registrationResult, '*'); + </script> + </body> `; if (new URL(importMapBaseURL).protocol === 'data:') { + if (!window.useInternalMethods) { + throw new Error( + 'Import maps with base URL = data: URL requires internal methods'); + } iframe.src = 'data:text/html;base64,' + btoa(testHTML); } else { - iframe.srcdoc = `<base href="${importMapBaseURL}">` + testHTML; + // Set the src to `scope` in order to make requests from `iframe` + // intercepted by the service worker. + iframe.src = scope; + iframe.onload = () => { + iframe.contentDocument.write( + `<base href="${importMapBaseURL}">` + testHTML); + iframe.contentDocument.close(); + }; } - document.body.appendChild(iframe); - }); } // Returns a promise that is resolved with the resulting URL. -function resolve(specifier, parsedImportMap, baseURL) { +// `expectedURL` is a string, or null if to be thrown. +function resolve(specifier, parsedImportMap, baseURL, expectedURL) { return new Promise((resolve, reject) => { window.addEventListener('message', event => { if (event.data.type === 'ResolutionSuccess') { resolve(event.data.result); } else if (event.data.type === 'Failure') { if (event.data.result === 'TypeError') { - reject(new TypeError()); + reject(new TypeError(event.data.message)); } else { reject(new Error(event.data.result)); } @@ -97,8 +91,20 @@ }, {once: true}); - parsedImportMap.contentWindow.postMessage( - {action: "resolve", specifier: specifier, baseURL: baseURL}, '*'); + parsedImportMap.contentWindow.postMessage({action: 'prepareResolve'}, '*'); + + navigator.serviceWorker.addEventListener('message', event => { + // Step 2. After postMessage() at Step 1 is processed, the service worker + // sends back a message and the parent Window receives the message here + // and sends a 'resolve' message to the iframe. + parsedImportMap.contentWindow.postMessage( + {action: 'resolve', + specifier: specifier, + baseURL: baseURL, + expectedURL: expectedURL, + useInternalMethods: window.useInternalMethods}, + '*'); + }, {once: true}); }); } @@ -112,14 +118,15 @@ {once: true}); parsedImportMap.contentWindow.postMessage( - {action: "getParsedImportMap"}, '*'); + {action: 'getParsedImportMap', + useInternalMethods: window.useInternalMethods}, '*'); }); } function assert_no_extra_properties(object, expectedProperties, description) { for (const actualProperty in object) { assert_true(expectedProperties.indexOf(actualProperty) !== -1, - description + ": unexpected property " + actualProperty); + description + ': unexpected property ' + actualProperty); } } @@ -184,18 +191,18 @@ assert_own_property(j, 'baseURL'); assert_equals( j.parsedImportMap.parseImportMapResult, - "Success", - "Import map registration should be successful for resolution tests"); + 'Success', + 'Import map registration should be successful for resolution tests'); for (const specifier in j.expectedResults) { const expected = j.expectedResults[specifier]; promise_test(async t => { if (expected === null) { return promise_rejects_js(t, TypeError, - resolve(specifier, j.parsedImportMap, j.baseURL)); + resolve(specifier, j.parsedImportMap, j.baseURL, null)); } else { // Should be resolved to `expected`. const actual = await resolve( - specifier, j.parsedImportMap, j.baseURL); + specifier, j.parsedImportMap, j.baseURL, expected); assert_equals(actual, expected); } }, @@ -207,7 +214,7 @@ if (j.hasOwnProperty('expectedParsedImportMap')) { promise_test(async t => { if (j.expectedParsedImportMap === null) { - assert_equals(j.parsedImportMap.parseImportMapResult, "ParseError"); + assert_equals(j.parsedImportMap.parseImportMapResult, 'ParseError'); } else { const actualParsedImportMap = await getParsedImportMap(j.parsedImportMap);
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/common/resources/empty-import-map-internal.json b/third_party/blink/web_tests/external/wpt/import-maps/common/resources/empty-import-map-internal.json new file mode 100644 index 0000000..59390c8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/import-maps/common/resources/empty-import-map-internal.json
@@ -0,0 +1,20 @@ +{ + "importMap": {}, + "importMapBaseURL": "https://example.com/app/index.html", + "baseURL": "https://example.com/js/app.mjs", + "tests": { + "non-HTTPS fetch scheme absolute URLs": { + "expectedResults": { + "about:fetch-scheme": "about:fetch-scheme" + } + }, + "non-fetch scheme absolute URLs": { + "expectedResults": { + "mailto:non-fetch-scheme": "mailto:non-fetch-scheme", + "import:non-fetch-scheme": "import:non-fetch-scheme", + "javascript:non-fetch-scheme": "javascript:non-fetch-scheme", + "wss:non-fetch-scheme": "wss://non-fetch-scheme/" + } + } + } +}
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/common/resources/empty-import-map.json b/third_party/blink/web_tests/external/wpt/import-maps/common/resources/empty-import-map.json index ce6c185..ff85a6d 100644 --- a/third_party/blink/web_tests/external/wpt/import-maps/common/resources/empty-import-map.json +++ b/third_party/blink/web_tests/external/wpt/import-maps/common/resources/empty-import-map.json
@@ -18,23 +18,14 @@ "/../foo/../bar": "https://example.com/bar" } }, - "fetch scheme absolute URLs": { + "HTTPS scheme absolute URLs": { "expectedResults": { - "about:fetch-scheme": "about:fetch-scheme", "https://fetch-scheme.net": "https://fetch-scheme.net/", "https:fetch-scheme.org": "https://fetch-scheme.org/", "https://fetch%2Dscheme.com/": "https://fetch-scheme.com/", "https://///fetch-scheme.com///": "https://fetch-scheme.com///" } }, - "non-fetch scheme absolute URLs": { - "expectedResults": { - "mailto:non-fetch-scheme": "mailto:non-fetch-scheme", - "import:non-fetch-scheme": "import:non-fetch-scheme", - "javascript:non-fetch-scheme": "javascript:non-fetch-scheme", - "wss:non-fetch-scheme": "wss://non-fetch-scheme/" - } - }, "valid relative URLs that are invalid as specifiers should fail": { "expectedResults": { "invalid-specifier": null,
diff --git a/third_party/blink/web_tests/external/wpt/lint.ignore b/third_party/blink/web_tests/external/wpt/lint.ignore index fe2933b..b44faa4 100644 --- a/third_party/blink/web_tests/external/wpt/lint.ignore +++ b/third_party/blink/web_tests/external/wpt/lint.ignore
@@ -690,7 +690,7 @@ MISSING-LINK: css/filter-effects/*.any.js # Tests that use WebKit/Blink testing APIs -LAYOUTTESTS APIS: import-maps/common/resources/common-test-helper.js +LAYOUTTESTS APIS: import-maps/common/resources/common-test-helper-iframe.js LAYOUTTESTS APIS: resources/chromium/enable-hyperlink-auditing.js LAYOUTTESTS APIS: resources/chromium/generic_sensor_mocks.js LAYOUTTESTS APIS: resources/chromium/webxr-test.js
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/element-based-offset-clamp.html b/third_party/blink/web_tests/external/wpt/scroll-animations/element-based-offset-clamp.html index 6467af19..b1405074 100644 --- a/third_party/blink/web_tests/external/wpt/scroll-animations/element-based-offset-clamp.html +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/element-based-offset-clamp.html
@@ -7,19 +7,25 @@ <script src="testcommon.js"></script> <style> -/* - * Overflow hidden prevents user scroll including mouse wheel; however, the - * element is still a scrollable container and can be scrolled programmatically. - * Removing the visible scrollbars in this manner simplifies the position - * calculations in the text. - */ .scroller { - overflow: hidden; + overflow: scroll; height: 500px; width: 500px; will-change: transform; } +/* Disable scrollbars to simplify the calculations in the test. */ +.scroller { + scrollbar-width: 0; +} +/* +Chrome does not support scrollbar-width so we use this non-standard property +until it does. +*/ +.scroller::-webkit-scrollbar { + display: none; +} + .contents { height: 1200px; width: 1200px; @@ -206,4 +212,4 @@ createScrollAnimationTest(description, config); } } -</script> +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/protocol/unbundled-pt-demuxing.https.html b/third_party/blink/web_tests/external/wpt/webrtc/protocol/unbundled-pt-demuxing.https.html new file mode 100644 index 0000000..e9f07e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webrtc/protocol/unbundled-pt-demuxing.https.html
@@ -0,0 +1,56 @@ +<!doctype html> +<meta charset=utf-8> +<title>RTCPeerConnection payload type demuxing for unbundled connections</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../RTCPeerConnection-helper.js"></script> +<script> +'use strict'; +promise_test(async t => { + const caller = new RTCPeerConnection({bundlePolicy: 'max-compat'}); + t.add_cleanup(() => caller.close()); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => callee.close()); + + const stream = await getNoiseStream({video: true}); + t.add_cleanup(() => stream.getTracks().forEach(track => track.stop())); + stream.getTracks().forEach(track => caller.addTrack(track, stream)); + stream.getTracks().forEach(track => caller.addTrack(track.clone(), stream.clone())); + + let callCount = 0; + let metadataToBeLoaded = new Promise(resolve => { + callee.ontrack = (e) => { + const stream = e.streams[0]; + const v = document.createElement('video'); + v.autoplay = true; + v.srcObject = stream; + v.id = stream.id + v.addEventListener('loadedmetadata', () => { + if (++callCount === 2) { + resolve(); + } + }); + }; + }); + + exchangeIceCandidates(caller, callee); + + const offer = await caller.createOffer(); + // Replace BUNDLE, the mid header extension and all ssrc lines + // with bogus. The receiver will be forced to do payload type demuxing + // which is still possible because the different m-lines arrive on + // different ports/sockets. + const sdp = offer.sdp.replace('BUNDLE', 'SOMETHING') + .replace(/rtp-hdrext:sdes/g, 'rtp-hdrext:something') + .replace(/a=ssrc:/g, 'a=notssrc'); + + await callee.setRemoteDescription({type: 'offer', sdp}); + await caller.setLocalDescription(offer); + + const answer = await callee.createAnswer(); + await caller.setRemoteDescription(answer); + await callee.setLocalDescription(answer); + + await metadataToBeLoaded; +}, 'Can demux two video tracks on an unbundled connection by payload type'); +</script>
diff --git a/third_party/blink/web_tests/fast/ruby/following-tab-crash.html b/third_party/blink/web_tests/fast/ruby/following-tab-crash.html new file mode 100644 index 0000000..5388ec9 --- /dev/null +++ b/third_party/blink/web_tests/fast/ruby/following-tab-crash.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<style> +#container { + width: 10em; + white-space: pre-wrap; +} +</style> +<body> +<div id=container></div> +<script> +test(() => { + const div = document.querySelector('#container'); + div.innerHTML = '<ruby>xx<rt>foo bar foo bar foo bar foo bar foo bar</rt></ruby><span>	</span>'; + // Force layout. + div.clientHeight; + // Success if CommitPendingEndOverhang() didn't crash in |div.clientHeight|. +}, 'Overhanging ruby followed by a TAB should not crash'); +</script> +</body>
diff --git a/third_party/blink/web_tests/http/tests/websocket/resources/connect-error-by-no-websocket-server.js b/third_party/blink/web_tests/http/tests/websocket/resources/connect-error-by-no-websocket-server.js index 4a10595..1c8c2a1c 100644 --- a/third_party/blink/web_tests/http/tests/websocket/resources/connect-error-by-no-websocket-server.js +++ b/third_party/blink/web_tests/http/tests/websocket/resources/connect-error-by-no-websocket-server.js
@@ -53,9 +53,9 @@ } }; - // Each failure to connect to 127.0.0.1 takes 1 second on Windows. - // Allow 2 seconds for padding. - timeoutID = setTimeout(timeOutCallback, 2000); + // Each failure to connect to 127.0.0.1 takes 3 seconds on Windows. + // Allow 4 seconds for padding. + timeoutID = setTimeout(timeOutCallback, 4000); } function timeOutCallback()
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/parsing/hyphens-computed-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/parsing/hyphens-computed-expected.txt deleted file mode 100644 index 10fa6879..0000000 --- a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/parsing/hyphens-computed-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -This is a testharness.js-based test. -PASS Property hyphens value 'none' -PASS Property hyphens value 'manual' -PASS Property hyphens value 'auto' -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/parsing/hyphens-computed-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/parsing/hyphens-computed-expected.txt deleted file mode 100644 index de12ec39..0000000 --- a/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/parsing/hyphens-computed-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -This is a testharness.js-based test. -PASS Property hyphens value 'none' -PASS Property hyphens value 'manual' -FAIL Property hyphens value 'auto' assert_true: 'auto' is a supported value for hyphens. expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/parsing/hyphens-valid-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/parsing/hyphens-valid-expected.txt deleted file mode 100644 index bc3ee835..0000000 --- a/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/parsing/hyphens-valid-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -This is a testharness.js-based test. -PASS e.style['hyphens'] = "none" should set the property value -PASS e.style['hyphens'] = "manual" should set the property value -FAIL e.style['hyphens'] = "auto" should set the property value assert_not_equals: property should be set got disallowed value "" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win/virtual/text-antialias/hyphens/hyphens-parsing-001-expected.txt b/third_party/blink/web_tests/platform/win/virtual/text-antialias/hyphens/hyphens-parsing-001-expected.txt deleted file mode 100644 index f6344a7..0000000 --- a/third_party/blink/web_tests/platform/win/virtual/text-antialias/hyphens/hyphens-parsing-001-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS Initial value -FAIL hyphens: auto assert_equals: expected "auto" but got "manual" -PASS hyphens: manual -PASS hyphens: none -FAIL hyphens should inherit assert_equals: expected "auto" but got "manual" -Harness: the test ran to completion. -
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp index 068cbc6..826b94c1 100644 --- a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp +++ b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
@@ -88,8 +88,10 @@ options_.checked_namespaces.insert("blink"); // Ignore GC implementation files. - options_.ignored_directories.push_back("/heap/"); - options_.allowed_directories.push_back("/test/"); + options_.ignored_directories.push_back( + "third_party/blink/renderer/platform/heap/"); + options_.allowed_directories.push_back( + "third_party/blink/renderer/platform/heap/test/"); } void BlinkGCPluginConsumer::HandleTranslationUnit(ASTContext& context) {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index eb8e2ad..643c55d 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -15999,6 +15999,7 @@ <int value="36" label="Web Store"/> <int value="37" label="YouTube"/> <int value="38" label="YouTube Music"/> + <int value="40" label="Stadia"/> </enum> <enum name="DefaultBrowserAsyncAttemptResult"> @@ -38731,6 +38732,23 @@ <int value="6" label="Most Visited Entry"/> </enum> +<enum name="IOSMultiWindowConfiguration"> + <int value="0" label="Unspecified"/> + <int value="1" label="Fullscreen"/> + <int value="2" label="Fullscreen with Slideover"/> + <int value="3" label="Shared Standard"/> + <int value="4" label="Shared Standard with Slideover"/> + <int value="5" label="Shared Compact"/> + <int value="6" label="Shared Compact with Slideover"/> + <int value="7" label="Slideover"/> + <int value="8" label="Standard beside Standard"/> + <int value="9" label="Standard beside Standard with Slideover"/> + <int value="10" label="Standard beside Compact"/> + <int value="11" label="Standard beside Compact with Slideover"/> + <int value="12" label="Compact beside Compact"/> + <int value="13" label="Compact beside Compact with Slideover"/> +</enum> + <enum name="IOSNTPImpression"> <int value="0" label="Local suggestions"/> <int value="1" label="Remote suggestions"/> @@ -41913,6 +41931,7 @@ <int value="-1722208902" label="CCTModuleCustomRequestHeader:disabled"/> <int value="-1720653947" label="WebRtcHybridAgc:disabled"/> <int value="-1719833926" label="disable-answers-in-suggest"/> + <int value="-1719699712" label="AudioPlayerJsModules:enabled"/> <int value="-1718074215" label="HomepageSettingsUIConversion:enabled"/> <int value="-1716654100" label="tab-capture-downscale-quality"/> <int value="-1716140224" label="EnableEmbeddedAssistantUI:disabled"/> @@ -43111,6 +43130,7 @@ <int value="-547301855" label="SyncPseudoUSSSupervisedUsers:enabled"/> <int value="-544685871" label="NewOsSettingsSearch:enabled"/> <int value="-544629557" label="CSSBackdropFilter:enabled"/> + <int value="-541764089" label="AudioPlayerJsModules:disabled"/> <int value="-541611402" label="OfflinePagesPrefetching:enabled"/> <int value="-540150399" label="TapVisualizerApp:enabled"/> <int value="-538141684" label="SafetyTip:enabled"/> @@ -43215,6 +43235,7 @@ <int value="-457292000" label="HappinessTrackingSurveysForDesktop:enabled"/> <int value="-457174225" label="Av1Decoder:enabled"/> <int value="-456321929" label="ForceEnableSystemAec:disabled"/> + <int value="-455413094" label="FilesJsModules:enabled"/> <int value="-455203267" label="use_new_features_summary"/> <int value="-454362199" label="HelpAppV2:disabled"/> <int value="-450976085" @@ -43268,6 +43289,7 @@ <int value="-396046249" label="PhotoPickerVideoSupport:enabled"/> <int value="-395606844" label="enable-site-settings"/> <int value="-395454065" label="DisablePostScriptPrinting:disabled"/> + <int value="-395259448" label="VideoPlayerJsModules:disabled"/> <int value="-394734604" label="FillingPasswordsFromAnyOrigin:disabled"/> <int value="-389664522" label="OmniboxUIExperimentHideSteadyStateUrlPathQueryAndRefOnInteraction:enabled"/> @@ -43792,6 +43814,7 @@ <int value="128086566" label="D3D11VideoDecoder:enabled"/> <int value="128323385" label="WebUIOmniboxPopup:enabled"/> <int value="129458360" label="LiteVideo:disabled"/> + <int value="130939792" label="FilesJsModules:disabled"/> <int value="131881947" label="D3DVsync:enabled"/> <int value="132560299" label="OmniboxUIExperimentHideSteadyStateUrlScheme:disabled"/> @@ -43877,6 +43900,7 @@ <int value="245896533" label="SearchSuggestionsOnLocalNtp:enabled"/> <int value="247200195" label="EnhancedProtectionPromoCard:enabled"/> <int value="250855010" label="WebAssemblyBaseline:disabled"/> + <int value="254497185" label="VideoPlayerJsModules:enabled"/> <int value="255375615" label="stop-non-timers-in-background:enabled"/> <int value="258621334" label="HappinessTrackingSurveysForDesktopDemo:disabled"/> @@ -73122,6 +73146,10 @@ <int value="57" label="kErrorCodeInternalLibCurlError"/> <int value="58" label="kErrorCodeUnresolvedHostError"/> <int value="59" label="kErrorCodeUnresolvedHostRecovered"/> + <int value="60" label="kErrorUnresolvedHostRecovered"/> + <int value="61" label="kErrorNotEnoughSpace"/> + <int value="62" label="kErrorDeviceCorrupted"/> + <int value="63" label="kErrorPackageExcludedFromUpdate"/> </enum> <enum name="UpdateEngineInstallDateProvisioningSource">
diff --git a/tools/metrics/histograms/histograms_xml/ios/histograms.xml b/tools/metrics/histograms/histograms_xml/ios/histograms.xml index 6f83a1c..bfccb0ac 100644 --- a/tools/metrics/histograms/histograms_xml/ios/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/ios/histograms.xml
@@ -495,6 +495,13 @@ </summary> </histogram> +<histogram name="IOS.MultiWindow.Configuration" + enum="IOSMultiWindowConfiguration" expires_after="2021-06-30"> + <owner>marq@chromium.org</owner> + <owner>djean@chromium.org</owner> + <summary>MultiWindow configration sampled once per minute.</summary> +</histogram> + <histogram name="IOS.MultiWindow.OpenInNewWindow" enum="WindowActivityOrigin" expires_after="2021-06-30"> <owner>marq@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/sync/histograms.xml b/tools/metrics/histograms/histograms_xml/sync/histograms.xml index 85ec85f..8a6b0c4 100644 --- a/tools/metrics/histograms/histograms_xml/sync/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/sync/histograms.xml
@@ -616,7 +616,10 @@ </histogram> <histogram name="Sync.PeakAnalysis.StopAfterAccountStateChanged" units="hits" - expires_after="M88"> + expires_after="2020-10-15"> + <obsolete> + Removed 2020-10. + </obsolete> <owner>tschumann@chromium.org</owner> <owner>treib@chromium.org</owner> <summary> @@ -630,7 +633,10 @@ </histogram> <histogram name="Sync.PeakAnalysis.StopAfterCredentialsChanged" units="hits" - expires_after="M88"> + expires_after="2020-10-15"> + <obsolete> + Removed 2020-10. + </obsolete> <owner>tschumann@chromium.org</owner> <owner>treib@chromium.org</owner> <summary> @@ -643,7 +649,10 @@ </histogram> <histogram name="Sync.PeakAnalysis.StopOnSyncManagedPrefChange" units="hits" - expires_after="M88"> + expires_after="2020-10-15"> + <obsolete> + Removed 2020-10. + </obsolete> <owner>tschumann@chromium.org</owner> <owner>treib@chromium.org</owner> <summary> @@ -655,7 +664,10 @@ </histogram> <histogram name="Sync.PeakAnalysis.StopOnSyncPermanentlyDisabled" units="hits" - expires_after="M88"> + expires_after="2020-10-15"> + <obsolete> + Removed 2020-10. + </obsolete> <owner>tschumann@chromium.org</owner> <owner>treib@chromium.org</owner> <summary>
diff --git a/ui/file_manager/file_manager/background/js/BUILD.gn b/ui/file_manager/file_manager/background/js/BUILD.gn index 2c00a02..da87fb9 100644 --- a/ui/file_manager/file_manager/background/js/BUILD.gn +++ b/ui/file_manager/file_manager/background/js/BUILD.gn
@@ -435,6 +435,8 @@ ":progress_center", "//ui/webui/resources/js/cr:event_target", ] + visibility += + [ "//ui/file_manager/file_manager/foreground/js:file_tasks_unittest" ] } js_library("progress_center") {
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 d36abca6..5645abd 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -2647,7 +2647,7 @@ background-position: center center; background-repeat: no-repeat; color: #888; - content: '\00a0'; + content: ' '; padding-inline-start: 13px; position: relative; top: 1px; @@ -2660,7 +2660,7 @@ background-position: center center; background-repeat: no-repeat; color: #888; - content: '\00a0'; + content: ' '; padding-inline-start: 13px; position: relative; top: -1px;
diff --git a/ui/file_manager/file_manager/foreground/css/menu.css b/ui/file_manager/file_manager/foreground/css/menu.css index 3b98fd05..7b89199 100644 --- a/ui/file_manager/file_manager/foreground/css/menu.css +++ b/ui/file_manager/file_manager/foreground/css/menu.css
@@ -43,13 +43,13 @@ cr-menu > [sub-menu]::after { color: rgb(100, 100, 100); - content: '\25b6'; + content: '▶'; float: right; font-size: 0.7em; } html[dir='rtl'] cr-menu > [sub-menu]::after { - content: '\25c0'; + content: '◀'; float: left; }
diff --git a/ui/file_manager/file_manager/foreground/elements/files_metadata_entry.html b/ui/file_manager/file_manager/foreground/elements/files_metadata_entry.html index b7d0a67..a9837ec 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_metadata_entry.html +++ b/ui/file_manager/file_manager/foreground/elements/files_metadata_entry.html
@@ -48,7 +48,7 @@ #value[loading]::after { animation: ellipsis 1s steps(4,end) 100ms infinite; - content: '\2026'; /* Unicode horizontal ellipsis */ + content: '…'; display: inline-block; overflow: hidden; transform: scale(2.5) translate(0, 1px);
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn index 98e88d58..5029f19 100644 --- a/ui/file_manager/file_manager/foreground/js/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -462,6 +462,7 @@ "//ui/file_manager/base/js:mock_chrome", "//ui/file_manager/base/js:test_error_reporting", "//ui/file_manager/file_manager/background/js:mock_crostini", + "//ui/file_manager/file_manager/background/js:mock_progress_center", "//ui/file_manager/file_manager/common/js:mock_entry", ] }
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.js b/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.js index c997a6a..615549f 100644 --- a/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.js
@@ -64,6 +64,34 @@ */ const mockFileTransferController = /** @type {!FileTransferController} */ ({}); +/** + * Mock directory change tracker. + * @type {!Object} + */ +const fakeTracker = { + hasChange: false, +}; + +/** + * Fake url for mounted ZIP file. + * @type {string} + */ +const fakeMountedZipUrl = + 'filesystem:chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/' + + 'external/fakePath/test.zip'; + +/** + * Panel IDs for ZIP mount operations. + * @type {string} + */ +const zipMountPanelId = 'Mounting: ' + fakeMountedZipUrl; + +/** + * Panel IDs for ZIP mount errors. + * @type {string} + */ +const errorZipMountPanelId = 'Cannot mount: ' + fakeMountedZipUrl; + // Set up test components. function setUp() { // Mock LoadTimeData strings. @@ -156,6 +184,7 @@ alertDialog: { showHtml: function(title, text, onOk, onCancel, onShow) {}, }, + passwordDialog: /** @type {!FilesPasswordDialog} */ ({}), speakA11yMessage: (text) => {}, }), metadataModel: /** @type {!MetadataModel} */ ({}), @@ -164,9 +193,10 @@ getCurrentRootType: function() { return null; }, + changeDirectoryEntry: function(displayRoot) {} }), crostini: crostini, - progressCenter: /** @type {!ProgressCenter} */ ({}), + progressCenter: /** @type {!ProgressCenter} */ (new MockProgressCenter()), }; fileManager.crostini.initVolumeManager(fileManager.volumeManager); @@ -759,3 +789,161 @@ done(); } + +/** + * Checks that the progress center is properly updated when mounting archives + * successfully. + * @suppress {visibility} + */ +async function testMountArchiveAndChangeDirectoryNotificationSuccess(done) { + const fileManager = getMockFileManager(); + + // Define FileTasks instance. + const tasks = await FileTasks.create( + fileManager.volumeManager, fileManager.metadataModel, + fileManager.directoryModel, fileManager.ui, mockFileTransferController, + [], [null], mockTaskHistory, fileManager.namingController, + fileManager.crostini, fileManager.progressCenter); + + fileManager.volumeManager.mountArchive = function(url, password) { + // Check: progressing state. + assertEquals( + ProgressItemState.PROGRESSING, + fileManager.progressCenter.getItemById(zipMountPanelId).state); + + const volumeInfo = {resolveDisplayRoot: () => null}; + return volumeInfo; + }; + + // Mount archive. + await tasks.mountArchiveAndChangeDirectory_(fakeTracker, fakeMountedZipUrl); + + // Check: mount completed, no error. + assertEquals( + ProgressItemState.COMPLETED, + fileManager.progressCenter.getItemById(zipMountPanelId).state); + assertEquals( + undefined, fileManager.progressCenter.getItemById(errorZipMountPanelId)); + + done(); +} + +/** + * Checks that the progress center is properly updated when mounting an archive + * resolves with an error. + * @suppress {visibility} + */ +async function testMountArchiveAndChangeDirectoryNotificationInvalidArchive( + done) { + const fileManager = getMockFileManager(); + + // Define FileTasks instance. + const tasks = await FileTasks.create( + fileManager.volumeManager, fileManager.metadataModel, + fileManager.directoryModel, fileManager.ui, mockFileTransferController, + [], [null], mockTaskHistory, fileManager.namingController, + fileManager.crostini, fileManager.progressCenter); + + fileManager.volumeManager.mountArchive = function(url, password) { + return Promise.reject(VolumeManagerCommon.VolumeError.INTERNAL); + }; + + // Mount archive. + await tasks.mountArchiveAndChangeDirectory_(fakeTracker, fakeMountedZipUrl); + + // Check: mount is completed with an error. + assertEquals( + ProgressItemState.COMPLETED, + fileManager.progressCenter.getItemById(zipMountPanelId).state); + assertEquals( + ProgressItemState.ERROR, + fileManager.progressCenter.getItemById(errorZipMountPanelId).state); + + done(); +} + +/** + * Checks that the progress center is properly updated when the password prompt + * for an encrypted archive is canceled. + * @suppress {visibility} + */ +async function testMountArchiveAndChangeDirectoryNotificationCancelPassword( + done) { + const fileManager = getMockFileManager(); + + // Define FileTasks instance. + const tasks = await FileTasks.create( + fileManager.volumeManager, fileManager.metadataModel, + fileManager.directoryModel, fileManager.ui, mockFileTransferController, + [], [null], mockTaskHistory, fileManager.namingController, + fileManager.crostini, fileManager.progressCenter); + + fileManager.volumeManager.mountArchive = function(url, password) { + return Promise.reject(VolumeManagerCommon.VolumeError.NEED_PASSWORD); + }; + + fileManager.ui.passwordDialog.askForPassword = + async function(filename, password = null) { + return Promise.reject(FilesPasswordDialog.USER_CANCELLED); + }; + + // Mount archive. + await tasks.mountArchiveAndChangeDirectory_(fakeTracker, fakeMountedZipUrl); + + // Check: mount is completed, no error since the user canceled the password + // prompt. + assertEquals( + ProgressItemState.COMPLETED, + fileManager.progressCenter.getItemById(zipMountPanelId).state); + assertEquals( + undefined, fileManager.progressCenter.getItemById(errorZipMountPanelId)); + + done(); +} + +/** + * Checks that the progress center is properly updated when mounting an + * encrypted archive. + * @suppress {visibility} + */ +async function testMountArchiveAndChangeDirectoryNotificationEncryptedArchive( + done) { + const fileManager = getMockFileManager(); + + // Define FileTasks instance. + const tasks = await FileTasks.create( + fileManager.volumeManager, fileManager.metadataModel, + fileManager.directoryModel, fileManager.ui, mockFileTransferController, + [], [null], mockTaskHistory, fileManager.namingController, + fileManager.crostini, fileManager.progressCenter); + + fileManager.volumeManager.mountArchive = function(url, password) { + return new Promise((resolve, reject) => { + if (password) { + assertEquals('testpassword', password); + const volumeInfo = {resolveDisplayRoot: () => null}; + resolve(volumeInfo); + } else { + reject(VolumeManagerCommon.VolumeError.NEED_PASSWORD); + } + }); + }; + + fileManager.ui.passwordDialog.askForPassword = + async function(filename, password = null) { + return Promise.resolve('testpassword'); + }; + + // Mount archive. + await tasks.mountArchiveAndChangeDirectory_(fakeTracker, fakeMountedZipUrl); + + // Check: mount is completed, no error since the user entered a valid + // password. + assertEquals( + ProgressItemState.COMPLETED, + fileManager.progressCenter.getItemById(zipMountPanelId).state); + assertEquals( + undefined, fileManager.progressCenter.getItemById(errorZipMountPanelId)); + + done(); +}
diff --git a/ui/file_manager/file_manager/foreground/js/naming_controller.js b/ui/file_manager/file_manager/foreground/js/naming_controller.js index fe930e5..79d6c68b 100644 --- a/ui/file_manager/file_manager/foreground/js/naming_controller.js +++ b/ui/file_manager/file_manager/foreground/js/naming_controller.js
@@ -262,14 +262,13 @@ const entry = input.currentEntry; const newName = input.value; - if (!newName || newName == entry.name) { - this.cancelRename_(); - return; - } - const renamedItemElement = this.listContainer_.findListItemForNode( this.listContainer_.renameInput); const nameNode = renamedItemElement.querySelector('.filename-label'); + if (!newName || newName == nameNode.textContent) { + this.cancelRename_(); + return; + } input.validation_ = true; const validationDone = valid => {
diff --git a/ui/file_manager/file_manager_resources.grd b/ui/file_manager/file_manager_resources.grd index 09c49296..749b388 100644 --- a/ui/file_manager/file_manager_resources.grd +++ b/ui/file_manager/file_manager_resources.grd
@@ -115,6 +115,7 @@ <include name="IDR_VIDEO_PLAYER" file="video_player/video_player.html" allowexternalscript="true" flattenhtml="true" type="BINDATA" /> <include name="IDR_VIDEO_PLAYER_JS" file="video_player/js/video_player_scripts.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_VIDEO_PLAYER_BACKGROUND_JS" file="video_player/js/background_scripts.js" flattenhtml="true" type="BINDATA" /> + <include name="IDR_VIDEO_PLAYER_BACKGROUND_HTML" file="video_player/background.html" type="BINDATA" /> <include name="IDR_VIDEO_PLAYER_ICON_FAVICON_16" file="video_player/images/icon/video-player-favicon-16.png" type="BINDATA" /> <include name="IDR_VIDEO_PLAYER_ICON_16" file="video_player/images/icon/video-player-16.png" type="BINDATA" /> <include name="IDR_VIDEO_PLAYER_ICON_32" file="video_player/images/icon/video-player-32.png" type="BINDATA" />
diff --git a/ui/file_manager/video_player/background.html b/ui/file_manager/video_player/background.html new file mode 100644 index 0000000..61ebf8ff --- /dev/null +++ b/ui/file_manager/video_player/background.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<meta charset="utf-8"> + +<script src="chrome://resources/js/cr.js"></script> +<script src="chrome://resources/js/cr/event_target.js"></script> +<script src="chrome://resources/js/cr/ui/array_data_model.js"></script> +<script src="chrome://resources/js/load_time_data.js"></script> +<script src="chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/background/js/background_common_scripts.js"></script> +<script src="js/background_scripts.js"></script>
diff --git a/ui/file_manager/video_player/manifest.json b/ui/file_manager/video_player/manifest.json index 945296a..c5c1781 100644 --- a/ui/file_manager/video_player/manifest.json +++ b/ui/file_manager/video_player/manifest.json
@@ -58,14 +58,7 @@ }, "app": { "background": { - "scripts": [ - "chrome://resources/js/cr.js", - "chrome://resources/js/cr/event_target.js", - "chrome://resources/js/cr/ui/array_data_model.js", - "chrome://resources/js/load_time_data.js", - "chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/background/js/background_common_scripts.js", - "js/background_scripts.js" - ] + "page": "background.html" }, // enhhojjnijigcajfphajepfemndkmdlo is the Dev Media Router component extension ID. // pkedcjkdefgpdelpbcmbmeomcjbeemfm is the Stable Media Router component extension ID.
diff --git a/ui/views/.clang-tidy b/ui/views/.clang-tidy index 1c0e0dc..b6c0d7f 100644 --- a/ui/views/.clang-tidy +++ b/ui/views/.clang-tidy
@@ -1,29 +1,7 @@ --- -Checks: '-*, - google-build-namespaces, - google-explicit-constructor, - google-readability-casting, - google-readability-namespace-comments, - modernize-avoid-bind, - modernize-loop-convert, - modernize-make-shared, - modernize-make-unique, - modernize-redundant-void-arg, - modernize-replace-auto-ptr, - modernize-replace-random-shuffle, - modernize-shrink-to-fit, - modernize-use-bool-literals, - modernize-use-default-member-init, - modernize-use-emplace, - modernize-use-equals-default, - modernize-use-noexcept, - modernize-use-nullptr, - modernize-use-override, - modernize-use-transparent-functors, - modernize-use-using, - readability-redundant-member-init' -HeaderFilterRegex: 'ui/views/*' -CheckOptions: - - key: modernize-use-default-member-init.UseAssignment - value: 1 + Checks: 'google-build-namespaces, + google-readability-namespace-comments, + modernize-replace-auto-ptr, + modernize-use-using' + HeaderFilterRegex: 'ui/views/*' ...
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index f22c34d..04bf0870 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -1830,6 +1830,7 @@ const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) { // TODO(https://crbug.com/952355): Support custom text spans. DCHECK(!model_->HasCompositionText()); + OnBeforeUserAction(); model_->SetCompositionFromExistingText(range); SchedulePaint(); OnAfterUserAction();
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index eee49b41..42d1f0f7 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -2996,6 +2996,21 @@ EXPECT_EQ(composed_text_length, static_cast<uint32_t>(0)); } +#if defined(OS_WIN) || defined(OS_CHROMEOS) +// SetCompositionFromExistingText is only available on Windows and Chrome OS. +TEST_F(TextfieldTest, SetCompositionFromExistingTextTest) { + InitTextfield(); + textfield_->SetText(ASCIIToUTF16("abc")); + + textfield_->SetCompositionFromExistingText(gfx::Range(1, 3), {}); + + gfx::Range actual_range; + EXPECT_TRUE(textfield_->HasCompositionText()); + EXPECT_TRUE(textfield_->GetCompositionTextRange(&actual_range)); + EXPECT_EQ(actual_range, gfx::Range(1, 3)); +} +#endif + TEST_F(TextfieldTest, GetCompositionCharacterBoundsTest) { InitTextfield(); ui::CompositionText composition;