diff --git a/BUILD.gn b/BUILD.gn index dca156f..b10d20c5 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -1370,7 +1370,6 @@ "//third_party/blink/web_tests/overflow/", "//third_party/blink/web_tests/paint/", "//third_party/blink/web_tests/payments/", - "//third_party/blink/web_tests/pending_beacon/", "//third_party/blink/web_tests/permissionclient/", "//third_party/blink/web_tests/plugins/", "//third_party/blink/web_tests/pointer-lock/",
diff --git a/DEPS b/DEPS index f9fcd260d..ef9f1b4 100644 --- a/DEPS +++ b/DEPS
@@ -297,15 +297,15 @@ # 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': '3901abed003450c20001e6b7538408e484ed7aa9', + 'skia_revision': 'bdeedf187ec21b71b4f8054d78765596f8780e80', # 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': '67b99da37770bf0286bf77349e1435d73ae6ae6e', + 'v8_revision': '862f5a27e9f71f1e36da33d0b0f7e017b90893b6', # 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': '58392791220067b2114a8c643f39a48420404d98', + 'angle_revision': 'afdd51060e51bf571cad6c754fa9ddf2c1dd2cec', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -368,7 +368,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': 'b2cd6477b94b91a0b94b3430a50ba3bce650c5b6', + 'catapult_revision': '6dbdca4bea6d53025e454524571f685731486cf5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -376,7 +376,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': '2b720e0e927ef45c6866215d9edd8e7f3a0fe3b1', + 'devtools_frontend_revision': '1243a8033c2875e590d08f9b08feb86d9f9fc00f', # 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. @@ -412,7 +412,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '4acf608cf2268dc894480bc8d125098e944e553c', + 'dawn_revision': '2c36bc628cd1faef671c73bdf2f0853b9f11ca3a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -480,7 +480,7 @@ # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. - 'libcxx_revision': '55e0c49d148aecc33568a1a61b916323004a2d18', + 'libcxx_revision': '9f503bebdb9a89f5ee82b82142109b26d688f40c', # GN CIPD package version. 'gn_version': 'git_revision:0bcd37bd2b83f1a9ee17088037ebdfe6eab6d31a', @@ -1613,7 +1613,7 @@ 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'YywdNQUrAK_HHH829t_MPLvTyjmQW-dWAsB7k-8gpNkC', + 'version': 'DZRgtLW0NflugdN9UMc7OsJqux69vI-6BxCNcTJaRTwC', }, ], 'condition': 'checkout_android', @@ -1693,7 +1693,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@24f4cdea6d0de6c92975421af3865acdafff3641', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@03dd80c1d5794532420768c320fc026f3454cb5a', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907', @@ -1805,7 +1805,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@2e7678c247fbf1f43fb044d7b980a111810c2ccb', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@abfeca3118772f956af3636e38754318876282bf', 'condition': 'checkout_src_internal', },
diff --git a/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.cc b/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.cc index 9d56205e..18f9343 100644 --- a/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.cc +++ b/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
@@ -208,7 +208,7 @@ void ArcVolumeMounterBridge::OnMountEvent( DiskMountManager::MountEvent event, ash::MountError error_code, - const DiskMountManager::MountPointInfo& mount_info) { + const DiskMountManager::MountPoint& mount_info) { DCHECK(delegate_); // Skip mount events for volumes that are not shared with ARC (e.g., those
diff --git a/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.h b/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.h index c919cd3..5619ed50 100644 --- a/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.h +++ b/ash/components/arc/volume_mounter/arc_volume_mounter_bridge.h
@@ -76,7 +76,7 @@ void OnMountEvent( ash::disks::DiskMountManager::MountEvent event, ash::MountError error_code, - const ash::disks::DiskMountManager::MountPointInfo& mount_info) override; + const ash::disks::DiskMountManager::MountPoint& mount_info) override; // ConnectionObserver<mojom::VolumeMounterInstance> overrides: void OnConnectionClosed() override;
diff --git a/ash/components/disks/disk_mount_manager.cc b/ash/components/disks/disk_mount_manager.cc index 8bcb064..a0212fb 100644 --- a/ash/components/disks/disk_mount_manager.cc +++ b/ash/components/disks/disk_mount_manager.cc
@@ -95,9 +95,8 @@ if (const auto [_, ok] = mount_callbacks_.try_emplace(source_path, std::move(callback)); !ok) { - std::move(callback).Run( - MountError::kPathAlreadyMounted, - MountPointInfo(source_path, "", type, MOUNT_CONDITION_NONE)); + std::move(callback).Run(MountError::kPathAlreadyMounted, + {source_path, "", type}); return; } @@ -332,7 +331,7 @@ // DiskMountManager override. // Corresponding disk should be added to the manager before this is called. - bool AddMountPointForTest(const MountPointInfo& mount_point) override { + bool AddMountPointForTest(const MountPoint& mount_point) override { if (mount_points_.find(mount_point.mount_path) != mount_points_.end()) { LOG(ERROR) << "Attempt to add a duplicate mount point"; return false; @@ -470,8 +469,8 @@ } } - const MountPointInfo mount_info(entry.source_path, entry.mount_path, - entry.mount_type, mount_condition); + const MountPoint mount_info{entry.source_path, entry.mount_path, + entry.mount_type, mount_condition}; // If the device is corrupted but it's still possible to format it, it will // be fake mounted. @@ -542,7 +541,7 @@ if (const MountPointMap::const_iterator mp_it = mount_points_.find(mount_path); mp_it != mount_points_.end()) { - const MountPointInfo& mp = mp_it->second; + const MountPoint& mp = mp_it->second; NotifyMountStatusUpdate(UNMOUNTING, error, mp); if (error == MountError::kNone) { @@ -984,7 +983,7 @@ // Notifies all observers about mount completion. void NotifyMountStatusUpdate(MountEvent event, MountError error_code, - const MountPointInfo& mount_info) { + const MountPoint& mount_info) { for (auto& observer : observers_) observer.OnMountEvent(event, error_code, mount_info); } @@ -1068,7 +1067,7 @@ return false; } -bool DiskMountManager::AddMountPointForTest(const MountPointInfo& mount_point) { +bool DiskMountManager::AddMountPointForTest(const MountPoint& mount_point) { return false; } @@ -1081,9 +1080,8 @@ return "unknown_filesystem"; case MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM: return "unsupported_filesystem"; - default: - NOTREACHED(); } + NOTREACHED(); return ""; }
diff --git a/ash/components/disks/disk_mount_manager.h b/ash/components/disks/disk_mount_manager.h index 678eae91..497a94f 100644 --- a/ash/components/disks/disk_mount_manager.h +++ b/ash/components/disks/disk_mount_manager.h
@@ -99,7 +99,7 @@ using MountPointInfo = MountPoint; // MountPointMap key is mount_path. - typedef std::map<std::string, MountPointInfo> MountPointMap; + typedef std::map<std::string, MountPoint> MountPointMap; // A callback function type which is called after UnmountDeviceRecursively // finishes. @@ -107,7 +107,7 @@ UnmountDeviceRecursivelyCallbackType; typedef base::OnceCallback<void(MountError error_code, - const MountPointInfo& mount_info)> + const MountPoint& mount_info)> MountPathCallback; // A callback type for UnmountPath method. @@ -130,7 +130,7 @@ // Called after a mount point has been mounted or unmounted. virtual void OnMountEvent(MountEvent event, MountError error_code, - const MountPointInfo& mount_info) {} + const MountPoint& mount_info) {} // Called on format process events. virtual void OnFormatEvent(FormatEvent event, FormatError error_code, @@ -238,7 +238,7 @@ // Used in tests to initialize the manager's disk and mount point sets. // Default implementation does noting. It just fails. virtual bool AddDiskForTest(std::unique_ptr<Disk> disk); - virtual bool AddMountPointForTest(const MountPointInfo& mount_point); + virtual bool AddMountPointForTest(const MountPoint& mount_point); // Returns corresponding string to |type| like "unknown_filesystem". static std::string MountConditionToString(MountCondition type);
diff --git a/ash/components/disks/disk_mount_manager_unittest.cc b/ash/components/disks/disk_mount_manager_unittest.cc index 6c0cad8..7bc5f422 100644 --- a/ash/components/disks/disk_mount_manager_unittest.cc +++ b/ash/components/disks/disk_mount_manager_unittest.cc
@@ -70,14 +70,6 @@ bool is_mounted; }; -// Holds information to create a DiskMOuntManager::MountPointInfo instance. -struct TestMountPointInfo { - const char* source_path; - const char* mount_path; - MountType mount_type; - MountCondition mount_condition; -}; - // List of disks held in DiskMountManager at the beginning of the test. const TestDiskInfo kTestDisks[] = { { @@ -136,28 +128,6 @@ }, }; -// List of mount points held in DiskMountManager at the beginning of the test. -const TestMountPointInfo kTestMountPoints[] = { - { - "/archive/source_path", - "/archive/mount_path", - MountType::kArchive, - MOUNT_CONDITION_NONE - }, - { - kDevice1SourcePath, - kDevice1MountPath, - MountType::kDevice, - MOUNT_CONDITION_NONE - }, - { - kReadOnlyDeviceSourcePath, - kReadOnlyDeviceMountPath, - MountType::kDevice, - MOUNT_CONDITION_NONE - }, -}; - // Represents which function in |DiskMountManager::Observer| was invoked. enum ObserverEventType { DEVICE_EVENT, // OnDeviceEvent() @@ -313,7 +283,7 @@ struct MountEvent : public ObserverEvent { DiskMountManager::MountEvent event; MountError error_code; - DiskMountManager::MountPointInfo mount_point; + DiskMountManager::MountPoint mount_point; // Not passed to callback, but read by handlers. So it's captured upon // callback. @@ -326,7 +296,7 @@ disk(std::move(other.disk)) {} MountEvent(DiskMountManager::MountEvent event, MountError error_code, - const DiskMountManager::MountPointInfo& mount_point, + const DiskMountManager::MountPoint& mount_point, const Disk& disk) : event(event), error_code(error_code), @@ -389,10 +359,9 @@ device_path, device_label)); } - void OnMountEvent( - DiskMountManager::MountEvent event, - MountError error_code, - const DiskMountManager::MountPointInfo& mount_point) override { + void OnMountEvent(DiskMountManager::MountEvent event, + MountError error_code, + const DiskMountManager::MountPoint& mount_point) override { // Take a snapshot (copy) of a Disk object at the time of invocation. // It can be verified later besides the arguments. events_.push_back(std::make_unique<MountEvent>( @@ -587,12 +556,9 @@ // Adds a new mount point to the disk mount manager. // If the mount point is a device mount point, disk with its source path // should already be added to the disk mount manager. - void AddTestMountPoint(const TestMountPointInfo& mount_point) { - EXPECT_TRUE(DiskMountManager::GetInstance()->AddMountPointForTest( - DiskMountManager::MountPointInfo(mount_point.source_path, - mount_point.mount_path, - mount_point.mount_type, - mount_point.mount_condition))); + void AddTestMountPoint(const DiskMountManager::MountPoint& mount_point) { + EXPECT_TRUE( + DiskMountManager::GetInstance()->AddMountPointForTest(mount_point)); } // Adds disks and mount points to disk mount manager. @@ -602,8 +568,12 @@ for (size_t i = 0; i < std::size(kTestDisks); i++) AddTestDisk(kTestDisks[i]); - for (size_t i = 0; i < std::size(kTestMountPoints); i++) - AddTestMountPoint(kTestMountPoints[i]); + AddTestMountPoint( + {"/archive/source_path", "/archive/mount_path", MountType::kArchive}); + AddTestMountPoint( + {kDevice1SourcePath, kDevice1MountPath, MountType::kDevice}); + AddTestMountPoint({kReadOnlyDeviceSourcePath, kReadOnlyDeviceMountPath, + MountType::kDevice}); } protected: @@ -999,15 +969,15 @@ EXPECT_CALL( mock_callback1, Run(MountError::kNone, - Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath1))); + Field(&DiskMountManager::MountPoint::mount_path, kMountPath1))); base::MockCallback<DiskMountManager::MountPathCallback> mock_callback2; EXPECT_CALL( mock_callback2, Run(MountError::kNone, - Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath2))) + Field(&DiskMountManager::MountPoint::mount_path, kMountPath2))) .WillOnce([&](MountError, - const DiskMountManager::MountPointInfo& mount_point) { + const DiskMountManager::MountPoint& mount_point) { // Verify the disk appears read-only when the callback is invoked. See // below comment about the 2nd source. EXPECT_TRUE(manager->disks() @@ -1058,10 +1028,10 @@ const std::string kMountLabel = std::string(); // N/A for MountType::kDevice base::MockCallback<DiskMountManager::MountPathCallback> mock_callback; - EXPECT_CALL(mock_callback, - Run(MountError::kNone, - Field(&DiskMountManager::MountPointInfo::mount_path, - kReadOnlyDeviceMountPath))); + EXPECT_CALL( + mock_callback, + Run(MountError::kNone, Field(&DiskMountManager::MountPoint::mount_path, + kReadOnlyDeviceMountPath))); // Attempt to mount a read-only device in read-write mode. manager->MountPath(kReadOnlyDeviceSourcePath, kSourceFormat, std::string(), @@ -1108,7 +1078,7 @@ EXPECT_CALL( mock_callback1, Run(MountError::kNone, - Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath1))); + Field(&DiskMountManager::MountPoint::mount_path, kMountPath1))); fake_cros_disks_client_->NotifyMountCompleted( MountError::kNone, kDevice1SourcePath, MountType::kDevice, kMountPath1); } @@ -1124,9 +1094,9 @@ EXPECT_CALL( mock_callback1, Run(MountError::kNone, - Field(&DiskMountManager::MountPointInfo::mount_path, kMountPath1))) + Field(&DiskMountManager::MountPoint::mount_path, kMountPath1))) .WillOnce([=](MountError error, - const DiskMountManager::MountPointInfo& mount_info) { + const DiskMountManager::MountPoint& mount_info) { // Try remount the same path and verify it fails. base::MockCallback<DiskMountManager::MountPathCallback> mock_callback2; EXPECT_CALL(mock_callback2, Run(MountError::kPathAlreadyMounted, _)); @@ -1136,10 +1106,10 @@ // Try mount a different path and verify it succeeds. base::MockCallback<DiskMountManager::MountPathCallback> mock_callback3; - EXPECT_CALL(mock_callback3, - Run(MountError::kNone, - Field(&DiskMountManager::MountPointInfo::mount_path, - kMountPath2))); + EXPECT_CALL( + mock_callback3, + Run(MountError::kNone, + Field(&DiskMountManager::MountPoint::mount_path, kMountPath2))); manager->MountPath(kDevice2SourcePath, "", "", {}, MountType::kDevice, chromeos::MOUNT_ACCESS_MODE_READ_WRITE, mock_callback3.Get());
diff --git a/ash/components/disks/mock_disk_mount_manager.cc b/ash/components/disks/mock_disk_mount_manager.cc index a110727..05fcd76 100644 --- a/ash/components/disks/mock_disk_mount_manager.cc +++ b/ash/components/disks/mock_disk_mount_manager.cc
@@ -124,7 +124,7 @@ void MockDiskMountManager::NotifyMountEvent(MountEvent event, MountError error_code, - const MountPointInfo& mount_info) { + const MountPoint& mount_info) { for (auto& observer : observers_) observer.OnMountEvent(event, error_code, mount_info); } @@ -152,7 +152,7 @@ } void MockDiskMountManager::CreateDiskEntryForMountDevice( - const DiskMountManager::MountPointInfo& mount_info, + const DiskMountManager::MountPoint& mount_info, const std::string& device_id, const std::string& device_label, const std::string& vendor_name, @@ -185,7 +185,7 @@ } void MockDiskMountManager::RemoveDiskEntryForMountDevice( - const DiskMountManager::MountPointInfo& mount_info) { + const DiskMountManager::MountPoint& mount_info) { disks_.erase(mount_info.source_path); }
diff --git a/ash/components/disks/mock_disk_mount_manager.h b/ash/components/disks/mock_disk_mount_manager.h index 040b96b..d5f538f 100644 --- a/ash/components/disks/mock_disk_mount_manager.h +++ b/ash/components/disks/mock_disk_mount_manager.h
@@ -87,7 +87,7 @@ // Invokes specified mount event. void NotifyMountEvent(MountEvent event, MountError error_code, - const MountPointInfo& mount_info); + const MountPoint& mount_info); // Sets up default results for mock methods. void SetupDefaultReplies(); @@ -97,7 +97,7 @@ // Creates a fake disk entry for the mounted device. void CreateDiskEntryForMountDevice( - const DiskMountManager::MountPointInfo& mount_info, + const DiskMountManager::MountPoint& mount_info, const std::string& device_id, const std::string& device_label, const std::string& vendor_name, @@ -113,7 +113,7 @@ // Removes the fake disk entry associated with the mounted device. This // function is primarily for StorageMonitorTest. void RemoveDiskEntryForMountDevice( - const DiskMountManager::MountPointInfo& mount_info); + const DiskMountManager::MountPoint& mount_info); private: // Is used to implement AddObserver.
diff --git a/ash/components/disks/mount_point.cc b/ash/components/disks/mount_point.cc index 6163433..8f9b3ae9 100644 --- a/ash/components/disks/mount_point.cc +++ b/ash/components/disks/mount_point.cc
@@ -18,7 +18,7 @@ void OnMountDone(DiskMountManager* disk_mount_manager, MountPoint::DoneCallback callback, MountError error_code, - const DiskMountManager::MountPointInfo& mount_info) { + const DiskMountManager::MountPoint& mount_info) { std::unique_ptr<MountPoint> mount_point; if (error_code == MountError::kNone) { DCHECK(!mount_info.mount_path.empty());
diff --git a/ash/components/disks/mount_point_unittest.cc b/ash/components/disks/mount_point_unittest.cc index 20eb9198..77ea1d6 100644 --- a/ash/components/disks/mount_point_unittest.cc +++ b/ash/components/disks/mount_point_unittest.cc
@@ -38,9 +38,8 @@ MountPath(kSourcePath, "", "", _, MountType::kDevice, MOUNT_ACCESS_MODE_READ_WRITE, _)) .WillOnce(RunOnceCallback<6>( - MountError::kNone, DiskMountManager::MountPointInfo( - kSourcePath, kMountPath, MountType::kDevice, - MOUNT_CONDITION_NONE))); + MountError::kNone, DiskMountManager::MountPoint{ + kSourcePath, kMountPath, MountType::kDevice})); EXPECT_CALL(disk_mount_manager_, UnmountPath(kMountPath, _)).Times(1); base::RunLoop run_loop; @@ -61,9 +60,9 @@ MountPath(kSourcePath, "", "", _, MountType::kDevice, MOUNT_ACCESS_MODE_READ_WRITE, _)) .WillOnce(RunOnceCallback<6>( - MountError::kUnknown, DiskMountManager::MountPointInfo( + MountError::kUnknown, DiskMountManager::MountPoint{ kSourcePath, kMountPath, MountType::kDevice, - MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM))); + MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM})); EXPECT_CALL(disk_mount_manager_, UnmountPath(_, _)).Times(0); base::RunLoop run_loop;
diff --git a/ash/components/disks/suspend_unmount_manager_unittest.cc b/ash/components/disks/suspend_unmount_manager_unittest.cc index 07e4d6911..3ccb372 100644 --- a/ash/components/disks/suspend_unmount_manager_unittest.cc +++ b/ash/components/disks/suspend_unmount_manager_unittest.cc
@@ -73,23 +73,17 @@ const std::string kDummyMountPathSd = "/dummy/mount/sd"; const std::string kDummyMountPathUnknown = "/dummy/mount/unknown"; disk_mount_manager_.CreateDiskEntryForMountDevice( - DiskMountManager::MountPointInfo("/dummy/device/usb", kDummyMountPathUsb, - MountType::kDevice, - MOUNT_CONDITION_NONE), - kDeviceId, kDeviceLabel, kVendor, kProduct, DeviceType::kUSB, 1024 * 1024, + {"/dummy/device/usb", kDummyMountPathUsb, MountType::kDevice}, kDeviceId, + kDeviceLabel, kVendor, kProduct, DeviceType::kUSB, 1024 * 1024, false /* is_parent */, false /* has_media */, false /* on_boot_device */, true /* on_removable_device */, kFileSystemType); disk_mount_manager_.CreateDiskEntryForMountDevice( - DiskMountManager::MountPointInfo("/dummy/device/sd", kDummyMountPathSd, - MountType::kDevice, - MOUNT_CONDITION_NONE), - kDeviceId, kDeviceLabel, kVendor, kProduct, DeviceType::kSD, 1024 * 1024, + {"/dummy/device/sd", kDummyMountPathSd, MountType::kDevice}, kDeviceId, + kDeviceLabel, kVendor, kProduct, DeviceType::kSD, 1024 * 1024, false /* is_parent */, false /* has_media */, false /* on_boot_device */, true /* on_removable_device */, kFileSystemType); disk_mount_manager_.CreateDiskEntryForMountDevice( - DiskMountManager::MountPointInfo( - "/dummy/device/unknown", kDummyMountPathUnknown, MountType::kDevice, - MOUNT_CONDITION_NONE), + {"/dummy/device/unknown", kDummyMountPathUnknown, MountType::kDevice}, kDeviceId, kDeviceLabel, kVendor, kProduct, DeviceType::kUnknown, 1024 * 1024, false /* is_parent */, false /* has_media */, false /* on_boot_device */, true /* on_removable_device */, @@ -120,10 +114,8 @@ TEST_F(SuspendUnmountManagerTest, CancelAndSuspendAgain) { const std::string kDummyMountPath = "/dummy/mount"; disk_mount_manager_.CreateDiskEntryForMountDevice( - DiskMountManager::MountPointInfo("/dummy/device", kDummyMountPath, - MountType::kDevice, - MOUNT_CONDITION_NONE), - kDeviceId, kDeviceLabel, kVendor, kProduct, DeviceType::kUSB, 1024 * 1024, + {"/dummy/device", kDummyMountPath, MountType::kDevice}, kDeviceId, + kDeviceLabel, kVendor, kProduct, DeviceType::kUSB, 1024 * 1024, false /* is_parent */, false /* has_media */, false /* on_boot_device */, true /* on_removable_device */, kFileSystemType); disk_mount_manager_.SetupDefaultReplies();
diff --git a/ash/components/smbfs/smbfs_mounter_unittest.cc b/ash/components/smbfs/smbfs_mounter_unittest.cc index 9db566a..d499519 100644 --- a/ash/components/smbfs/smbfs_mounter_unittest.cc +++ b/ash/components/smbfs/smbfs_mounter_unittest.cc
@@ -49,12 +49,10 @@ constexpr char kKerberosIdentity[] = "my-kerberos-identity"; constexpr char kAccountHash[] = "00112233445566778899aabb"; -ash::disks::DiskMountManager::MountPointInfo MakeMountPointInfo( +ash::disks::DiskMountManager::MountPoint MakeMountPointInfo( const std::string& source_path, const std::string& mount_path) { - return ash::disks::DiskMountManager::MountPointInfo( - source_path, mount_path, ash::MountType::kNetworkStorage, - ash::disks::MOUNT_CONDITION_NONE); + return {source_path, mount_path, ash::MountType::kNetworkStorage}; } class MockDelegate : public SmbFsHost::Delegate {
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 5e5bf87..7f520d50 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -925,6 +925,9 @@ // Enables Jelly features. const base::Feature kJelly{"Jelly", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables Jellyroll features. +const base::Feature kJellyroll{"Jellyroll", base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables IME button in the floating accessibility menu for the Kiosk session. const base::Feature kKioskEnableImeButton{"KioskEnableImeButton", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -2035,6 +2038,10 @@ return base::FeatureList::IsEnabled(kJelly); } +bool IsJellyrollEnabled() { + return base::FeatureList::IsEnabled(kJellyroll); +} + bool IsKeyboardBacklightToggleEnabled() { return base::FeatureList::IsEnabled(kEnableKeyboardBacklightToggle); }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index ff3651a3..d9573b4 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -383,6 +383,7 @@ extern const base::Feature kImprovedLoginErrorHandling; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kInstantTethering; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kJelly; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kJellyroll; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kKioskEnableImeButton; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kLacrosOnly; @@ -758,6 +759,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsInstantTetheringBackgroundAdvertisingSupported(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsJellyEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsJellyrollEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsKeyboardBacklightToggleEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsLanguagePacksEnabled();
diff --git a/ash/webui/os_feedback_ui/backend/feedback_service_provider.cc b/ash/webui/os_feedback_ui/backend/feedback_service_provider.cc index 3a10d81..a7df41a 100644 --- a/ash/webui/os_feedback_ui/backend/feedback_service_provider.cc +++ b/ash/webui/os_feedback_ui/backend/feedback_service_provider.cc
@@ -68,6 +68,10 @@ feedback_delegate_->OpenSystemInfoDialog(); } +void FeedbackServiceProvider::OpenBluetoothLogsInfoDialog() { + feedback_delegate_->OpenBluetoothLogsInfoDialog(); +} + void FeedbackServiceProvider::RecordPostSubmitAction( os_feedback_ui::mojom::FeedbackAppPostSubmitAction action) { os_feedback_ui::metrics::EmitFeedbackAppPostSubmitAction(action);
diff --git a/ash/webui/os_feedback_ui/backend/feedback_service_provider.h b/ash/webui/os_feedback_ui/backend/feedback_service_provider.h index 60353ebd..232f934 100644 --- a/ash/webui/os_feedback_ui/backend/feedback_service_provider.h +++ b/ash/webui/os_feedback_ui/backend/feedback_service_provider.h
@@ -37,6 +37,7 @@ void OpenExploreApp() override; void OpenMetricsDialog() override; void OpenSystemInfoDialog() override; + void OpenBluetoothLogsInfoDialog() override; void RecordPostSubmitAction( os_feedback_ui::mojom::FeedbackAppPostSubmitAction action) override; void RecordPreSubmitAction(
diff --git a/ash/webui/os_feedback_ui/backend/feedback_service_provider_unittest.cc b/ash/webui/os_feedback_ui/backend/feedback_service_provider_unittest.cc index 9ac69177..5b7427f 100644 --- a/ash/webui/os_feedback_ui/backend/feedback_service_provider_unittest.cc +++ b/ash/webui/os_feedback_ui/backend/feedback_service_provider_unittest.cc
@@ -72,6 +72,8 @@ void OpenMetricsDialog() override {} void OpenSystemInfoDialog() override {} + + void OpenBluetoothLogsInfoDialog() override {} }; class FeedbackServiceProviderTest : public testing::Test {
diff --git a/ash/webui/os_feedback_ui/backend/os_feedback_delegate.h b/ash/webui/os_feedback_ui/backend/os_feedback_delegate.h index 14ae718..3d24a7bf6 100644 --- a/ash/webui/os_feedback_ui/backend/os_feedback_delegate.h +++ b/ash/webui/os_feedback_ui/backend/os_feedback_delegate.h
@@ -48,6 +48,9 @@ // Open system info dialog (which displays the system logs // to be sent with the report if the user has opted in). virtual void OpenSystemInfoDialog() = 0; + // Open bluetooth logs info dialog (which displays the bluetooth logs + // to be sent with the report if the user has opted in). + virtual void OpenBluetoothLogsInfoDialog() = 0; }; } // namespace ash
diff --git a/ash/webui/os_feedback_ui/mojom/os_feedback_ui.mojom b/ash/webui/os_feedback_ui/mojom/os_feedback_ui.mojom index 9d8cc474..0a4e7c72 100644 --- a/ash/webui/os_feedback_ui/mojom/os_feedback_ui.mojom +++ b/ash/webui/os_feedback_ui/mojom/os_feedback_ui.mojom
@@ -180,6 +180,9 @@ // Open system info dialog (which displays the system logs // to be sent with the report if the user has opted in). OpenSystemInfoDialog(); + // Open bluetooth logs info dialog (which displays the bluetooth logs + // to be sent with the report if the user has opted in). + OpenBluetoothLogsInfoDialog(); // Record the metrics of users' first action on confirmation page. RecordPostSubmitAction(FeedbackAppPostSubmitAction action); // Record metrics of users' action before sending the feedback.
diff --git a/ash/webui/os_feedback_ui/os_feedback_ui.cc b/ash/webui/os_feedback_ui/os_feedback_ui.cc index a05c276..5b5f8fd 100644 --- a/ash/webui/os_feedback_ui/os_feedback_ui.cc +++ b/ash/webui/os_feedback_ui/os_feedback_ui.cc
@@ -97,6 +97,7 @@ {"buttonNewReport", IDS_FEEDBACK_TOOL_SEND_NEW_REPORT_BUTTON_LABEL}, {"buttonDone", IDS_FEEDBACK_TOOL_DONE_BUTTON_LABEL}, {"fileTooBigErrorMessage", IDS_FEEDBACK_TOOL_FILE_TOO_BIG_ERROR_MESSAGE}, + {"bluetoothLogsInfo", IDS_FEEDBACK_TOOL_BLUETOOTH_LOGS_CHECKBOX}, }; source->AddLocalizedStrings(kLocalizedStrings);
diff --git a/ash/webui/os_feedback_ui/resources/fake_feedback_service_provider.js b/ash/webui/os_feedback_ui/resources/fake_feedback_service_provider.js index 967f88fa..82d78ab 100644 --- a/ash/webui/os_feedback_ui/resources/fake_feedback_service_provider.js +++ b/ash/webui/os_feedback_ui/resources/fake_feedback_service_provider.js
@@ -44,6 +44,8 @@ openMetricsDialog: 0, /** @type {number} */ openSystemInfoDialog: 0, + /** @type {number} */ + openBluetoothLogsInfoDialog: 0, }; /** @type {?FeedbackAppPostSubmitAction} */ @@ -187,6 +189,17 @@ } /** + * @return {number} + */ + getOpenBluetoothLogsInfoDialogCallCount() { + return this.callCounts_.openBluetoothLogsInfoDialog; + } + + openBluetoothLogsInfoDialog() { + this.callCounts_.openBluetoothLogsInfoDialog++; + } + + /** * @param {!FeedbackAppPostSubmitAction} action * @return {boolean} */
diff --git a/ash/webui/os_feedback_ui/resources/share_data_page.html b/ash/webui/os_feedback_ui/resources/share_data_page.html index 9564624..0b056899 100644 --- a/ash/webui/os_feedback_ui/resources/share_data_page.html +++ b/ash/webui/os_feedback_ui/resources/share_data_page.html
@@ -50,11 +50,6 @@ width: 50%; } - #screenshotCheckLabel { - flex: 1; - margin-inline-end: 12px; - } - #screenshotContainer > button { cursor: pointer; } @@ -95,7 +90,12 @@ } #shareDiagnosticData { - height: 96px; + margin-bottom: 16px; + } + + .checkbox-field-container { + display: flex; + margin-bottom: 8px; } #pageUrl { @@ -119,7 +119,10 @@ } #screenshotCheckLabel { + flex: 1; font-weight: 400; + line-height: 20px; + margin-inline-end: 12px; } #imageButton { @@ -130,7 +133,6 @@ width: 68px; } - #sysInfoContainer, #userConsent { display: flex; margin-bottom: 24px; @@ -218,6 +220,12 @@ </cr-checkbox> <label id="sysInfoCheckboxLabel" inner-h-t-m-l="[[sysInfoCheckboxLabel_]]"></label> </div> + <!-- Bluetooth Logs (Googler Internal Only) --> + <div id="bluetoothCheckboxContainer" class="checkbox-field-container"> + <cr-checkbox id="bluetoothLogsCheckbox" aria-labelledby="sysInfoCheckboxLabel" checked> + </cr-checkbox> + <label id="bluetoothInfoLabel" inner-h-t-m-l="[[bluetoothLogsCheckboxLabel_]]"></label> + </div> </div> <!-- Privacy note --> <div id="privacyNote" inner-h-t-m-l="[[privacyNote_]]"></div>
diff --git a/ash/webui/os_feedback_ui/resources/share_data_page.js b/ash/webui/os_feedback_ui/resources/share_data_page.js index 90c48d1..c65d4813 100644 --- a/ash/webui/os_feedback_ui/resources/share_data_page.js +++ b/ash/webui/os_feedback_ui/resources/share_data_page.js
@@ -70,6 +70,12 @@ * @type {string} * @protected */ + this.bluetoothLogsCheckboxLabel_; + + /** + * @type {string} + * @protected + */ this.privacyNote_; /** @private {!FeedbackServiceProviderInterface} */ @@ -80,6 +86,7 @@ super.ready(); this.setPrivacyNote_(); this.setSysInfoCheckboxLabelAndAttributes_(); + this.setBluetoothLogsCheckboxLabelAndAttributes_(); // Set the aria description works the best for screen reader. // It reads the description when the checkbox is focused, and when it is // checked and unchecked. @@ -175,6 +182,20 @@ * @param {!Event} e * @protected */ + handleOpenBluetoothLogsInfoDialog_(e) { + // The default behavior of clicking on an anchor tag + // with href="#" is a scroll to the top of the page. + // This link opens a dialog, so we want to prevent + // this default behavior. + e.preventDefault(); + + this.feedbackServiceProvider_.openBluetoothLogsInfoDialog(); + } + + /** + * @param {!Event} e + * @protected + */ handleBackButtonClicked_(e) { e.stopPropagation(); @@ -303,6 +324,19 @@ histogramsLink.addEventListener( 'click', (e) => void this.handleOpenMetricsDialog_(e)); } + + /** @private */ + setBluetoothLogsCheckboxLabelAndAttributes_() { + this.bluetoothLogsCheckboxLabel_ = + this.i18nAdvanced('bluetoothLogsInfo', {attrs: ['id']}); + + const bluetoothLogsLink = + this.shadowRoot.querySelector('#bluetoothLogsInfoLink'); + // Setting href causes <a> tag to display as link. + bluetoothLogsLink.setAttribute('href', '#'); + bluetoothLogsLink.addEventListener( + 'click', (e) => void this.handleOpenBluetoothLogsInfoDialog_(e)); + } } customElements.define(ShareDataPageElement.is, ShareDataPageElement);
diff --git a/base/allocator/partition_allocator/partition_bucket.cc b/base/allocator/partition_allocator/partition_bucket.cc index bbb8090..603cc96 100644 --- a/base/allocator/partition_allocator/partition_bucket.cc +++ b/base/allocator/partition_allocator/partition_bucket.cc
@@ -841,14 +841,13 @@ PA_DCHECK(!slot_span->get_freelist_head()); PA_DCHECK(!slot_span->is_full()); - size_t size = slot_size; uintptr_t slot_span_start = SlotSpanMetadata<thread_safe>::ToSlotSpanStart(slot_span); // If we got here, the first unallocated slot is either partially or fully on // an uncommitted page. If the latter, it must be at the start of that page. uintptr_t return_slot = - slot_span_start + (size * slot_span->num_allocated_slots); - uintptr_t next_slot = return_slot + size; + slot_span_start + (slot_size * slot_span->num_allocated_slots); + uintptr_t next_slot = return_slot + slot_size; uintptr_t commit_start = base::bits::AlignUp(return_slot, SystemPageSize()); PA_DCHECK(next_slot > commit_start); uintptr_t commit_end = base::bits::AlignUp(next_slot, SystemPageSize()); @@ -862,7 +861,7 @@ slot_span->num_allocated_slots++; // Round down, because a slot that doesn't fully fit in the new page(s) isn't // provisioned. - size_t slots_to_provision = (commit_end - return_slot) / size; + size_t slots_to_provision = (commit_end - return_slot) / slot_size; slot_span->num_unprovisioned_slots -= slots_to_provision; PA_DCHECK(slot_span->num_allocated_slots + slot_span->num_unprovisioned_slots <= @@ -880,31 +879,31 @@ PageAccessibilityDisposition::kRequireUpdate); } - if (PA_LIKELY(size <= kMaxMemoryTaggingSize)) { + if (PA_LIKELY(slot_size <= kMaxMemoryTaggingSize)) { // Ensure the MTE-tag of the memory pointed by |return_slot| is unguessable. - TagMemoryRangeRandomly(return_slot, size); + TagMemoryRangeRandomly(return_slot, slot_size); } #if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) - PartitionTagSetValue(return_slot, size, root->GetNewPartitionTag()); + PartitionTagSetValue(return_slot, slot_size, root->GetNewPartitionTag()); #endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) // Add all slots that fit within so far committed pages to the free list. PartitionFreelistEntry* prev_entry = nullptr; - uintptr_t next_slot_end = next_slot + size; + uintptr_t next_slot_end = next_slot + slot_size; size_t free_list_entries_added = 0; while (next_slot_end <= commit_end) { void* next_slot_ptr; - if (PA_LIKELY(size <= kMaxMemoryTaggingSize)) { + if (PA_LIKELY(slot_size <= kMaxMemoryTaggingSize)) { // Ensure the MTE-tag of the memory pointed by other provisioned slot is // unguessable. They will be returned to the app as is, and the MTE-tag // will only change upon calling Free(). - next_slot_ptr = TagMemoryRangeRandomly(next_slot, size); + next_slot_ptr = TagMemoryRangeRandomly(next_slot, slot_size); } else { // No MTE-tagging for larger slots, just cast. next_slot_ptr = reinterpret_cast<void*>(next_slot); } #if defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) - PartitionTagSetValue(next_slot, size, root->GetNewPartitionTag()); + PartitionTagSetValue(next_slot, slot_size, root->GetNewPartitionTag()); #endif // defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS) auto* entry = PartitionFreelistEntry::EmplaceAndInitNull(next_slot_ptr); if (!slot_span->get_freelist_head()) { @@ -916,7 +915,7 @@ prev_entry->SetNext(entry); } next_slot = next_slot_end; - next_slot_end = next_slot + size; + next_slot_end = next_slot + slot_size; prev_entry = entry; #if BUILDFLAG(PA_DCHECK_IS_ON) free_list_entries_added++;
diff --git a/base/message_loop/message_pump_glib.cc b/base/message_loop/message_pump_glib.cc index a02deb91..9638bf5 100644 --- a/base/message_loop/message_pump_glib.cc +++ b/base/message_loop/message_pump_glib.cc
@@ -182,9 +182,10 @@ if (RunningOnMainThread()) { context_ = g_main_context_default(); } else { - context_ = g_main_context_new(); + owned_context_ = std::unique_ptr<GMainContext, GMainContextDeleter>( + g_main_context_new()); + context_ = owned_context_.get(); g_main_context_push_thread_default(context_); - context_owned_ = true; } // Create our wakeup pipe, which is used to flag when work was scheduled. @@ -197,25 +198,22 @@ wakeup_gpollfd_->fd = wakeup_pipe_read_; wakeup_gpollfd_->events = G_IO_IN; - work_source_ = g_source_new(&WorkSourceFuncs, sizeof(WorkSource)); - static_cast<WorkSource*>(work_source_)->pump = this; - g_source_add_poll(work_source_, wakeup_gpollfd_.get()); - g_source_set_priority(work_source_, kPriorityWork); + work_source_ = std::unique_ptr<GSource, GSourceDeleter>( + g_source_new(&WorkSourceFuncs, sizeof(WorkSource))); + static_cast<WorkSource*>(work_source_.get())->pump = this; + g_source_add_poll(work_source_.get(), wakeup_gpollfd_.get()); + g_source_set_priority(work_source_.get(), kPriorityWork); // This is needed to allow Run calls inside Dispatch. - g_source_set_can_recurse(work_source_, TRUE); - g_source_attach(work_source_, context_); + g_source_set_can_recurse(work_source_.get(), TRUE); + g_source_attach(work_source_.get(), context_); } MessagePumpGlib::~MessagePumpGlib() { - g_source_destroy(work_source_); - g_source_unref(work_source_); + work_source_.reset(); close(wakeup_pipe_read_); close(wakeup_pipe_write_); - - if (context_owned_) { - g_main_context_pop_thread_default(context_); - g_main_context_unref(context_); - } + context_ = nullptr; + owned_context_.reset(); } MessagePumpGlib::FdWatchController::FdWatchController(const Location& location)
diff --git a/base/message_loop/message_pump_glib.h b/base/message_loop/message_pump_glib.h index 17322fc..cdaee97 100644 --- a/base/message_loop/message_pump_glib.h +++ b/base/message_loop/message_pump_glib.h
@@ -5,6 +5,7 @@ #ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_GLIB_H_ #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_GLIB_H_ +#include <glib.h> #include <memory> #include "base/base_export.h" @@ -14,10 +15,6 @@ #include "base/threading/thread_checker.h" #include "base/time/time.h" -typedef struct _GMainContext GMainContext; -typedef struct _GPollFD GPollFD; -typedef struct _GSource GSource; - namespace base { // This class implements a base MessagePump needed for TYPE_UI MessageLoops on @@ -110,6 +107,22 @@ void HandleFdWatchDispatch(FdWatchController* controller); private: + struct GMainContextDeleter { + inline void operator()(GMainContext* context) const { + if (context) { + g_main_context_pop_thread_default(context); + g_main_context_unref(context); + } + } + }; + struct GSourceDeleter { + inline void operator()(GSource* source) const { + if (source) { + g_source_destroy(source); + g_source_unref(source); + } + } + }; bool ShouldQuit() const; // We may make recursive calls to Run, so we save state that needs to be @@ -118,15 +131,15 @@ raw_ptr<RunState> state_; + std::unique_ptr<GMainContext, GMainContextDeleter> owned_context_; // This is a GLib structure that we can add event sources to. On the main // thread, we use the default GLib context, which is the one to which all GTK // events are dispatched. - raw_ptr<GMainContext, DanglingUntriaged> context_ = nullptr; - bool context_owned_ = false; + raw_ptr<GMainContext> context_ = nullptr; // The work source. It is shared by all calls to Run and destroyed when // the message pump is destroyed. - raw_ptr<GSource, DanglingUntriaged> work_source_; + std::unique_ptr<GSource, GSourceDeleter> work_source_; // We use a wakeup pipe to make sure we'll get out of the glib polling phase // when another thread has scheduled us to do some work. There is a glib
diff --git a/base/metrics/histogram_functions.h b/base/metrics/histogram_functions.h index 76c79b30..738730c7 100644 --- a/base/metrics/histogram_functions.h +++ b/base/metrics/histogram_functions.h
@@ -63,7 +63,7 @@ // kMaxValue = kOpenBookmark, // }; // base::UmaHistogramEnumeration("My.Enumeration", -// NewTabPageAction::kUseSearchbox); +// NewTabPageAction::kClickTitle); template <typename T> void UmaHistogramEnumeration(const std::string& name, T sample) { static_assert(std::is_enum<T>::value, "T is not an enum."); @@ -104,7 +104,7 @@ // kCount, // }; // base::UmaHistogramEnumeration("My.Enumeration", -// NewTabPageAction::kUseSearchbox, +// NewTabPageAction::kClickTitle, // kCount); // Note: The value in |sample| must be strictly less than |enum_size|. This is // otherwise functionally equivalent to the above.
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni index 19677f6..e5b36e22 100644 --- a/buildtools/deps_revisions.gni +++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@ declare_args() { # Used to cause full rebuilds on libc++ rolls. This should be kept in sync # with the libcxx_revision vars in //DEPS. - libcxx_revision = "55e0c49d148aecc33568a1a61b916323004a2d18" + libcxx_revision = "9f503bebdb9a89f5ee82b82142109b26d688f40c" }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 09cf0e58..351deb9 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3009,6 +3009,8 @@ "fast_checkout/fast_checkout_capabilities_fetcher.h", "fast_checkout/fast_checkout_capabilities_fetcher_impl.cc", "fast_checkout/fast_checkout_capabilities_fetcher_impl.h", + "fast_checkout/fast_checkout_capabilities_results_cache.cc", + "fast_checkout/fast_checkout_capabilities_results_cache.h", "fast_checkout/fast_checkout_client.cc", "fast_checkout/fast_checkout_client.h", "fast_checkout/fast_checkout_client_impl.cc", @@ -5563,6 +5565,8 @@ "notifications/notification_platform_bridge_delegate.h", "notifications/notification_platform_bridge_lacros.cc", "notifications/notification_platform_bridge_lacros.h", + "performance_manager/policies/oom_score_policy_lacros.cc", + "performance_manager/policies/oom_score_policy_lacros.h", "platform_util_lacros.cc", "policy/status_provider/device_policy_status_provider_lacros.cc", "policy/status_provider/device_policy_status_provider_lacros.h",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 7ac6571..854a3ef5 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -5095,6 +5095,10 @@ flag_descriptions::kDriveFsChromeNetworkingName, flag_descriptions::kDriveFsChromeNetworkingDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kDriveFsChromeNetworking)}, + {"file-transfer-enterprise-connector", + flag_descriptions::kFileTransferEnterpriseConnectorName, + flag_descriptions::kFileTransferEnterpriseConnectorDescription, kOsCrOS, + FEATURE_VALUE_TYPE(features::kFileTransferEnterpriseConnector)}, {"files-app-experimental", flag_descriptions::kFilesAppExperimentalName, flag_descriptions::kFilesAppExperimentalDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kFilesAppExperimental)}, @@ -7422,12 +7426,6 @@ #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_ANDROID) - {"incognito-brand-consistency-for-android", - flag_descriptions::kIncognitoBrandConsistencyForAndroidName, - flag_descriptions::kIncognitoBrandConsistencyForAndroidDescription, - kOsAndroid, - FEATURE_VALUE_TYPE(features::kIncognitoBrandConsistencyForAndroid)}, - {"incognito-reauthentication-for-android", flag_descriptions::kIncognitoReauthenticationForAndroidName, flag_descriptions::kIncognitoReauthenticationForAndroidDescription,
diff --git a/chrome/browser/apps/app_deduplication_service/app_deduplication_service.cc b/chrome/browser/apps/app_deduplication_service/app_deduplication_service.cc index e40589d..f6bbd6c 100644 --- a/chrome/browser/apps/app_deduplication_service/app_deduplication_service.cc +++ b/chrome/browser/apps/app_deduplication_service/app_deduplication_service.cc
@@ -65,14 +65,16 @@ for (auto const& app : group.second.apps()) { const std::string& app_id = app.app_id_for_platform(); const std::string& source = app.source_name(); - AppType app_type = AppType::kUnknown; + EntryId entry_id; // TODO(b/238394602): Add more data type when real data is ready. if (source == "arc") { - app_type = AppType::kArc; + entry_id = EntryId(app_id, AppType::kArc); } else if (source == "web") { - app_type = AppType::kWeb; + entry_id = EntryId(app_id, AppType::kWeb); + } else if (source == "phonehub") { + entry_id = EntryId(app_id); } - EntryId entry_id(app_id, app_type); + entry_to_group_map_[entry_id] = group.first; Entry entry(std::move(entry_id));
diff --git a/chrome/browser/apps/app_deduplication_service/app_deduplication_service.h b/chrome/browser/apps/app_deduplication_service/app_deduplication_service.h index c367455..254429a 100644 --- a/chrome/browser/apps/app_deduplication_service/app_deduplication_service.h +++ b/chrome/browser/apps/app_deduplication_service/app_deduplication_service.h
@@ -34,6 +34,7 @@ friend class AppDeduplicationServiceTest; FRIEND_TEST_ALL_PREFIXES(AppDeduplicationServiceTest, OnDuplicatedAppsMapUpdated); + FRIEND_TEST_ALL_PREFIXES(AppDeduplicationServiceTest, ExactDuplicate); // AppProvisioningDataManager::Observer: void OnDuplicatedAppsMapUpdated(
diff --git a/chrome/browser/apps/app_deduplication_service/app_deduplication_service_unittest.cc b/chrome/browser/apps/app_deduplication_service/app_deduplication_service_unittest.cc index 65fea9f..508ad50 100644 --- a/chrome/browser/apps/app_deduplication_service/app_deduplication_service_unittest.cc +++ b/chrome/browser/apps/app_deduplication_service/app_deduplication_service_unittest.cc
@@ -4,10 +4,15 @@ #include "chrome/browser/apps/app_deduplication_service/app_deduplication_service.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/path_service.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/apps/app_deduplication_service/app_deduplication_service_factory.h" #include "chrome/browser/apps/app_provisioning_service/app_provisioning_data_manager.h" +#include "chrome/browser/apps/app_provisioning_service/proto/app_data.pb.h" #include "chrome/common/chrome_features.h" +#include "chrome/common/chrome_paths.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/browser_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" @@ -74,6 +79,16 @@ } TEST_F(AppDeduplicationServiceTest, OnDuplicatedAppsMapUpdated) { + base::FilePath path; + EXPECT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &path)); + path = path.AppendASCII("app_deduplication_service/binary_test_data.pb"); + + std::string dedupe_pb; + ASSERT_TRUE(base::ReadFileToString(path, &dedupe_pb)); + + proto::DuplicatedAppsMap duplicated_apps_map; + ASSERT_TRUE(duplicated_apps_map.ParseFromString(dedupe_pb)); + TestingProfile::Builder profile_builder; auto profile = profile_builder.Build(); ASSERT_TRUE(AppDeduplicationServiceFactory:: @@ -81,32 +96,161 @@ auto* service = AppDeduplicationServiceFactory::GetForProfile(profile.get()); EXPECT_NE(nullptr, service); - std::string binary_pb = ""; - base::FilePath install_dir("/"); - apps::AppProvisioningDataManager::Get()->PopulateFromDynamicUpdate( - binary_pb, install_dir); + service->OnDuplicatedAppsMapUpdated(duplicated_apps_map); - std::string test_key = "test_key"; - std::string arc_app_id = "test_arc_app_id"; - auto it = - service->entry_to_group_map_.find(EntryId(arc_app_id, AppType::kArc)); + std::string skype_test_key = "Skype"; + std::string skype_arc_app_id = "com.skype.raider"; + auto it = service->entry_to_group_map_.find( + EntryId(skype_arc_app_id, AppType::kArc)); ASSERT_NE(it, service->entry_to_group_map_.end()); - EXPECT_EQ(test_key, it->second); + EXPECT_EQ(skype_test_key, it->second); - std::string web_app_id = "test_web_app_id"; - it = service->entry_to_group_map_.find(EntryId(web_app_id, AppType::kWeb)); + std::string skype_web_app_id = "http://web.skype.com/"; + it = service->entry_to_group_map_.find( + EntryId(skype_web_app_id, AppType::kWeb)); ASSERT_NE(it, service->entry_to_group_map_.end()); - EXPECT_EQ(test_key, it->second); + EXPECT_EQ(skype_test_key, it->second); - auto map_it = service->duplication_map_.find(test_key); + std::string skype_phonehub_app_id = "com.skype.raider"; + it = service->entry_to_group_map_.find(EntryId(skype_phonehub_app_id)); + ASSERT_NE(it, service->entry_to_group_map_.end()); + EXPECT_EQ(skype_test_key, it->second); + + auto map_it = service->duplication_map_.find(skype_test_key); ASSERT_FALSE(map_it == service->duplication_map_.end()); EXPECT_THAT(map_it->second.entries, - ElementsAre(Entry(EntryId(arc_app_id, AppType::kArc)), - Entry(EntryId(web_app_id, AppType::kWeb)))); + ElementsAre(Entry(EntryId(skype_phonehub_app_id)), + Entry(EntryId(skype_arc_app_id, AppType::kArc)), + Entry(EntryId(skype_web_app_id, AppType::kWeb)))); + + std::string whatsapp_test_key = "WhatsApp"; + std::string whatsapp_arc_app_id = "com.whatsapp"; + it = service->entry_to_group_map_.find( + EntryId(whatsapp_arc_app_id, AppType::kArc)); + ASSERT_NE(it, service->entry_to_group_map_.end()); + EXPECT_EQ(whatsapp_test_key, it->second); + + std::string whatsapp_web_app_id = "http://web.whatsapp.com/"; + it = service->entry_to_group_map_.find( + EntryId(whatsapp_web_app_id, AppType::kWeb)); + ASSERT_NE(it, service->entry_to_group_map_.end()); + EXPECT_EQ(whatsapp_test_key, it->second); + + std::string whatsapp_phonehub_app_id = "com.whatsapp"; + it = service->entry_to_group_map_.find(EntryId(whatsapp_phonehub_app_id)); + ASSERT_NE(it, service->entry_to_group_map_.end()); + EXPECT_EQ(whatsapp_test_key, it->second); + + map_it = service->duplication_map_.find(whatsapp_test_key); + ASSERT_FALSE(map_it == service->duplication_map_.end()); + EXPECT_THAT(map_it->second.entries, + ElementsAre(Entry(EntryId(whatsapp_phonehub_app_id)), + Entry(EntryId(whatsapp_arc_app_id, AppType::kArc)), + Entry(EntryId(whatsapp_web_app_id, AppType::kWeb)))); } -// Test exact match entry ids. TEST_F(AppDeduplicationServiceTest, ExactDuplicate) { + base::FilePath path; + EXPECT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &path)); + path = path.AppendASCII("app_deduplication_service/binary_test_data.pb"); + + std::string dedupe_pb; + ASSERT_TRUE(base::ReadFileToString(path, &dedupe_pb)); + + proto::DuplicatedAppsMap duplicated_apps_map; + ASSERT_TRUE(duplicated_apps_map.ParseFromString(dedupe_pb)); + + TestingProfile::Builder profile_builder; + auto profile = profile_builder.Build(); + ASSERT_TRUE(AppDeduplicationServiceFactory:: + IsAppDeduplicationServiceAvailableForProfile(profile.get())); + auto* service = AppDeduplicationServiceFactory::GetForProfile(profile.get()); + EXPECT_NE(nullptr, service); + + service->OnDuplicatedAppsMapUpdated(duplicated_apps_map); + + EntryId skype_arc_entry_id("com.skype.raider", apps::AppType::kArc); + EntryId skype_web_entry_id("http://web.skype.com/", apps::AppType::kWeb); + EntryId skype_phonehub_entry_id("com.skype.raider"); + EntryId whatsapp_arc_entry_id("com.whatsapp", apps::AppType::kArc); + EntryId whatsapp_web_entry_id("http://web.whatsapp.com/", + apps::AppType::kWeb); + EntryId whatsapp_phonehub_entry_id("com.whatsapp"); + + EXPECT_THAT( + service->GetDuplicates(skype_arc_entry_id), + ElementsAre(Entry(skype_phonehub_entry_id), Entry(skype_arc_entry_id), + Entry(skype_web_entry_id))); + EXPECT_THAT( + service->GetDuplicates(skype_web_entry_id), + ElementsAre(Entry(skype_phonehub_entry_id), Entry(skype_arc_entry_id), + Entry(skype_web_entry_id))); + EXPECT_THAT( + service->GetDuplicates(skype_phonehub_entry_id), + ElementsAre(Entry(skype_phonehub_entry_id), Entry(skype_arc_entry_id), + Entry(skype_web_entry_id))); + EXPECT_THAT( + service->GetDuplicates(whatsapp_web_entry_id), + ElementsAre(Entry(whatsapp_phonehub_entry_id), + Entry(whatsapp_arc_entry_id), Entry(whatsapp_web_entry_id))); + EXPECT_THAT( + service->GetDuplicates(whatsapp_arc_entry_id), + ElementsAre(Entry(whatsapp_phonehub_entry_id), + Entry(whatsapp_arc_entry_id), Entry(whatsapp_web_entry_id))); + EXPECT_THAT( + service->GetDuplicates(whatsapp_phonehub_entry_id), + ElementsAre(Entry(whatsapp_phonehub_entry_id), + Entry(whatsapp_arc_entry_id), Entry(whatsapp_web_entry_id))); + + EXPECT_TRUE(service->AreDuplicates(skype_arc_entry_id, skype_web_entry_id)); + EXPECT_TRUE( + service->AreDuplicates(skype_arc_entry_id, skype_phonehub_entry_id)); + EXPECT_TRUE( + service->AreDuplicates(skype_phonehub_entry_id, skype_web_entry_id)); + EXPECT_TRUE( + service->AreDuplicates(whatsapp_arc_entry_id, whatsapp_web_entry_id)); + EXPECT_TRUE(service->AreDuplicates(whatsapp_arc_entry_id, + whatsapp_phonehub_entry_id)); + EXPECT_TRUE(service->AreDuplicates(whatsapp_web_entry_id, + whatsapp_phonehub_entry_id)); + + EXPECT_FALSE( + service->AreDuplicates(skype_arc_entry_id, whatsapp_arc_entry_id)); + EXPECT_FALSE( + service->AreDuplicates(skype_arc_entry_id, whatsapp_web_entry_id)); + EXPECT_FALSE( + service->AreDuplicates(skype_arc_entry_id, whatsapp_phonehub_entry_id)); + EXPECT_FALSE( + service->AreDuplicates(skype_web_entry_id, whatsapp_arc_entry_id)); + EXPECT_FALSE( + service->AreDuplicates(skype_web_entry_id, whatsapp_web_entry_id)); + EXPECT_FALSE( + service->AreDuplicates(skype_web_entry_id, whatsapp_phonehub_entry_id)); + EXPECT_FALSE( + service->AreDuplicates(skype_phonehub_entry_id, whatsapp_arc_entry_id)); + EXPECT_FALSE( + service->AreDuplicates(skype_phonehub_entry_id, whatsapp_web_entry_id)); + EXPECT_FALSE(service->AreDuplicates(skype_phonehub_entry_id, + whatsapp_phonehub_entry_id)); + + EntryId not_duplicate_app_id("not_duplicate_app_id", apps::AppType::kWeb); + EXPECT_TRUE(service->GetDuplicates(not_duplicate_app_id).empty()); + EXPECT_FALSE( + service->AreDuplicates(not_duplicate_app_id, skype_arc_entry_id)); + EXPECT_FALSE( + service->AreDuplicates(not_duplicate_app_id, skype_web_entry_id)); + EXPECT_FALSE( + service->AreDuplicates(not_duplicate_app_id, skype_phonehub_entry_id)); + EXPECT_FALSE( + service->AreDuplicates(not_duplicate_app_id, whatsapp_arc_entry_id)); + EXPECT_FALSE( + service->AreDuplicates(not_duplicate_app_id, whatsapp_web_entry_id)); + EXPECT_FALSE( + service->AreDuplicates(not_duplicate_app_id, whatsapp_phonehub_entry_id)); +} + +// Test updating duplication data from app provisioning data manager. +TEST_F(AppDeduplicationServiceTest, AppPromisioningDataManagerUpdate) { TestingProfile::Builder profile_builder; auto profile = profile_builder.Build(); ASSERT_TRUE(AppDeduplicationServiceFactory:: @@ -116,13 +260,13 @@ std::string binary_pb = ""; base::FilePath install_dir("/"); + // TODO(b/238394602): Move the fake data population to test only when real + // data feeds in. apps::AppProvisioningDataManager::Get()->PopulateFromDynamicUpdate( binary_pb, install_dir); - std::string arc_app_id = "test_arc_app_id"; - std::string web_app_id = "test_web_app_id"; - EntryId arc_entry_id(arc_app_id, apps::AppType::kArc); - EntryId web_entry_id(web_app_id, apps::AppType::kWeb); + EntryId arc_entry_id("test_arc_app_id", apps::AppType::kArc); + EntryId web_entry_id("test_web_app_id", apps::AppType::kWeb); EXPECT_THAT(service->GetDuplicates(arc_entry_id), ElementsAre(Entry(arc_entry_id), Entry(web_entry_id)));
diff --git a/chrome/browser/apps/app_deduplication_service/entry_types.h b/chrome/browser/apps/app_deduplication_service/entry_types.h index a24ff4f6..723ed5c 100644 --- a/chrome/browser/apps/app_deduplication_service/entry_types.h +++ b/chrome/browser/apps/app_deduplication_service/entry_types.h
@@ -19,8 +19,9 @@ }; struct EntryId { + EntryId() = default; // Constructor for apps. - EntryId(std::string app_id, apps::AppType app_type); + EntryId(std::string app_id, AppType app_type); // Constructor for web pages. explicit EntryId(const GURL& url);
diff --git a/chrome/browser/ash/app_mode/startup_app_launcher.cc b/chrome/browser/ash/app_mode/startup_app_launcher.cc index e32b4232..277a971 100644 --- a/chrome/browser/ash/app_mode/startup_app_launcher.cc +++ b/chrome/browser/ash/app_mode/startup_app_launcher.cc
@@ -69,7 +69,7 @@ } callback_ = std::move(callback); - browser_manager()->InitializeAndStart(); + browser_manager()->InitializeAndStartIfNeeded(); browser_manager_observation_.Observe(browser_manager()); }
diff --git a/chrome/browser/ash/crosapi/BUILD.gn b/chrome/browser/ash/crosapi/BUILD.gn index f12fcc0..f26e8db 100644 --- a/chrome/browser/ash/crosapi/BUILD.gn +++ b/chrome/browser/ash/crosapi/BUILD.gn
@@ -42,6 +42,8 @@ "authentication_ash.h", "automation_ash.cc", "automation_ash.h", + "browser_action.cc", + "browser_action.h", "browser_data_migrator.cc", "browser_data_migrator.h", "browser_data_migrator_util.cc",
diff --git a/chrome/browser/ash/crosapi/browser_action.cc b/chrome/browser/ash/crosapi/browser_action.cc new file mode 100644 index 0000000..35e3afc0 --- /dev/null +++ b/chrome/browser/ash/crosapi/browser_action.cc
@@ -0,0 +1,371 @@ +// Copyright 2022 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/ash/crosapi/browser_action.h" + +#include "chrome/browser/ash/app_restore/full_restore_service.h" +#include "chrome/browser/ash/crosapi/crosapi_ash.h" +#include "chrome/browser/ash/crosapi/crosapi_manager.h" +#include "chrome/browser/ash/crosapi/desk_template_ash.h" +#include "chrome/browser/prefs/incognito_mode_prefs.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "components/user_manager/user_manager.h" + +namespace crosapi { + +// No-op action, used to start the browser without opening a window. +class NoOpAction final : public BrowserAction { + public: + NoOpAction() : BrowserAction(true) {} + void Perform(const VersionedBrowserService& service) override{}; +}; + +class NewWindowAction final : public BrowserAction { + public: + NewWindowAction(bool incognito, bool should_trigger_session_restore) + : BrowserAction(true), + incognito_(incognito), + should_trigger_session_restore_(should_trigger_session_restore) {} + + void Perform(const VersionedBrowserService& service) override { + if (incognito_) { + Profile* profile = ProfileManager::GetPrimaryUserProfile(); + if (!profile || !IncognitoModePrefs::IsIncognitoAllowed(profile)) + return; + } + service.service->NewWindow(incognito_, should_trigger_session_restore_, + base::DoNothing()); + } + + private: + const bool incognito_; + const bool should_trigger_session_restore_; +}; + +class NewWindowForDetachingTabAction final : public BrowserAction { + public: + NewWindowForDetachingTabAction(base::StringPiece16 tab_id_str, + base::StringPiece16 group_id_str, + NewWindowForDetachingTabCallback callback) + : BrowserAction(false), + tab_id_str_(tab_id_str), + group_id_str_(group_id_str), + callback_(std::move(callback)) {} + + void Perform(const VersionedBrowserService& service) override { + if (service.interface_version < + mojom::BrowserService::kNewWindowForDetachingTabMinVersion) { + Cancel(crosapi::mojom::CreationResult::kUnsupported); + return; + } + service.service->NewWindowForDetachingTab(tab_id_str_, group_id_str_, + std::move(callback_)); + } + + void Cancel(crosapi::mojom::CreationResult reason) override { + std::move(callback_).Run(reason, std::string() /*new_window*/); + }; + + private: + const std::u16string tab_id_str_; + const std::u16string group_id_str_; + NewWindowForDetachingTabCallback callback_; +}; + +class NewTabAction final : public BrowserAction { + public: + explicit NewTabAction(bool should_trigger_session_restore) + : BrowserAction(true), + should_trigger_session_restore_(should_trigger_session_restore) {} + + void Perform(const VersionedBrowserService& service) override { + service.service->NewTab(should_trigger_session_restore_, base::DoNothing()); + } + + private: + const bool should_trigger_session_restore_; +}; + +namespace { +crosapi::mojom::OpenUrlParams_SwitchToTabPathBehavior ConvertPathBehavior( + NavigateParams::PathBehavior path_behavior) { + switch (path_behavior) { + case NavigateParams::RESPECT: + return crosapi::mojom::OpenUrlParams_SwitchToTabPathBehavior::kRespect; + case NavigateParams::IGNORE_AND_NAVIGATE: + return crosapi::mojom::OpenUrlParams_SwitchToTabPathBehavior::kIgnore; + } +} +} // namespace + +class OpenUrlAction final : public BrowserAction { + public: + OpenUrlAction( + const GURL& url, + crosapi::mojom::OpenUrlParams::WindowOpenDisposition disposition, + crosapi::mojom::OpenUrlFrom from, + NavigateParams::PathBehavior path_behavior) + : BrowserAction(true), + url_(url), + disposition_(disposition), + from_(from), + path_behavior_(path_behavior) {} + + void Perform(const VersionedBrowserService& service) override { + if (service.interface_version < mojom::BrowserService::kOpenUrlMinVersion) { + LOG(ERROR) << "BrowserService does not support OpenUrl"; + return; + } + auto params = crosapi::mojom::OpenUrlParams::New(); + params->disposition = disposition_; + params->from = from_; + params->path_behavior = ConvertPathBehavior(path_behavior_); + service.service->OpenUrl(url_, std::move(params), base::DoNothing()); + } + + private: + const GURL url_; + const crosapi::mojom::OpenUrlParams::WindowOpenDisposition disposition_; + const crosapi::mojom::OpenUrlFrom from_; + const NavigateParams::PathBehavior path_behavior_; +}; + +class NewGuestWindowAction final : public BrowserAction { + public: + NewGuestWindowAction() : BrowserAction(true) {} + + void Perform(const VersionedBrowserService& service) override { + if (service.interface_version < + crosapi::mojom::BrowserService::kNewGuestWindowMinVersion) { + return; + } + service.service->NewGuestWindow(base::DoNothing()); + } +}; + +class HandleTabScrubbingAction final : public BrowserAction { + public: + explicit HandleTabScrubbingAction(float x_offset) + : BrowserAction(false), x_offset_(x_offset) {} + + void Perform(const VersionedBrowserService& service) override { + if (service.interface_version < + crosapi::mojom::BrowserService::kHandleTabScrubbingMinVersion) { + return; + } + service.service->HandleTabScrubbing(x_offset_); + } + + private: + const float x_offset_; +}; + +class NewFullscreenWindowAction final : public BrowserAction { + public: + NewFullscreenWindowAction(const GURL& url, + NewFullscreenWindowCallback callback) + : BrowserAction(true), url_(url), callback_(std::move(callback)) {} + + void Perform(const VersionedBrowserService& service) override { + if (service.interface_version < + crosapi::mojom::BrowserService::kNewFullscreenWindowMinVersion) { + Cancel(crosapi::mojom::CreationResult::kUnsupported); + return; + } + service.service->NewFullscreenWindow(url_, std::move(callback_)); + } + + void Cancel(crosapi::mojom::CreationResult reason) override { + std::move(callback_).Run(reason); + }; + + private: + const GURL url_; + NewFullscreenWindowCallback callback_; +}; + +class RestoreTabAction final : public BrowserAction { + public: + RestoreTabAction() : BrowserAction(true) {} + + void Perform(const VersionedBrowserService& service) override { + service.service->RestoreTab(base::DoNothing()); + } +}; + +namespace { +ui::mojom::WindowShowState ConvertWindowShowState(ui::WindowShowState state) { + switch (state) { + case ui::SHOW_STATE_DEFAULT: + return ui::mojom::WindowShowState::SHOW_STATE_DEFAULT; + case ui::SHOW_STATE_NORMAL: + return ui::mojom::WindowShowState::SHOW_STATE_NORMAL; + case ui::SHOW_STATE_MINIMIZED: + return ui::mojom::WindowShowState::SHOW_STATE_MINIMIZED; + case ui::SHOW_STATE_MAXIMIZED: + return ui::mojom::WindowShowState::SHOW_STATE_MAXIMIZED; + case ui::SHOW_STATE_INACTIVE: + return ui::mojom::WindowShowState::SHOW_STATE_INACTIVE; + case ui::SHOW_STATE_FULLSCREEN: + return ui::mojom::WindowShowState::SHOW_STATE_FULLSCREEN; + case ui::SHOW_STATE_END: + NOTREACHED(); + return ui::mojom::WindowShowState::SHOW_STATE_DEFAULT; + } +} +} // namespace + +class CreateBrowserWithRestoredDataAction final : public BrowserAction { + public: + CreateBrowserWithRestoredDataAction(const std::vector<GURL>& urls, + const gfx::Rect& bounds, + ui::WindowShowState show_state, + int32_t active_tab_index, + base::StringPiece app_name, + int32_t restore_window_id) + : BrowserAction(true), + urls_(urls), + bounds_(bounds), + show_state_(show_state), + active_tab_index_(active_tab_index), + app_name_(app_name), + restore_window_id_(restore_window_id) {} + + void Perform(const VersionedBrowserService& service) override { + crosapi::mojom::DeskTemplateStatePtr additional_state = + crosapi::mojom::DeskTemplateState::New(urls_, active_tab_index_, + app_name_, restore_window_id_); + crosapi::CrosapiManager::Get() + ->crosapi_ash() + ->desk_template_ash() + ->CreateBrowserWithRestoredData(bounds_, + ConvertWindowShowState(show_state_), + std::move(additional_state)); + } + + private: + const std::vector<GURL> urls_; + const gfx::Rect bounds_; + const ui::WindowShowState show_state_; + const int32_t active_tab_index_; + const std::string app_name_; + const int32_t restore_window_id_; +}; + +// static +std::unique_ptr<BrowserAction> BrowserAction::NewWindow( + bool incognito, + bool should_trigger_session_restore) { + return std::make_unique<NewWindowAction>(incognito, + should_trigger_session_restore); +} + +// static +std::unique_ptr<BrowserAction> BrowserAction::NewTab( + bool should_trigger_session_restore) { + return std::make_unique<NewTabAction>(should_trigger_session_restore); +} + +// static +std::unique_ptr<BrowserAction> BrowserAction::NewWindowForDetachingTab( + base::StringPiece16 tab_id_str, + base::StringPiece16 group_id_str, + NewWindowForDetachingTabCallback callback) { + return std::make_unique<NewWindowForDetachingTabAction>( + tab_id_str, group_id_str, std::move(callback)); +} + +// static +std::unique_ptr<BrowserAction> BrowserAction::NewGuestWindow() { + return std::make_unique<NewGuestWindowAction>(); +} + +// static +std::unique_ptr<BrowserAction> BrowserAction::NewFullscreenWindow( + const GURL& url, + NewFullscreenWindowCallback callback) { + return std::make_unique<NewFullscreenWindowAction>(url, std::move(callback)); +} + +// static +std::unique_ptr<BrowserAction> BrowserAction::OpenUrl( + const GURL& url, + crosapi::mojom::OpenUrlParams::WindowOpenDisposition disposition, + crosapi::mojom::OpenUrlFrom from, + NavigateParams::PathBehavior path_behavior) { + return std::make_unique<OpenUrlAction>(url, disposition, from, path_behavior); +} + +// static +std::unique_ptr<BrowserAction> BrowserAction::RestoreTab() { + return std::make_unique<RestoreTabAction>(); +} + +// static +std::unique_ptr<BrowserAction> BrowserAction::HandleTabScrubbing( + float x_offset) { + return std::make_unique<HandleTabScrubbingAction>(x_offset); +} + +// static +std::unique_ptr<BrowserAction> BrowserAction::CreateBrowserWithRestoredData( + const std::vector<GURL>& urls, + const gfx::Rect& bounds, + ui::WindowShowState show_state, + int32_t active_tab_index, + base::StringPiece app_name, + int32_t restore_window_id) { + return std::make_unique<CreateBrowserWithRestoredDataAction>( + urls, bounds, show_state, active_tab_index, app_name, restore_window_id); +} + +// No window will be opened in the following circumstances: +// 1. Lacros-chrome is initialized in the web Kiosk session +// 2. Full restore is responsible for restoring/launching Lacros. +// static +std::unique_ptr<BrowserAction> BrowserAction::GetActionForSessionStart() { + if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) + return std::make_unique<NewWindowAction>( + /*incognito=*/false, /*should_trigger_session_restore=*/false); + if (user_manager::UserManager::Get()->IsLoggedInAsWebKioskApp() || + ash::full_restore::MaybeCreateFullRestoreServiceForLacros()) + return std::make_unique<NoOpAction>(); + return std::make_unique<NewWindowAction>( + /*incognito=*/false, /*should_trigger_session_restore=*/true); +} + +BrowserActionQueue::BrowserActionQueue() = default; +BrowserActionQueue::~BrowserActionQueue() = default; + +bool BrowserActionQueue::IsEmpty() const { + return actions_.empty(); +} + +void BrowserActionQueue::PushOrCancel(std::unique_ptr<BrowserAction> action) { + if (action->IsQueueable()) { + actions_.push(std::move(action)); + } else { + action->Cancel(mojom::CreationResult::kBrowserNotRunning); + } +} + +void BrowserActionQueue::Push(std::unique_ptr<BrowserAction> action) { + DCHECK(action->IsQueueable()); + actions_.push(std::move(action)); +} + +std::unique_ptr<BrowserAction> BrowserActionQueue::Pop() { + DCHECK(!IsEmpty()); + std::unique_ptr<BrowserAction> action = std::move(actions_.front()); + actions_.pop(); + return action; +} + +void BrowserActionQueue::Clear() { + base::queue<std::unique_ptr<BrowserAction>> empty; + actions_.swap(empty); + DCHECK(IsEmpty()); +} + +} // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/browser_action.h b/chrome/browser/ash/crosapi/browser_action.h new file mode 100644 index 0000000..be68a00 --- /dev/null +++ b/chrome/browser/ash/crosapi/browser_action.h
@@ -0,0 +1,102 @@ +// Copyright 2022 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_ASH_CROSAPI_BROWSER_ACTION_H_ +#define CHROME_BROWSER_ASH_CROSAPI_BROWSER_ACTION_H_ + +#include "base/containers/queue.h" +#include "base/strings/string_piece_forward.h" +#include "chrome/browser/ui/browser_navigator_params.h" +#include "chromeos/crosapi/mojom/crosapi.mojom.h" +#include "ui/base/ui_base_types.h" + +namespace crosapi { + +struct VersionedBrowserService { + mojom::BrowserService* service; + uint32_t interface_version; +}; + +// Base class representing the browser actions that BrowserManager provides. +class BrowserAction { + public: + explicit BrowserAction(bool is_queueable) : is_queueable_(is_queueable) {} + virtual ~BrowserAction() = default; + + using NewFullscreenWindowCallback = + base::OnceCallback<void(crosapi::mojom::CreationResult)>; + using NewWindowForDetachingTabCallback = + base::OnceCallback<void(crosapi::mojom::CreationResult, + const std::string&)>; + + // Factory functions for creating specific browser actions. See + // the browser_manager.h for documentation. + static std::unique_ptr<BrowserAction> NewWindow( + bool incognito, + bool should_trigger_session_restore); + static std::unique_ptr<BrowserAction> NewTab( + bool should_trigger_session_restore); + static std::unique_ptr<BrowserAction> NewWindowForDetachingTab( + base::StringPiece16 tab_id_str, + base::StringPiece16 group_id_str, + NewWindowForDetachingTabCallback callback); + static std::unique_ptr<BrowserAction> NewGuestWindow(); + static std::unique_ptr<BrowserAction> NewFullscreenWindow( + const GURL& url, + NewFullscreenWindowCallback callback); + static std::unique_ptr<BrowserAction> OpenUrl( + const GURL& url, + crosapi::mojom::OpenUrlParams::WindowOpenDisposition disposition, + crosapi::mojom::OpenUrlFrom from, + NavigateParams::PathBehavior path_behavior); + static std::unique_ptr<BrowserAction> RestoreTab(); + static std::unique_ptr<BrowserAction> HandleTabScrubbing(float x_offset); + static std::unique_ptr<BrowserAction> CreateBrowserWithRestoredData( + const std::vector<GURL>& urls, + const gfx::Rect& bounds, + ui::WindowShowState show_state, + int32_t active_tab_index, + base::StringPiece app_name, + int32_t restore_window_id); + + // Returns the initial action for the automatic start of Lacros. + // No window will be opened in the following circumstances: + // 1. Lacros-chrome is initialized in the web Kiosk session + // 2. Full restore is responsible for restoring/launching Lacros. + static std::unique_ptr<BrowserAction> GetActionForSessionStart(); + + // Performs the action. + virtual void Perform(const VersionedBrowserService& service) = 0; + + // Cancels the action. + virtual void Cancel(crosapi::mojom::CreationResult reason) {} + + // Returns whether the action can be be postponed when Lacros isn't ready. + bool IsQueueable() const { return is_queueable_; } + + private: + const bool is_queueable_; +}; + +// A queue of queueable actions. +class BrowserActionQueue { + public: + BrowserActionQueue(); + ~BrowserActionQueue(); + + // Enqueues |action| if it is queueable. Cancels it otherwise. + void PushOrCancel(std::unique_ptr<BrowserAction> action); + + void Push(std::unique_ptr<BrowserAction> action); + std::unique_ptr<BrowserAction> Pop(); + bool IsEmpty() const; + void Clear(); + + private: + base::queue<std::unique_ptr<BrowserAction>> actions_; +}; + +} // namespace crosapi + +#endif // CHROME_BROWSER_ASH_CROSAPI_BROWSER_ACTION_H_
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc index 553bc236..371a715 100644 --- a/chrome/browser/ash/crosapi/browser_manager.cc +++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -20,6 +20,7 @@ #include "base/callback.h" #include "base/callback_helpers.h" #include "base/command_line.h" +#include "base/debug/stack_trace.h" #include "base/environment.h" #include "base/files/file.h" #include "base/files/file_path.h" @@ -44,7 +45,7 @@ #include "base/task/thread_pool.h" #include "base/threading/thread_restrictions.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" -#include "chrome/browser/ash/app_restore/full_restore_service.h" +#include "chrome/browser/ash/crosapi/browser_action.h" #include "chrome/browser/ash/crosapi/browser_data_migrator.h" #include "chrome/browser/ash/crosapi/browser_data_migrator_util.h" #include "chrome/browser/ash/crosapi/browser_loader.h" @@ -64,7 +65,6 @@ #include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/component_updater/cros_component_manager.h" #include "chrome/browser/notifications/system_notification_helper.h" -#include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h" #include "chrome/browser/ui/browser_navigator_params.h" @@ -369,23 +369,6 @@ browser_util::kLaunchOnLoginPref); } -// Returns the initial browser action. No browser will be opened in the -// following circumstances: -// 1. Lacros-chrome is initialized in the web Kiosk session -// 2. Full restore is responsible for restoring/launching Lacros. -browser_util::InitialBrowserAction GetInitialBrowserAction() { - if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) { - return browser_util::InitialBrowserAction( - mojom::InitialBrowserAction::kOpenNewTabPageWindow); - } - - return browser_util::InitialBrowserAction( - user_manager::UserManager::Get()->IsLoggedInAsWebKioskApp() || - ash::full_restore::MaybeCreateFullRestoreServiceForLacros() - ? mojom::InitialBrowserAction::kDoNotOpenWindow - : mojom::InitialBrowserAction::kUseStartupPreference); -} - bool IsKeepAliveDisabledForTesting() { return base::CommandLine::ForCurrentProcess()->HasSwitch( ash::switches::kDisableLacrosKeepAliveForTesting); @@ -396,57 +379,8 @@ ash::switches::kDisableLoginLacrosOpening); } -ui::mojom::WindowShowState ConvertWindowShowState(ui::WindowShowState state) { - switch (state) { - case ui::SHOW_STATE_DEFAULT: - return ui::mojom::WindowShowState::SHOW_STATE_DEFAULT; - case ui::SHOW_STATE_NORMAL: - return ui::mojom::WindowShowState::SHOW_STATE_NORMAL; - case ui::SHOW_STATE_MINIMIZED: - return ui::mojom::WindowShowState::SHOW_STATE_MINIMIZED; - case ui::SHOW_STATE_MAXIMIZED: - return ui::mojom::WindowShowState::SHOW_STATE_MAXIMIZED; - case ui::SHOW_STATE_INACTIVE: - return ui::mojom::WindowShowState::SHOW_STATE_INACTIVE; - case ui::SHOW_STATE_FULLSCREEN: - return ui::mojom::WindowShowState::SHOW_STATE_FULLSCREEN; - case ui::SHOW_STATE_END: - NOTREACHED(); - return ui::mojom::WindowShowState::SHOW_STATE_DEFAULT; - } -} - -crosapi::mojom::OpenUrlParams_SwitchToTabPathBehavior ConvertPathBehavior( - NavigateParams::PathBehavior path_behavior) { - switch (path_behavior) { - case NavigateParams::RESPECT: - return crosapi::mojom::OpenUrlParams_SwitchToTabPathBehavior::kRespect; - case NavigateParams::IGNORE_AND_NAVIGATE: - return crosapi::mojom::OpenUrlParams_SwitchToTabPathBehavior::kIgnore; - } -} - } // namespace -BrowserManager::RestoreFromDeskTemplate::RestoreFromDeskTemplate( - const std::vector<GURL>& urls, - const gfx::Rect& bounds, - ui::WindowShowState show_state, - int32_t active_tab_index, - const std::string& app_name, - int32_t restore_window_id) - : urls(urls), - bounds(bounds), - show_state(show_state), - active_tab_index(active_tab_index), - app_name(app_name), - restore_window_id(restore_window_id) {} - -BrowserManager::RestoreFromDeskTemplate::RestoreFromDeskTemplate( - RestoreFromDeskTemplate&&) = default; - -BrowserManager::RestoreFromDeskTemplate::~RestoreFromDeskTemplate() = default; - // To be sure the lacros is running with neutral thread type. class LacrosThreadTypeDelegate : public base::LaunchOptions::PreExecDelegate { public: @@ -535,45 +469,14 @@ state_ == State::CREATING_LOG_FILE || state_ == State::TERMINATING; } -void BrowserManager::DisableAutoLaunchForTesting() { - disable_autolaunch_for_testing_ = true; -} - void BrowserManager::NewWindow(bool incognito, bool should_trigger_session_restore) { - if (incognito) { - Profile* profile = ProfileManager::GetPrimaryUserProfile(); - if (!profile || !IncognitoModePrefs::IsIncognitoAllowed(profile)) - return; - } - - // If `should_trigger_session_restore` is set to true the new lacros window - // should be treated like the start of a new session. Ensure this is the case - // by deferring to the browser startup preferences. Otherwise we open the - // window with the default NTP. - // Incognito's default behavior is to open to a NTP regardless of session - // restore settings so the same browser action is used regardless of the value - // of `should_trigger_session_restore`. - constexpr mojom::InitialBrowserAction kBrowserActions[2][2] = { - {mojom::InitialBrowserAction::kOpenNewTabPageWindow, - mojom::InitialBrowserAction::kUseStartupPreference}, - {mojom::InitialBrowserAction::kOpenIncognitoWindow, - mojom::InitialBrowserAction::kOpenIncognitoWindow}}; - - auto result = MaybeStart(browser_util::InitialBrowserAction( - kBrowserActions[incognito][should_trigger_session_restore])); - - if (result != MaybeStartResult::kRunning) - return; - - if (!browser_service_.has_value()) { - LOG(ERROR) << "BrowserService was disconnected"; - return; - } - browser_service_->service->NewWindow( - incognito, should_trigger_session_restore, base::DoNothing()); + PerformOrEnqueue( + BrowserAction::NewWindow(incognito, should_trigger_session_restore)); } +// TODO(neis): Create BrowserAction also for this and others, perhaps even +// UpdateKeepAlive. void BrowserManager::OpenForFullRestore(bool skip_crash_restore) { if (!browser_service_) { LOG(ERROR) << "BrowserService is disconnected, cannot perform Full Restore"; @@ -582,171 +485,63 @@ browser_service_->service->OpenForFullRestore(skip_crash_restore); } -bool BrowserManager::NewWindowForDetachingTabSupported() const { - return browser_service_.has_value() && - browser_service_->interface_version >= - crosapi::mojom::BrowserService:: - kNewWindowForDetachingTabMinVersion; -} - void BrowserManager::NewWindowForDetachingTab( const std::u16string& tab_id_str, const std::u16string& group_id_str, NewWindowForDetachingTabCallback callback) { - // Chrome OS uses different user model where clicking the chrome icon always - // opens a new tab page, and it doesn't matter whether lacros is launching - // for the first time or not. - auto result = MaybeStart(browser_util::InitialBrowserAction( - mojom::InitialBrowserAction::kOpenNewTabPageWindow)); - if (result != MaybeStartResult::kRunning) { - std::move(callback).Run(mojom::CreationResult::kBrowserNotRunning, - std::string() /*new_window*/); - return; - } - - if (!browser_service_.has_value()) { - std::move(callback).Run(mojom::CreationResult::kServiceDisconnected, - std::string() /*new_window*/); - return; - } - - if (!NewWindowForDetachingTabSupported()) { - std::move(callback).Run(mojom::CreationResult::kUnsupported, - std::string() /*new_window*/); - return; - } - browser_service_->service->NewWindowForDetachingTab(tab_id_str, group_id_str, - std::move(callback)); -} - -bool BrowserManager::NewFullscreenWindowSupported() const { - return browser_service_.has_value() && - browser_service_->interface_version >= - crosapi::mojom::BrowserService::kNewFullscreenWindowMinVersion; + PerformOrEnqueue(BrowserAction::NewWindowForDetachingTab( + tab_id_str, group_id_str, std::move(callback))); } void BrowserManager::NewFullscreenWindow(const GURL& url, NewFullscreenWindowCallback callback) { - auto result = MaybeStart(browser_util::InitialBrowserAction( - mojom::InitialBrowserAction::kDoNotOpenWindow)); - if (result != MaybeStartResult::kRunning) { - std::move(callback).Run(mojom::CreationResult::kBrowserNotRunning); - return; - } - - if (!browser_service_.has_value()) { - LOG(ERROR) << "BrowserService was disconnected"; - std::move(callback).Run(mojom::CreationResult::kServiceDisconnected); - return; - } - - if (!NewFullscreenWindowSupported()) { - std::move(callback).Run(mojom::CreationResult::kUnsupported); - return; - } - browser_service_->service->NewFullscreenWindow(url, std::move(callback)); + PerformOrEnqueue( + BrowserAction::NewFullscreenWindow(url, std::move(callback))); } void BrowserManager::NewGuestWindow() { - auto result = MaybeStart(browser_util::InitialBrowserAction( - mojom::InitialBrowserAction::kOpenGuestWindow)); - if (result != MaybeStartResult::kRunning) - return; - - if (!browser_service_.has_value()) { - LOG(ERROR) << "BrowserService was disconnected"; - return; - } - - if (!NewFullscreenWindowSupported()) - return; - - browser_service_->service->NewGuestWindow(base::DoNothing()); + PerformOrEnqueue(BrowserAction::NewGuestWindow()); } void BrowserManager::NewTab(bool should_trigger_session_restore) { - auto result = MaybeStart(browser_util::InitialBrowserAction( - should_trigger_session_restore - ? mojom::InitialBrowserAction::kUseStartupPreference - : mojom::InitialBrowserAction::kOpenNewTabPageWindow)); - if (result != MaybeStartResult::kRunning) - return; - if (!browser_service_.has_value()) { - LOG(ERROR) << "BrowserService was disconnected"; - return; - } - browser_service_->service->NewTab(should_trigger_session_restore, - base::DoNothing()); + PerformOrEnqueue(BrowserAction::NewTab(should_trigger_session_restore)); } void BrowserManager::OpenUrl(const GURL& url, crosapi::mojom::OpenUrlFrom from) { - OpenUrlImpl( + PerformOrEnqueue(BrowserAction::OpenUrl( url, crosapi::mojom::OpenUrlParams::WindowOpenDisposition::kNewForegroundTab, - from, NavigateParams::RESPECT); + from, NavigateParams::RESPECT)); } void BrowserManager::SwitchToTab(const GURL& url, NavigateParams::PathBehavior path_behavior) { - OpenUrlImpl( + PerformOrEnqueue(BrowserAction::OpenUrl( url, crosapi::mojom::OpenUrlParams::WindowOpenDisposition::kSwitchToTab, - crosapi::mojom::OpenUrlFrom::kUnspecified, path_behavior); + crosapi::mojom::OpenUrlFrom::kUnspecified, path_behavior)); } void BrowserManager::RestoreTab() { - auto result = MaybeStart(browser_util::InitialBrowserAction( - mojom::InitialBrowserAction::kRestoreLastSession)); - if (result != MaybeStartResult::kRunning) - return; - - if (!browser_service_.has_value()) { - LOG(ERROR) << "BrowserService was disconnected"; - return; - } - browser_service_->service->RestoreTab(base::DoNothing()); -} - -bool BrowserManager::HandleTabScrubbingSupported() const { - return browser_service_.has_value() && - browser_service_->interface_version >= - crosapi::mojom::BrowserService::kHandleTabScrubbingMinVersion; + PerformOrEnqueue(BrowserAction::RestoreTab()); } void BrowserManager::HandleTabScrubbing(float x_offset) { - // If Lacros isn't running, bail out. - if (!IsRunning()) - return; - - if (!browser_service_.has_value()) - return; - - if (!HandleTabScrubbingSupported()) - return; - - browser_service_->service->HandleTabScrubbing(x_offset); + PerformOrEnqueue(BrowserAction::HandleTabScrubbing(x_offset)); } void BrowserManager::CreateBrowserWithRestoredData( const std::vector<GURL>& urls, const gfx::Rect& bounds, - const ui::WindowShowState show_state, + ui::WindowShowState show_state, int32_t active_tab_index, const std::string& app_name, int32_t restore_window_id) { - auto result = MaybeStart(browser_util::InitialBrowserAction( - mojom::InitialBrowserAction::kDoNotOpenWindow)); - // The service will not be available, return immediately. - if (result == MaybeStartResult::kNotStarted) - return; - - windows_to_restore_.emplace_back(urls, bounds, show_state, active_tab_index, - app_name, restore_window_id); - if (result == MaybeStartResult::kRunning) - RestoreWindowsFromTemplate(); + PerformOrEnqueue(BrowserAction::CreateBrowserWithRestoredData( + urls, bounds, show_state, active_tab_index, app_name, restore_window_id)); } -void BrowserManager::InitializeAndStart() { +void BrowserManager::InitializeAndStartIfNeeded() { DCHECK_EQ(state_, State::NOT_INITIALIZED); // Ensure this isn't run multiple times. @@ -768,11 +563,19 @@ // Must be checked after user session start because it depends on user type. if (is_lacros_enabled) { + // Start Lacros automatically on login, if + // 1) Lacros was opened in the previous session; or + // 2) Lacros is the primary web browser. + // This can be suppressed via commandline flag for testing. + if (GetLaunchOnLoginPref() || (browser_util::IsLacrosPrimaryBrowser() && + !IsLoginLacrosOpeningDisabledForTesting())) { + pending_actions_.Push(BrowserAction::GetActionForSessionStart()); + } + component_update_observation_.Observe(component_update_service_); SetState(State::MOUNTING); browser_loader_->Load(base::BindOnce(&BrowserManager::OnLoadComplete, - weak_factory_.GetWeakPtr(), - GetInitialBrowserAction())); + weak_factory_.GetWeakPtr())); } else { SetState(State::UNAVAILABLE); browser_loader_->Unload(); @@ -843,26 +646,22 @@ // `shutdown_requested_` has been set. UpdateKeepAliveInBrowserIfNecessary(false); shutdown_requested_ = true; + pending_actions_.Clear(); // The lacros-chrome process may have already been terminated as the result of - // a previous mojo pipe disconnection in `OnMojoDisconnected()` and has not - // yet been restarted. Ensure the lacros process is still valid before - // proceeding. - if (!lacros_process_.IsValid()) - return; + // a previous mojo pipe disconnection in `OnMojoDisconnected()` and not yet + // restarted. If, on the other hand, it is still valid, terminate it now. + if (lacros_process_.IsValid()) { + LOG(WARNING) << "Ash-chrome shutdown initiated. Terminating lacros-chrome"; + lacros_process_.Terminate(/*exit_code=*/0, /*wait=*/false); - // Signal the lacros process to terminate. We then immediately call into - // HandleLacrosChromeTermination() to synchronously post a shutdown blocking - // task that waits for lacros-chrome to cleanly exit. Terminate() will - // eventually result in a callback into OnMojoDisconnected(), however this - // resolves asynchronously and there is a risk that ash exits before this is - // called. - LOG(WARNING) << "Ash-chrome shutdown initiated. Terminating lacros-chrome"; - lacros_process_.Terminate(/*exit_code=*/0, /*wait=*/false); - - // Wait 3s for lacros-chrome to terminate to align with the timeout set by - // session_manager. - HandleLacrosChromeTermination(base::Seconds(3)); + // Synchronously post a shutdown blocking task that waits for lacros-chrome + // to cleanly exit. Terminate() will eventually result in a callback into + // OnMojoDisconnected(), however this resolves asynchronously and there is a + // risk that ash exits before this is called. The 3s timeout aligns with the + // timeout set by session_manager. + HandleLacrosChromeTermination(base::Seconds(3)); + } } void BrowserManager::SetState(State state) { @@ -876,8 +675,6 @@ } observer.OnStateChanged(); } - - LaunchForKeepAliveIfNecessary(); } BrowserManager::ScopedKeepAlive::~ScopedKeepAlive() { @@ -911,88 +708,23 @@ default; BrowserManager::BrowserServiceInfo::~BrowserServiceInfo() = default; -BrowserManager::MaybeStartResult BrowserManager::MaybeStart( - browser_util::InitialBrowserAction initial_browser_action) { - if (!browser_util::IsLacrosEnabled()) - return MaybeStartResult::kNotStarted; - - if (disable_autolaunch_for_testing_) - return MaybeStartResult::kNotStarted; - - if (!browser_util::IsLacrosAllowedToLaunch()) { - std::unique_ptr<message_center::Notification> notification = - ash::CreateSystemNotification( - message_center::NOTIFICATION_TYPE_SIMPLE, - kLacrosCannotLaunchNotificationID, - /*title=*/std::u16string(), - l10n_util::GetStringUTF16( - IDS_LACROS_CANNOT_LAUNCH_MULTI_SIGNIN_MESSAGE), - /* display_source= */ std::u16string(), GURL(), - message_center::NotifierId( - message_center::NotifierType::SYSTEM_COMPONENT, - kLacrosLauncherNotifierID, - ash::NotificationCatalogName::kLacrosCannotLaunch), - message_center::RichNotificationData(), - base::MakeRefCounted< - message_center::HandleNotificationClickDelegate>( - base::RepeatingClosure()), - gfx::kNoneIcon, - message_center::SystemNotificationWarningLevel::NORMAL); - - SystemNotificationHelper::GetInstance()->Display(*notification); - return MaybeStartResult::kNotStarted; - } - - if (!IsReady()) { - LOG(WARNING) << "lacros component image not yet available"; - return MaybeStartResult::kNotStarted; - } +void BrowserManager::Start() { + DCHECK_EQ(state_, State::STOPPED); + DCHECK(!shutdown_requested_); DCHECK(!lacros_path_.empty()); DCHECK(lacros_selection_.has_value()); - if (shutdown_requested_) { - LOG(WARNING) << "lacros-chrome is preparing for system shutdown"; - return MaybeStartResult::kNotStarted; + if (update_available_) { + update_available_ = false; + SetState(State::MOUNTING); + lacros_path_ = base::FilePath(); + lacros_selection_ = absl::nullopt; + // OnLoadComplete will call Start again. + browser_loader_->Load(base::BindOnce(&BrowserManager::OnLoadComplete, + weak_factory_.GetWeakPtr())); + return; } - if (state_ == State::TERMINATING) { - LOG(WARNING) << "lacros-chrome is terminating, so cannot start now"; - return MaybeStartResult::kNotStarted; - } - - if (state_ == State::CREATING_LOG_FILE || state_ == State::STARTING) { - LOG(WARNING) << "lacros-chrome is in the process of launching"; - return MaybeStartResult::kStarting; - } - - // If lacros-chrome is not running, launch it. - if (state_ == State::STOPPED) { - // If an update is available, load the most up-to-date installed version and - // let the load complete callback start the browser. - if (update_available_) { - update_available_ = false; - - SetState(State::MOUNTING); - lacros_path_ = base::FilePath(); - lacros_selection_ = absl::nullopt; - browser_loader_->Load(base::BindOnce(&BrowserManager::OnLoadComplete, - weak_factory_.GetWeakPtr(), - std::move(initial_browser_action))); - } else { - Start(std::move(initial_browser_action)); - } - return MaybeStartResult::kStarting; - } - - return MaybeStartResult::kRunning; -} - -void BrowserManager::Start( - browser_util::InitialBrowserAction initial_browser_action) { - DCHECK_EQ(state_, State::STOPPED); - DCHECK(!lacros_path_.empty()); - DCHECK(!shutdown_requested_); - // Ensure we're not trying to open a window before the shelf is initialized. // Kiosk sessions don't need this check because they don't enable the shelf. DCHECK(user_manager::UserManager::Get()->IsLoggedInAsAnyKioskApp() || @@ -1008,22 +740,18 @@ base::BindOnce(&DoLacrosBackgroundWorkPreLaunch, lacros_path_, is_initial_lacros_launch_after_reboot_), base::BindOnce(&BrowserManager::StartWithLogFile, - weak_factory_.GetWeakPtr(), - std::move(initial_browser_action))); + weak_factory_.GetWeakPtr())); // Set false to prepare for the next Lacros launch. is_initial_lacros_launch_after_reboot_ = false; } -void BrowserManager::StartWithLogFile( - browser_util::InitialBrowserAction initial_browser_action, - LaunchParamsFromBackground params) { +void BrowserManager::StartWithLogFile(LaunchParamsFromBackground params) { DCHECK_EQ(state_, State::CREATING_LOG_FILE); + // Shutdown() might have been called after Start() posted the StartWithLogFile + // task, so we need to check `shutdown_requested_` again. if (shutdown_requested_) { - // StartWithLogFile() may have been posted before Shutdown() has been - // signalled by the system. Ensure that we do not start lacros-chrome in - // this case. LOG(ERROR) << "Start attempted after Shutdown() called."; SetState(State::STOPPED); return; @@ -1142,7 +870,9 @@ } base::ScopedFD startup_fd = browser_util::CreateStartupData( - environment_provider_.get(), std::move(initial_browser_action), + environment_provider_.get(), + browser_util::InitialBrowserAction( + mojom::InitialBrowserAction::kDoNotOpenWindow), !keep_alive_features_.empty(), lacros_selection_); if (startup_fd.is_valid()) { // Hardcoded to use FD 3 to make the ash-chrome's behavior more predictable. @@ -1203,7 +933,8 @@ lacros_process_ = base::LaunchProcess(command_line, options); if (!lacros_process_.IsValid()) { LOG(ERROR) << "Failed to launch lacros-chrome"; - SetState(State::STOPPED); + // We give up, as this is most likely a permanent problem. + SetState(State::UNAVAILABLE); return; } SetState(State::STARTING); @@ -1243,9 +974,12 @@ // So, send it to lacros-chrome to update to fill the possible gap. UpdateKeepAliveInBrowserIfNecessary(!keep_alive_features_.empty()); - // We may have some windows pending to be restored from the desk template. - // Now is the time to create them. - RestoreWindowsFromTemplate(); + while (!pending_actions_.IsEmpty()) { + pending_actions_.Pop()->Perform( + {browser_service_.value().service, + browser_service_.value().interface_version}); + DCHECK_EQ(state_, State::RUNNING); + } } void BrowserManager::OnBrowserServiceDisconnected( @@ -1308,19 +1042,18 @@ void BrowserManager::OnLacrosChromeTerminated() { DCHECK_EQ(state_, State::TERMINATING); LOG(WARNING) << "Lacros-chrome is terminated"; + is_terminated_ = true; SetState(State::STOPPED); + // TODO(https://crbug.com/1109366): Restart lacros-chrome if it exits // abnormally (e.g. crashes). For now, assume the user meant to close it. // Relaunch lacros-chrome if it was closed due to ash shutting down. // Note that this only matters for side-by-side lacros. SetLaunchOnLoginPref(shutdown_requested_); - is_terminated_ = true; - - if (!shutdown_requested_ && relaunch_requested_) { - MaybeStart(browser_util::InitialBrowserAction( - mojom::InitialBrowserAction::kRestoreLastSession)); - } + if (relaunch_requested_) + pending_actions_.Push(BrowserAction::RestoreTab()); + StartIfNeeded(); } void BrowserManager::OnSessionStateChanged() { @@ -1333,7 +1066,32 @@ return; } - InitializeAndStart(); + // Launch Lacros if appropriate. + if (browser_util::IsLacrosEnabled()) { + if (!browser_util::IsLacrosAllowedToLaunch()) { + std::unique_ptr<message_center::Notification> notification = + ash::CreateSystemNotification( + message_center::NOTIFICATION_TYPE_SIMPLE, + kLacrosCannotLaunchNotificationID, + /*title=*/std::u16string(), + l10n_util::GetStringUTF16( + IDS_LACROS_CANNOT_LAUNCH_MULTI_SIGNIN_MESSAGE), + /* display_source= */ std::u16string(), GURL(), + message_center::NotifierId( + message_center::NotifierType::SYSTEM_COMPONENT, + kLacrosLauncherNotifierID, + ash::NotificationCatalogName::kLacrosCannotLaunch), + message_center::RichNotificationData(), + base::MakeRefCounted< + message_center::HandleNotificationClickDelegate>( + base::RepeatingClosure()), + gfx::kNoneIcon, + message_center::SystemNotificationWarningLevel::NORMAL); + SystemNotificationHelper::GetInstance()->Display(*notification); + } else { + InitializeAndStartIfNeeded(); + } + } // If "Go to files" on the migration error page was clicked, launch it here. Profile* profile = ProfileManager::GetPrimaryUserProfile(); @@ -1408,32 +1166,31 @@ } } -void BrowserManager::OnLoadComplete( - browser_util::InitialBrowserAction initial_browser_action, - const base::FilePath& path, - LacrosSelection selection) { +void BrowserManager::OnLoadComplete(const base::FilePath& path, + LacrosSelection selection) { + if (shutdown_requested_) { + LOG(ERROR) << "Load completed after Shutdown() called."; + return; + } DCHECK_EQ(state_, State::MOUNTING); lacros_path_ = path; lacros_selection_ = absl::optional<LacrosSelection>(selection); - SetState(path.empty() ? State::UNAVAILABLE : State::STOPPED); - + const bool success = !path.empty(); + SetState(success ? State::STOPPED : State::UNAVAILABLE); // TODO(crbug.com/1266010): In the event the load operation failed, we should // launch the last successfully loaded image. - const bool success = !path.empty(); for (auto& observer : observers_) { observer.OnLoadComplete(success); } - // Start Lacros browser automatically on login, if - // 1) Lacros was opened in the previous session. - // 2) Lacros is the primary web browser. - // This can be suppressed on commandline flag for testing. - if (state_ == State::STOPPED && !shutdown_requested_ && - (GetLaunchOnLoginPref() || (browser_util::IsLacrosPrimaryBrowser() && - !IsLoginLacrosOpeningDisabledForTesting()))) { - MaybeStart(std::move(initial_browser_action)); - } + StartIfNeeded(); +} + +void BrowserManager::StartIfNeeded() { + if (state_ == State::STOPPED && !shutdown_requested_) + if (!pending_actions_.IsEmpty() || IsKeepAliveEnabled()) + Start(); } void BrowserManager::PrepareLacrosPolicies() { @@ -1509,6 +1266,8 @@ LaunchParamsFromBackground::~LaunchParamsFromBackground() = default; void BrowserManager::StartKeepAlive(Feature feature) { + DCHECK(browser_util::IsLacrosEnabled()); + if (IsKeepAliveDisabledForTesting()) return; @@ -1517,16 +1276,14 @@ keep_alive_features_.insert(feature); // If this is first KeepAlive instance, update the keep-alive in the browser. - if (keep_alive_features_.size() == 1) { - // If browser is not running, we have to launch it. - LaunchForKeepAliveIfNecessary(); + if (keep_alive_features_.size() == 1) UpdateKeepAliveInBrowserIfNecessary(true); - } + StartIfNeeded(); } void BrowserManager::StopKeepAlive(Feature feature) { keep_alive_features_.erase(feature); - if (keep_alive_features_.empty()) + if (!IsKeepAliveEnabled()) UpdateKeepAliveInBrowserIfNecessary(false); } @@ -1534,18 +1291,6 @@ return !keep_alive_features_.empty(); } -void BrowserManager::LaunchForKeepAliveIfNecessary() { - // KeepAlive should not start lacros in a windowless state if a relaunch has - // been requested. Lacros restart will instead be handled in - // `OnLacrosChromeTerminated()`. - if (state_ == State::STOPPED && !shutdown_requested_ && - !keep_alive_features_.empty() && !relaunch_requested_) { - CHECK(browser_util::IsLacrosEnabled()); - MaybeStart(browser_util::InitialBrowserAction( - mojom::InitialBrowserAction::kDoNotOpenWindow)); - } -} - void BrowserManager::UpdateKeepAliveInBrowserIfNecessary(bool enabled) { if (shutdown_requested_ || !browser_service_.has_value() || browser_service_->interface_version < @@ -1557,11 +1302,6 @@ browser_service_->service->UpdateKeepAlive(enabled); } -bool BrowserManager::IsReady() const { - return state_ != State::NOT_INITIALIZED && state_ != State::MOUNTING && - state_ != State::UNAVAILABLE; -} - void BrowserManager::RecordLacrosLaunchMode() { LacrosLaunchMode lacros_mode; LacrosLaunchModeAndSource lacros_mode_and_source; @@ -1620,60 +1360,51 @@ lacros_mode_and_source); } -void BrowserManager::OpenUrlImpl( - const GURL& url, - crosapi::mojom::OpenUrlParams::WindowOpenDisposition disposition, - crosapi::mojom::OpenUrlFrom from, - NavigateParams::PathBehavior path_behavior) { - auto result = MaybeStart(browser_util::InitialBrowserAction( - mojom::InitialBrowserAction::kOpenWindowWithUrls, {url}, from)); - if (result != MaybeStartResult::kRunning) - return; - - if (!browser_service_.has_value()) { - LOG(ERROR) << "BrowserService was disconnected"; - return; - } - if (browser_service_->interface_version < - mojom::BrowserService::kOpenUrlMinVersion) { - LOG(ERROR) << "BrowserService does not support OpenUrl"; +void BrowserManager::PerformOrEnqueue(std::unique_ptr<BrowserAction> action) { + if (shutdown_requested_) { + LOG(WARNING) << "lacros-chrome is preparing for system shutdown"; + action->Cancel(mojom::CreationResult::kBrowserNotRunning); return; } - using OpenUrlParams = crosapi::mojom::OpenUrlParams; - auto params = OpenUrlParams::New(); - params->disposition = disposition; - params->from = from; - params->path_behavior = ConvertPathBehavior(path_behavior); - browser_service_->service->OpenUrl(url, std::move(params), base::DoNothing()); -} + switch (state_) { + case State::UNAVAILABLE: + LOG(ERROR) << "lacros unavailable"; + action->Cancel(mojom::CreationResult::kBrowserNotRunning); + return; -bool BrowserManager::IsNewGuestWindowSupported() const { - return browser_service_.has_value() && - browser_service_->interface_version >= - crosapi::mojom::BrowserService::kNewGuestWindowMinVersion; -} + case State::NOT_INITIALIZED: + case State::MOUNTING: + LOG(WARNING) << "lacros component image not yet available"; + pending_actions_.PushOrCancel(std::move(action)); + return; + case State::TERMINATING: + LOG(WARNING) << "lacros-chrome is terminating, so cannot start now"; + pending_actions_.PushOrCancel(std::move(action)); + return; + case State::CREATING_LOG_FILE: + case State::STARTING: + LOG(WARNING) << "lacros-chrome is in the process of launching"; + pending_actions_.PushOrCancel(std::move(action)); + return; -void BrowserManager::RestoreWindowsFromTemplate() { - if (!browser_service_.has_value()) { - LOG(ERROR) << "BrowserService was disconnected"; - return; + case State::STOPPED: + DCHECK(!IsKeepAliveEnabled()); + DCHECK(pending_actions_.IsEmpty()); + pending_actions_.PushOrCancel(std::move(action)); + StartIfNeeded(); + return; + + case State::RUNNING: + if (!browser_service_.has_value()) { + LOG(ERROR) << "BrowserService was disconnected"; + action->Cancel(mojom::CreationResult::kServiceDisconnected); + return; + } + action->Perform( + {browser_service_->service, browser_service_->interface_version}); + return; } - - for (const auto& data : windows_to_restore_) { - crosapi::mojom::DeskTemplateStatePtr additional_state = - crosapi::mojom::DeskTemplateState::New(data.urls, data.active_tab_index, - data.app_name, - data.restore_window_id); - crosapi::CrosapiManager::Get() - ->crosapi_ash() - ->desk_template_ash() - ->CreateBrowserWithRestoredData(data.bounds, - ConvertWindowShowState(data.show_state), - std::move(additional_state)); - } - - windows_to_restore_.clear(); } } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/browser_manager.h b/chrome/browser/ash/crosapi/browser_manager.h index 980f57a..2a530fd8 100644 --- a/chrome/browser/ash/crosapi/browser_manager.h +++ b/chrome/browser/ash/crosapi/browser_manager.h
@@ -18,6 +18,7 @@ #include "base/process/process.h" #include "base/scoped_observation.h" #include "base/time/time.h" +#include "chrome/browser/ash/crosapi/browser_action.h" #include "chrome/browser/ash/crosapi/browser_manager_observer.h" #include "chrome/browser/ash/crosapi/browser_service_host_observer.h" #include "chrome/browser/ash/crosapi/browser_util.h" @@ -61,6 +62,7 @@ } namespace crosapi { + namespace mojom { class Crosapi; } // namespace mojom @@ -112,16 +114,9 @@ // Returns true if Lacros is terminated. bool IsTerminated() const { return is_terminated_; } - // Tests will typically manually launch Lacros. As such it should not be - // automatically launched. - void DisableAutoLaunchForTesting(); - // Opens the browser window in lacros-chrome. - // If lacros-chrome is not yet launched, it triggers to launch. If this is - // called again during the setup phase of the launch process, it will be - // ignored. This needs to be called after loading. The condition can be - // checked IsReady(), and if not yet, SetLoadCompletionCallback can be used to - // wait for the loading. + // If lacros-chrome is not yet launched, it triggers to launch. + // This needs to be called after loading. // TODO(crbug.com/1101676): Notify callers the result of opening window // request. Because of asynchronous operations crossing processes, // there's no guarantee that the opening window request succeeds. @@ -191,9 +186,6 @@ // See crosapi::mojom::BrowserService::RestoreTab for more details void RestoreTab(); - // Returns true if crosapi interface supports HandleTabScrubbing API. - bool HandleTabScrubbingSupported() const; - // Triggers tab switching in Lacros via horizontal 3-finger swipes. // // |x_offset| is in DIP coordinates. @@ -217,7 +209,7 @@ // - For Kiosk sessions, Lacros needs to be started earlier because all // extensions and browser window should be well prepared before the user // enters the session. This method should be called at the appropriate time. - void InitializeAndStart(); + void InitializeAndStartIfNeeded(); // Returns true if keep-alive is enabled. bool IsKeepAliveEnabled() const; @@ -333,8 +325,43 @@ void SetState(State state); // Posts CreateLogFile() and StartWithLogFile() to the thread pool. + // Also takes care of loading an update first, if available. // Virtual for tests. - virtual void Start(browser_util::InitialBrowserAction initial_browser_action); + virtual void Start(); + + // BrowserServiceHostObserver: + void OnBrowserServiceConnected(CrosapiId id, + mojo::RemoteSetElementId mojo_id, + mojom::BrowserService* browser_service, + uint32_t browser_service_version) override; + void OnBrowserServiceDisconnected(CrosapiId id, + mojo::RemoteSetElementId mojo_id) override; + + // Called when lacros-chrome is terminated and successfully wait(2)ed. + void OnLacrosChromeTerminated(); + + // ID for the current Crosapi connection. + // Available only when lacros-chrome is running. + absl::optional<CrosapiId> crosapi_id_; + + // Proxy to BrowserService mojo service in lacros-chrome. + // Available only when lacros-chrome is running. + struct BrowserServiceInfo { + BrowserServiceInfo(mojo::RemoteSetElementId mojo_id, + mojom::BrowserService* service, + uint32_t interface_version); + BrowserServiceInfo(const BrowserServiceInfo&); + BrowserServiceInfo& operator=(const BrowserServiceInfo&); + ~BrowserServiceInfo(); + + // ID managed in BrowserServiceHostAsh, which is tied to the |service|. + mojo::RemoteSetElementId mojo_id; + // BrowserService proxy connected to lacros-chrome. + mojom::BrowserService* service; + // Supported interface version of the BrowserService in Lacros-chrome. + uint32_t interface_version; + }; + absl::optional<BrowserServiceInfo> browser_service_; private: FRIEND_TEST_ALL_PREFIXES(BrowserManagerTest, LacrosKeepAlive); @@ -359,34 +386,15 @@ // Only for exposing state_ to Tast tests. friend class extensions::AutotestPrivateGetLacrosInfoFunction; - // Holds the data for restoring a window from the desk template. - // The request to restore a window may come when the browser service is not - // yet started. In such case we cache the requests until the service is up. - struct RestoreFromDeskTemplate { - RestoreFromDeskTemplate(const std::vector<GURL>& urls, - const gfx::Rect& bounds, - ui::WindowShowState show_state, - int32_t active_tab_index, - const std::string& app_name, - int32_t restore_window_id); - RestoreFromDeskTemplate(const RestoreFromDeskTemplate&) = delete; - RestoreFromDeskTemplate& operator=(const RestoreFromDeskTemplate&) = delete; - RestoreFromDeskTemplate(RestoreFromDeskTemplate&&); - ~RestoreFromDeskTemplate(); + // Processes the action depending on the current state. + // Ignoring a few exceptional cases, the logic is as follows: + // - If Lacros is ready, the action is performed. + // - If Lacros is not ready and the action is queueable, the action is queued + // (and Lacros started if necessary). + // - Otherwise, the action is cancelled. + void PerformOrEnqueue(std::unique_ptr<BrowserAction> action); - std::vector<GURL> urls; - gfx::Rect bounds; - ui::WindowShowState show_state; - int32_t active_tab_index; - // An non-empty |app_name| indicates that it's an app type browser window. - std::string app_name; - int32_t restore_window_id; - }; - - // Returns true if the binary is ready to launch or already launched. - bool IsReady() const; - - // Remember the launch mode of Lacros. + // Remembers the launch mode of Lacros. void RecordLacrosLaunchMode(); // These ash features are allowed to request that Lacros stay running in the @@ -419,50 +427,13 @@ // marked as friends of this class so that lacros owners can audit usage. std::unique_ptr<ScopedKeepAlive> KeepAlive(Feature feature); - struct BrowserServiceInfo { - BrowserServiceInfo(mojo::RemoteSetElementId mojo_id, - mojom::BrowserService* service, - uint32_t interface_version); - BrowserServiceInfo(const BrowserServiceInfo&); - BrowserServiceInfo& operator=(const BrowserServiceInfo&); - ~BrowserServiceInfo(); - - // ID managed in BrowserServiceHostAsh, which is tied to the |service|. - mojo::RemoteSetElementId mojo_id; - // BrowserService proxy connected to lacros-chrome. - mojom::BrowserService* service; - // Supported interface version of the BrowserService in Lacros-chrome. - uint32_t interface_version; - }; - - enum class MaybeStartResult { - kNotStarted, - kStarting, - kRunning, - }; - // Checks the precondition to start Lacros, and actually trigger to start - // if necessary. - // If the condition to start lacros is not met, kNotStarted is returned. - // If the condition to start lacros is met, and it is not yet started, - // or it is under starting, kStarting is returned. - // Otherwise, i.e., lacros is already running, kRunning is returned. - // |extra_args| will be passed to the argument to launch lacros. - MaybeStartResult MaybeStart( - browser_util::InitialBrowserAction initial_browser_action); + void StartIfNeeded(); // Starts the lacros-chrome process and redirects stdout/err to file pointed - // by logfd. - void StartWithLogFile( - browser_util::InitialBrowserAction initial_browser_action, - LaunchParamsFromBackground params); + // by |params.logfd|. + void StartWithLogFile(LaunchParamsFromBackground params); // BrowserServiceHostObserver: - void OnBrowserServiceConnected(CrosapiId id, - mojo::RemoteSetElementId mojo_id, - mojom::BrowserService* browser_service, - uint32_t browser_service_version) override; - void OnBrowserServiceDisconnected(CrosapiId id, - mojo::RemoteSetElementId mojo_id) override; void OnBrowserRelaunchRequested(CrosapiId id) override; // CloudPolicyCore::Observer: @@ -486,9 +457,6 @@ // killing the process. void HandleLacrosChromeTermination(base::TimeDelta timeout); - // Called when lacros-chrome is terminated and successfully wait(2)ed. - void OnLacrosChromeTerminated(); - // session_manager::SessionManagerObserver: void OnSessionStateChanged() override; @@ -520,19 +488,13 @@ void OnEvent(Events event, const std::string& id) override; // crosapi::BrowserManagerObserver: - void OnLoadComplete(browser_util::InitialBrowserAction initial_browser_action, - const base::FilePath& path, - LacrosSelection selection); + void OnLoadComplete(const base::FilePath& path, LacrosSelection selection); // Methods for features to register and de-register for needing to keep Lacros // alive. void StartKeepAlive(Feature feature); void StopKeepAlive(Feature feature); - // The implementation of keep-alive is simple: every time state_ becomes - // STOPPED, launch Lacros. - void LaunchForKeepAliveIfNecessary(); - // Notifies browser to update its keep-alive status. // Disabling keep-alive here may shut down the browser in background. // (i.e., if there's no browser window opened, it may be shut down). @@ -565,7 +527,7 @@ base::FilePath lacros_path_; // Whether we are starting "rootfs" or "stateful" lacros. - absl::optional<LacrosSelection> lacros_selection_ = absl::nullopt; + absl::optional<LacrosSelection> lacros_selection_; // Version of the browser (e.g. lacros-chrome) displayed to user in feedback // report, etc. It includes both browser version and channel in the format of: @@ -579,14 +541,6 @@ // Process handle for the lacros-chrome process. base::Process lacros_process_; - // ID for the current Crosapi connection. - // Available only when lacros-chrome is running. - absl::optional<CrosapiId> crosapi_id_; - - // Proxy to BrowserService mojo service in lacros-chrome. - // Available during lacros-chrome is running. - absl::optional<BrowserServiceInfo> browser_service_; - // Remembers the request from Lacros-chrome whether it needs to be // relaunched. Reset on new process start in any cases. bool relaunch_requested_ = false; @@ -630,9 +584,8 @@ // error screen. std::unique_ptr<FilesAppLauncher> files_app_launcher_; - // Takes data when `CreateBrowserWithRestoredData()` is called. Flushed by - // `RestoreWindowsFromTemplate()`. - std::vector<RestoreFromDeskTemplate> windows_to_restore_; + // The queue of actions to be performed when Lacros becomes ready. + BrowserActionQueue pending_actions_; base::WeakPtrFactory<BrowserManager> weak_factory_{this}; };
diff --git a/chrome/browser/ash/crosapi/browser_manager_unittest.cc b/chrome/browser/ash/crosapi/browser_manager_unittest.cc index 4972521..0685bc3d 100644 --- a/chrome/browser/ash/crosapi/browser_manager_unittest.cc +++ b/chrome/browser/ash/crosapi/browser_manager_unittest.cc
@@ -5,16 +5,21 @@ #include "chrome/browser/ash/crosapi/browser_manager.h" #include "ash/constants/ash_features.h" +#include "ash/public/cpp/shelf_model.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/ash/crosapi/browser_loader.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/component_updater/fake_cros_component_manager.h" +#include "chrome/browser/lacros/browser_service_lacros.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h" #include "chrome/test/base/scoped_testing_local_state.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" +#include "chromeos/crosapi/mojom/crosapi.mojom-test-utils.h" +#include "chromeos/crosapi/mojom/crosapi.mojom.h" #include "components/account_id/account_id.h" #include "components/component_updater/mock_component_updater_service.h" #include "components/session_manager/core/session_manager.h" @@ -36,35 +41,60 @@ constexpr char kSampleLacrosPath[] = "/run/imageloader-lacros-dogfood-dev/97.0.4676/"; +class MockBrowserService : public mojom::BrowserServiceInterceptorForTesting { + public: + BrowserService* GetForwardingInterface() override { + NOTREACHED(); + return nullptr; + } + + MOCK_METHOD(void, + NewWindow, + (bool incognito, + bool should_trigger_session_restore, + NewWindowCallback callback), + (override)); + MOCK_METHOD(void, RestoreTab, (RestoreTabCallback callback), (override)); + MOCK_METHOD(void, UpdateKeepAlive, (bool enabled), (override)); +}; + class BrowserManagerFake : public BrowserManager { public: BrowserManagerFake(std::unique_ptr<BrowserLoader> browser_loader, component_updater::ComponentUpdateService* update_service) : BrowserManager(std::move(browser_loader), update_service) {} + ~BrowserManagerFake() override = default; // BrowserManager: - void Start( - browser_util::InitialBrowserAction initial_browser_action) override { + void Start() override { ++start_count_; - initial_browser_action_ = initial_browser_action.action; - SetState(State::STARTING); + BrowserManager::Start(); } int start_count() const { return start_count_; } - mojom::InitialBrowserAction initial_browser_action() const { - return initial_browser_action_; + void SetStatePublic(State state) { SetState(state); } + + void SimulateLacrosTermination() { + SetStatePublic(State::TERMINATING); + if (browser_service_.has_value()) + OnBrowserServiceDisconnected(*crosapi_id_, browser_service_->mojo_id); + OnLacrosChromeTerminated(); } - void SetStatePublic(State state) { SetState(state); } + void SimulateLacrosStart(mojom::BrowserService* browser_service) { + crosapi_id_ = CrosapiId::FromUnsafeValue(42); // Dummy value. + SetStatePublic(State::STARTING); + OnBrowserServiceConnected(*crosapi_id_, + mojo::RemoteSetElementId::FromUnsafeValue(42), + browser_service, 42); + } // Make the State enum publicly available. using BrowserManager::State; - private: int start_count_ = 0; - mojom::InitialBrowserAction initial_browser_action_; }; } // namespace @@ -105,6 +135,14 @@ std::make_unique<testing::NiceMock<MockComponentUpdateService>>(); fake_browser_manager_ = std::make_unique<BrowserManagerFake>( std::move(browser_loader), component_update_service_.get()); + + shelf_model_ = std::make_unique<ash::ShelfModel>(); + shelf_controller_ = std::make_unique<ChromeShelfController>( + &testing_profile_, shelf_model_.get(), /*shelf_item_factory=*/nullptr); + shelf_controller_->Init(); + + EXPECT_CALL(mock_browser_service_, NewWindow(_, _, _)).Times(0); + EXPECT_CALL(mock_browser_service_, RestoreTab(_)).Times(0); } void AddRegularUser(const std::string& email) { @@ -130,6 +168,9 @@ std::unique_ptr<MockComponentUpdateService> component_update_service_; std::unique_ptr<BrowserManagerFake> fake_browser_manager_; ScopedTestingLocalState local_state_; + std::unique_ptr<ash::ShelfModel> shelf_model_; + std::unique_ptr<ChromeShelfController> shelf_controller_; + MockBrowserService mock_browser_service_; private: base::test::ScopedFeatureList feature_list_; @@ -156,7 +197,7 @@ std::move(callback).Run(base::FilePath("/run/lacros"), browser_util::LacrosSelection::kRootfs); }); - fake_browser_manager_->InitializeAndStart(); + fake_browser_manager_->InitializeAndStartIfNeeded(); EXPECT_EQ(fake_browser_manager_->start_count(), 0); fake_browser_manager_->SetStatePublic(State::UNAVAILABLE); @@ -167,17 +208,17 @@ fake_browser_manager_->KeepAlive(BrowserManager::Feature::kTestOnly); EXPECT_EQ(fake_browser_manager_->start_count(), 0); - // Once the state becomes STOPPED, then Lacros should start. - fake_browser_manager_->SetStatePublic(State::STOPPED); + // On termination, KeepAlive should start Lacros. + fake_browser_manager_->SimulateLacrosTermination(); EXPECT_EQ(fake_browser_manager_->start_count(), 1); // Repeating the process starts Lacros again. - fake_browser_manager_->SetStatePublic(State::STOPPED); + fake_browser_manager_->SimulateLacrosTermination(); EXPECT_EQ(fake_browser_manager_->start_count(), 2); // Once the ScopedKeepAlive is destroyed, this should no longer happen. keep_alive.reset(); - fake_browser_manager_->SetStatePublic(State::STOPPED); + fake_browser_manager_->SimulateLacrosTermination(); EXPECT_EQ(fake_browser_manager_->start_count(), 2); } @@ -197,7 +238,7 @@ std::move(callback).Run(base::FilePath("/run/lacros"), browser_util::LacrosSelection::kRootfs); }); - fake_browser_manager_->InitializeAndStart(); + fake_browser_manager_->InitializeAndStartIfNeeded(); using State = BrowserManagerFake::State; EXPECT_EQ(fake_browser_manager_->start_count(), 0); @@ -222,10 +263,11 @@ browser_util::LacrosSelection::kStateful); }); - // Once the state becomes STOPPED, then Lacros should start. Since there is - // an update, it should first load the updated image. - fake_browser_manager_->SetStatePublic(State::STOPPED); - EXPECT_EQ(fake_browser_manager_->start_count(), 1); + // On simulated termination, KeepAlive restarts Lacros. Since there is an + // update, it should first load the updated image. + EXPECT_EQ(fake_browser_manager_->start_count(), 0); + fake_browser_manager_->SimulateLacrosTermination(); + EXPECT_GE(fake_browser_manager_->start_count(), 1); } TEST_F(BrowserManagerTest, NewWindowReloadsWhenUpdateAvailable) { @@ -244,7 +286,7 @@ std::move(callback).Run(base::FilePath("/run/lacros"), browser_util::LacrosSelection::kRootfs); }); - fake_browser_manager_->InitializeAndStart(); + fake_browser_manager_->InitializeAndStartIfNeeded(); // Set the state of the browser manager as stopped, which would match the // state after the browser mounted an image, ran, and was terminated. @@ -258,16 +300,20 @@ ->OnEvent(UpdateClient::Observer::Events::COMPONENT_UPDATED, lacros_component_id); - EXPECT_CALL(*browser_loader_, Load(_)) - .WillOnce([](BrowserLoader::LoadCompletionCallback callback) { - std::move(callback).Run(base::FilePath(kSampleLacrosPath), - browser_util::LacrosSelection::kStateful); - }); - fake_browser_manager_->NewWindow(/*incongnito=*/false, + EXPECT_EQ(fake_browser_manager_->start_count(), 0); + EXPECT_CALL(*browser_loader_, Load(_)); + EXPECT_CALL(mock_browser_service_, NewWindow(_, _, _)) + .Times(1) + .RetiresOnSaturation(); + fake_browser_manager_->NewWindow(/*incognito=*/false, /*should_trigger_session_restore=*/false); + EXPECT_EQ(fake_browser_manager_->start_count(), 1); + fake_browser_manager_->SimulateLacrosStart(&mock_browser_service_); } TEST_F(BrowserManagerTest, LacrosKeepAliveDoesNotBlockRestart) { + EXPECT_CALL(mock_browser_service_, UpdateKeepAlive(_)).Times(0); + AddRegularUser("user@test.com"); browser_util::SetProfileMigrationCompletedForUser( local_state_.Get(), @@ -288,7 +334,7 @@ std::move(callback).Run(base::FilePath("/run/lacros"), browser_util::LacrosSelection::kRootfs); }); - fake_browser_manager_->InitializeAndStart(); + fake_browser_manager_->InitializeAndStartIfNeeded(); EXPECT_EQ(fake_browser_manager_->start_count(), 0); fake_browser_manager_->SetStatePublic(State::UNAVAILABLE); @@ -301,37 +347,40 @@ // Simulate a Lacros termination, keep alive should launch Lacros in a // windowless state. - auto simulate_lacros_termination = [&]() { - fake_browser_manager_->SetStatePublic(State::TERMINATING); - fake_browser_manager_->OnLacrosChromeTerminated(); - }; - simulate_lacros_termination(); + fake_browser_manager_->SimulateLacrosTermination(); EXPECT_EQ(fake_browser_manager_->start_count(), 1); - EXPECT_EQ(fake_browser_manager_->initial_browser_action(), - mojom::InitialBrowserAction::kDoNotOpenWindow); + EXPECT_CALL(mock_browser_service_, UpdateKeepAlive(_)) + .Times(1) + .RetiresOnSaturation(); + fake_browser_manager_->SimulateLacrosStart(&mock_browser_service_); // Terminating again causes keep alive to again start Lacros in a windowless // state. - simulate_lacros_termination(); + fake_browser_manager_->SimulateLacrosTermination(); EXPECT_EQ(fake_browser_manager_->start_count(), 2); - EXPECT_EQ(fake_browser_manager_->initial_browser_action(), - mojom::InitialBrowserAction::kDoNotOpenWindow); + EXPECT_CALL(mock_browser_service_, UpdateKeepAlive(_)) + .Times(1) + .RetiresOnSaturation(); + fake_browser_manager_->SimulateLacrosStart(&mock_browser_service_); // Request a relaunch. Keep alive should not start Lacros in a windowless // state but Lacros should instead start with the kRestoreLastSession action. fake_browser_manager_->set_relaunch_requested_for_testing(true); - simulate_lacros_termination(); + fake_browser_manager_->SimulateLacrosTermination(); EXPECT_EQ(fake_browser_manager_->start_count(), 3); - EXPECT_EQ(fake_browser_manager_->initial_browser_action(), - mojom::InitialBrowserAction::kRestoreLastSession); + EXPECT_CALL(mock_browser_service_, UpdateKeepAlive(_)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(mock_browser_service_, RestoreTab(_)) + .Times(1) + .RetiresOnSaturation(); + fake_browser_manager_->SimulateLacrosStart(&mock_browser_service_); // Resetting the relaunch requested bit should cause keep alive to start // Lacros in a windowless state. fake_browser_manager_->set_relaunch_requested_for_testing(false); - simulate_lacros_termination(); + fake_browser_manager_->SimulateLacrosTermination(); EXPECT_EQ(fake_browser_manager_->start_count(), 4); - EXPECT_EQ(fake_browser_manager_->initial_browser_action(), - mojom::InitialBrowserAction::kDoNotOpenWindow); } } // namespace crosapi
diff --git a/chrome/browser/ash/file_manager/fake_disk_mount_manager.cc b/chrome/browser/ash/file_manager/fake_disk_mount_manager.cc index 8629d43..891da2de 100644 --- a/chrome/browser/ash/file_manager/fake_disk_mount_manager.cc +++ b/chrome/browser/ash/file_manager/fake_disk_mount_manager.cc
@@ -81,8 +81,7 @@ mount_requests_.emplace_back(source_path, source_format, mount_label, mount_options, type, access_mode); - const MountPointInfo mount_point(source_path, source_path, type, - ash::disks::MOUNT_CONDITION_NONE); + const MountPoint mount_point{source_path, source_path, type}; mount_points_.insert(make_pair(source_path, mount_point)); std::move(callback).Run(ash::MountError::kNone, mount_point); for (auto& observer : observers_) { @@ -105,7 +104,7 @@ if (iter == mount_points_.end()) return; - const MountPointInfo mount_point = iter->second; + const MountPoint mount_point = iter->second; mount_points_.erase(iter); for (auto& observer : observers_) { observer.OnMountEvent(DiskMountManager::UNMOUNTING, @@ -166,8 +165,7 @@ return disks_.insert(make_pair(disk->device_path(), std::move(disk))).second; } -bool FakeDiskMountManager::AddMountPointForTest( - const MountPointInfo& mount_point) { +bool FakeDiskMountManager::AddMountPointForTest(const MountPoint& mount_point) { if (mount_point.mount_type == ash::MountType::kDevice && disks_.find(mount_point.source_path) == disks_.end()) { // Device mount point must have a disk entry.
diff --git a/chrome/browser/ash/file_manager/fake_disk_mount_manager.h b/chrome/browser/ash/file_manager/fake_disk_mount_manager.h index 25a2e2f0..c6abef88 100644 --- a/chrome/browser/ash/file_manager/fake_disk_mount_manager.h +++ b/chrome/browser/ash/file_manager/fake_disk_mount_manager.h
@@ -105,7 +105,7 @@ UnmountDeviceRecursivelyCallbackType callback) override; bool AddDiskForTest(std::unique_ptr<ash::disks::Disk> disk) override; - bool AddMountPointForTest(const MountPointInfo& mount_point) override; + bool AddMountPointForTest(const MountPoint& mount_point) override; void InvokeDiskEventForTest(DiskEvent event, const ash::disks::Disk* disk); private:
diff --git a/chrome/browser/ash/file_manager/file_tasks.cc b/chrome/browser/ash/file_manager/file_tasks.cc index f99da98..6079338 100644 --- a/chrome/browser/ash/file_manager/file_tasks.cc +++ b/chrome/browser/ash/file_manager/file_tasks.cc
@@ -559,28 +559,20 @@ VLOG(1) << "Looking for default for MIME type: " << mime_type << " and suffix: " << suffix; if (!mime_type.empty()) { - const base::Value* mime_task_prefs = - pref_service.GetDictionary(prefs::kDefaultTasksByMimeType); - DCHECK(mime_task_prefs); - LOG_IF(ERROR, !mime_task_prefs) << "Unable to open MIME type prefs"; - if (mime_task_prefs) { - const std::string* task_id = mime_task_prefs->FindStringKey(mime_type); - if (task_id) { - VLOG(1) << "Found MIME default handler: " << *task_id; - return ParseTaskID(*task_id, task_out); - } + const base::Value::Dict& mime_task_prefs = + pref_service.GetValueDict(prefs::kDefaultTasksByMimeType); + const std::string* task_id = mime_task_prefs.FindString(mime_type); + if (task_id) { + VLOG(1) << "Found MIME default handler: " << *task_id; + return ParseTaskID(*task_id, task_out); } } - const base::Value* suffix_task_prefs = - pref_service.GetDictionary(prefs::kDefaultTasksBySuffix); - DCHECK(suffix_task_prefs); - LOG_IF(ERROR, !suffix_task_prefs) << "Unable to open suffix prefs"; + const base::Value::Dict& suffix_task_prefs = + pref_service.GetValueDict(prefs::kDefaultTasksBySuffix); std::string lower_suffix = base::ToLowerASCII(suffix); - if (!suffix_task_prefs) - return false; - const std::string* task_id = suffix_task_prefs->FindStringKey(lower_suffix); + const std::string* task_id = suffix_task_prefs.FindString(lower_suffix); if (!task_id || task_id->empty()) return false; @@ -659,7 +651,8 @@ if (IsFilesAppId(task.app_id) && (parsed_action_id == "upload-office-to-drive")) { - const bool opened = chromeos::cloud_upload::CloudUploadDialog::Show(); + const bool opened = + chromeos::cloud_upload::CloudUploadDialog::Show(file_urls); if (done) { if (opened) { std::move(done).Run(
diff --git a/chrome/browser/ash/file_manager/fusebox_mounter.h b/chrome/browser/ash/file_manager/fusebox_mounter.h index da3e0a7..d958a11 100644 --- a/chrome/browser/ash/file_manager/fusebox_mounter.h +++ b/chrome/browser/ash/file_manager/fusebox_mounter.h
@@ -16,7 +16,7 @@ using FuseBoxDiskMountManager = ::ash::disks::DiskMountManager; -using FuseBoxMountInfo = ::ash::disks::DiskMountManager::MountPointInfo; +using FuseBoxMountInfo = ::ash::disks::DiskMountManager::MountPoint; class FuseBoxMounter { public:
diff --git a/chrome/browser/ash/file_manager/path_util_unittest.cc b/chrome/browser/ash/file_manager/path_util_unittest.cc index 674861c7..651f9b5 100644 --- a/chrome/browser/ash/file_manager/path_util_unittest.cc +++ b/chrome/browser/ash/file_manager/path_util_unittest.cc
@@ -672,9 +672,8 @@ .Build())); ASSERT_TRUE( ash::disks::DiskMountManager::GetInstance()->AddMountPointForTest( - ash::disks::DiskMountManager::MountPointInfo( - "/device/source_path", "/media/removable/a", - ash::MountType::kDevice, ash::disks::MOUNT_CONDITION_NONE))); + {"/device/source_path", "/media/removable/a", + ash::MountType::kDevice})); // Add a Share Cache mount point for the primary profile. ASSERT_TRUE(mount_points->RegisterFileSystem(
diff --git a/chrome/browser/ash/file_manager/volume_manager.cc b/chrome/browser/ash/file_manager/volume_manager.cc index fa08406..56d915c 100644 --- a/chrome/browser/ash/file_manager/volume_manager.cc +++ b/chrome/browser/ash/file_manager/volume_manager.cc
@@ -316,7 +316,7 @@ // static std::unique_ptr<Volume> Volume::CreateForRemovable( - const ash::disks::DiskMountManager::MountPointInfo& mount_point, + const ash::disks::DiskMountManager::MountPoint& mount_point, const ash::disks::Disk* disk) { std::unique_ptr<Volume> volume(new Volume()); volume->type_ = MountTypeToVolumeType(mount_point.mount_type); @@ -1130,7 +1130,7 @@ void VolumeManager::OnMountEvent( ash::disks::DiskMountManager::MountEvent event, ash::MountError error_code, - const ash::disks::DiskMountManager::MountPointInfo& mount_info) { + const ash::disks::DiskMountManager::MountPoint& mount_info) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); // Network storage is responsible for doing its own mounting.
diff --git a/chrome/browser/ash/file_manager/volume_manager.h b/chrome/browser/ash/file_manager/volume_manager.h index 92999969..b9fc8c7 100644 --- a/chrome/browser/ash/file_manager/volume_manager.h +++ b/chrome/browser/ash/file_manager/volume_manager.h
@@ -106,7 +106,7 @@ static std::unique_ptr<Volume> CreateForDownloads( const base::FilePath& downloads_path); static std::unique_ptr<Volume> CreateForRemovable( - const ash::disks::DiskMountManager::MountPointInfo& mount_point, + const ash::disks::DiskMountManager::MountPoint& mount_point, const ash::disks::Disk* disk); static std::unique_ptr<Volume> CreateForProvidedFileSystem( const ash::file_system_provider::ProvidedFileSystemInfo& file_system_info, @@ -460,7 +460,7 @@ void OnMountEvent( ash::disks::DiskMountManager::MountEvent event, ash::MountError error_code, - const ash::disks::DiskMountManager::MountPointInfo& mount_info) override; + const ash::disks::DiskMountManager::MountPoint& mount_info) override; void OnFormatEvent(ash::disks::DiskMountManager::FormatEvent event, ash::FormatError error_code, const std::string& device_path,
diff --git a/chrome/browser/ash/file_manager/volume_manager_unittest.cc b/chrome/browser/ash/file_manager/volume_manager_unittest.cc index 3fc6d08..b7570ad 100644 --- a/chrome/browser/ash/file_manager/volume_manager_unittest.cc +++ b/chrome/browser/ash/file_manager/volume_manager_unittest.cc
@@ -694,9 +694,8 @@ LoggingObserver observer; volume_manager()->AddObserver(&observer); - const DiskMountManager::MountPointInfo kMountPoint( - "device1", "mount1", ash::MountType::kDevice, - ash::disks::MOUNT_CONDITION_NONE); + const DiskMountManager::MountPoint kMountPoint{"device1", "mount1", + ash::MountType::kDevice}; volume_manager()->OnMountEvent(DiskMountManager::MOUNTING, ash::MountError::kNone, kMountPoint); @@ -729,9 +728,8 @@ chromeos::MOUNT_ACCESS_MODE_READ_WRITE, base::DoNothing()); - const DiskMountManager::MountPointInfo kMountPoint( - "device1", "mount1", ash::MountType::kDevice, - ash::disks::MOUNT_CONDITION_NONE); + const DiskMountManager::MountPoint kMountPoint{"device1", "mount1", + ash::MountType::kDevice}; volume_manager()->OnMountEvent(DiskMountManager::MOUNTING, ash::MountError::kNone, kMountPoint); @@ -768,9 +766,8 @@ LoggingObserver observer; volume_manager()->AddObserver(&observer); - const DiskMountManager::MountPointInfo kMountPoint( - "device1", "mount1", ash::MountType::kDevice, - ash::disks::MOUNT_CONDITION_NONE); + const DiskMountManager::MountPoint kMountPoint{"device1", "mount1", + ash::MountType::kDevice}; volume_manager()->OnMountEvent(DiskMountManager::UNMOUNTING, ash::MountError::kNone, kMountPoint); @@ -1151,16 +1148,12 @@ // Mount a USB stick. volume_manager()->OnMountEvent( DiskMountManager::MOUNTING, ash::MountError::kNone, - DiskMountManager::MountPointInfo("/removable/usb", "/removable/usb", - ash::MountType::kDevice, - ash::disks::MOUNT_CONDITION_NONE)); + {"/removable/usb", "/removable/usb", ash::MountType::kDevice}); // Mount a zip archive in the stick. volume_manager()->OnMountEvent( DiskMountManager::MOUNTING, ash::MountError::kNone, - DiskMountManager::MountPointInfo("/removable/usb/1.zip", "/archive/1", - ash::MountType::kArchive, - ash::disks::MOUNT_CONDITION_NONE)); + {"/removable/usb/1.zip", "/archive/1", ash::MountType::kArchive}); base::WeakPtr<Volume> volume = volume_manager()->FindVolumeById("archive:1"); ASSERT_TRUE(volume.get()); EXPECT_EQ("/archive/1", volume->mount_path().AsUTF8Unsafe()); @@ -1169,9 +1162,7 @@ // Mount a zip archive in the previous zip archive. volume_manager()->OnMountEvent( DiskMountManager::MOUNTING, ash::MountError::kNone, - DiskMountManager::MountPointInfo("/archive/1/2.zip", "/archive/2", - ash::MountType::kArchive, - ash::disks::MOUNT_CONDITION_NONE)); + {"/archive/1/2.zip", "/archive/2", ash::MountType::kArchive}); base::WeakPtr<Volume> second_volume = volume_manager()->FindVolumeById("archive:2"); ASSERT_TRUE(second_volume.get()); @@ -1180,11 +1171,10 @@ // A zip file is mounted from other profile. It must be ignored in the current // VolumeManager. - volume_manager()->OnMountEvent( - DiskMountManager::MOUNTING, ash::MountError::kNone, - DiskMountManager::MountPointInfo("/other/profile/drive/folder/3.zip", - "/archive/3", ash::MountType::kArchive, - ash::disks::MOUNT_CONDITION_NONE)); + volume_manager()->OnMountEvent(DiskMountManager::MOUNTING, + ash::MountError::kNone, + {"/other/profile/drive/folder/3.zip", + "/archive/3", ash::MountType::kArchive}); base::WeakPtr<Volume> third_volume = volume_manager()->FindVolumeById("archive:3"); ASSERT_FALSE(third_volume.get());
diff --git a/chrome/browser/ash/input_method/assistive_suggester_client_filter.cc b/chrome/browser/ash/input_method/assistive_suggester_client_filter.cc index 27db0a6..ae69907 100644 --- a/chrome/browser/ash/input_method/assistive_suggester_client_filter.cc +++ b/chrome/browser/ash/input_method/assistive_suggester_client_filter.cc
@@ -163,7 +163,7 @@ } template <size_t N> -bool IsAllowedUrlWithPathPrefix(const char* (&allowedDomainAndPaths)[N][2], +bool IsMatchedUrlWithPathPrefix(const char* (&allowedDomainAndPaths)[N][2], GURL url) { if (IsTestUrl(url) || IsInternalWebsite(url)) return true; @@ -200,7 +200,7 @@ } template <size_t N> -bool IsAllowedApp(const char* (&allowedApps)[N]) { +bool IsMatchedApp(const char* (&allowedApps)[N]) { // WMHelper is not available in Chrome on Linux. if (!exo::WMHelper::HasInstance()) return false; @@ -227,17 +227,17 @@ bool IsAllowedUrlOrAppForPersonalInfoSuggestion() { return IsAllowedUrlLegacy(kAllowedDomainAndPathsForPersonalInfoSuggester) || - IsAllowedApp(kAllowedAppsForPersonalInfoSuggester); + IsMatchedApp(kAllowedAppsForPersonalInfoSuggester); } bool IsAllowedUrlOrAppForEmojiSuggestion() { return IsAllowedUrlLegacy(kAllowedDomainAndPathsForEmojiSuggester) || - IsAllowedApp(kAllowedAppsForEmojiSuggester); + IsMatchedApp(kAllowedAppsForEmojiSuggester); } bool IsAllowedUrlOrAppForMultiWordSuggestion() { return IsAllowedUrlLegacy(kAllowedDomainAndPathsForMultiWordSuggester) || - IsAllowedApp(kAllowedAppsForMultiWordSuggester); + IsMatchedApp(kAllowedAppsForMultiWordSuggester); } void ReturnEnabledSuggestions( @@ -248,20 +248,23 @@ return; } + // Allow-list (will only allow if matched) bool emoji_suggestions_allowed = - IsAllowedUrlWithPathPrefix(kAllowedDomainAndPathsForEmojiSuggester, + IsMatchedUrlWithPathPrefix(kAllowedDomainAndPathsForEmojiSuggester, *current_url) || - IsAllowedApp(kAllowedAppsForEmojiSuggester); + IsMatchedApp(kAllowedAppsForEmojiSuggester); + // Allow-list (will only allow if matched) bool multi_word_suggestions_allowed = - IsAllowedUrlWithPathPrefix(kAllowedDomainAndPathsForMultiWordSuggester, + IsMatchedUrlWithPathPrefix(kAllowedDomainAndPathsForMultiWordSuggester, *current_url) || - IsAllowedApp(kAllowedAppsForMultiWordSuggester); + IsMatchedApp(kAllowedAppsForMultiWordSuggester); + // Allow-list (will only allow if matched) bool personal_info_suggestions_allowed = - IsAllowedUrlWithPathPrefix(kAllowedDomainAndPathsForPersonalInfoSuggester, + IsMatchedUrlWithPathPrefix(kAllowedDomainAndPathsForPersonalInfoSuggester, *current_url) || - IsAllowedApp(kAllowedAppsForPersonalInfoSuggester); + IsMatchedApp(kAllowedAppsForPersonalInfoSuggester); std::move(callback).Run(AssistiveSuggesterSwitch::EnabledSuggestions{ .emoji_suggestions = emoji_suggestions_allowed,
diff --git a/chrome/browser/ash/input_method/assistive_suggester_prefs.cc b/chrome/browser/ash/input_method/assistive_suggester_prefs.cc index ebbaf57..6d94a8b 100644 --- a/chrome/browser/ash/input_method/assistive_suggester_prefs.cc +++ b/chrome/browser/ash/input_method/assistive_suggester_prefs.cc
@@ -13,10 +13,10 @@ bool IsPredictiveWritingPrefEnabled(PrefService* pref_service, const std::string& engine_id) { - const base::Value* input_method_settings = pref_service->GetDictionary( - ::prefs::kLanguageInputMethodSpecificSettings); + const base::Value::Dict& input_method_settings = + pref_service->GetValueDict(::prefs::kLanguageInputMethodSpecificSettings); absl::optional<bool> predictive_writing_setting = - input_method_settings->FindBoolPath( + input_method_settings.FindBoolByDottedPath( engine_id + ".physicalKeyboardEnablePredictiveWriting"); // If no preference has been set yet by the user then we can assume the // default preference as enabled.
diff --git a/chrome/browser/ash/input_method/input_method_engine.cc b/chrome/browser/ash/input_method/input_method_engine.cc index 65f5b1f9..d5ff71f2 100644 --- a/chrome/browser/ash/input_method/input_method_engine.cc +++ b/chrome/browser/ash/input_method/input_method_engine.cc
@@ -113,8 +113,8 @@ profile_observation_.Observe(profile); input_method_settings_snapshot_ = profile->GetPrefs() - ->GetDictionary(prefs::kLanguageInputMethodSpecificSettings) - ->Clone(); + ->GetValueDict(prefs::kLanguageInputMethodSpecificSettings) + .Clone(); pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>(); pref_change_registrar_->Init(profile->GetPrefs()); @@ -1097,21 +1097,19 @@ } void InputMethodEngine::OnInputMethodOptionsChanged() { - const base::Value* new_settings = profile_->GetPrefs()->GetDictionary( + const base::Value::Dict& new_settings = profile_->GetPrefs()->GetValueDict( prefs::kLanguageInputMethodSpecificSettings); - const base::DictionaryValue& old_settings = - base::Value::AsDictionaryValue(input_method_settings_snapshot_); - for (const auto it : new_settings->DictItems()) { - if (old_settings.FindKey(it.first)) { - if (*(old_settings.FindPath(it.first)) != - *(new_settings->FindPath(it.first))) { - observer_->OnInputMethodOptionsChanged(it.first); + const base::Value::Dict& old_settings = input_method_settings_snapshot_; + for (const auto&& [path, value] : new_settings) { + if (const base::Value* old_value = old_settings.Find(path)) { + if (*old_value != value) { + observer_->OnInputMethodOptionsChanged(path); } } else { - observer_->OnInputMethodOptionsChanged(it.first); + observer_->OnInputMethodOptionsChanged(path); } } - input_method_settings_snapshot_ = new_settings->Clone(); + input_method_settings_snapshot_ = new_settings.Clone(); } void InputMethodEngine::UpdateComposition(
diff --git a/chrome/browser/ash/input_method/input_method_engine.h b/chrome/browser/ash/input_method/input_method_engine.h index 76157b5..99efbe5a 100644 --- a/chrome/browser/ash/input_method/input_method_engine.h +++ b/chrome/browser/ash/input_method/input_method_engine.h
@@ -406,7 +406,7 @@ std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; - base::Value input_method_settings_snapshot_; + base::Value::Dict input_method_settings_snapshot_; base::ScopedObservation<Profile, ProfileObserver> profile_observation_{this}; };
diff --git a/chrome/browser/ash/input_method/input_method_settings.cc b/chrome/browser/ash/input_method/input_method_settings.cc index 8c796b4..74d6a3f 100644 --- a/chrome/browser/ash/input_method/input_method_settings.cc +++ b/chrome/browser/ash/input_method/input_method_settings.cc
@@ -94,7 +94,7 @@ } mojom::LatinSettingsPtr CreateLatinSettings( - const base::Value& input_method_specific_pref, + const base::Value::Dict& input_method_specific_pref, const PrefService& prefs, const std::string& engine_id) { auto settings = mojom::LatinSettings::New(); @@ -102,8 +102,7 @@ base::StartsWith(engine_id, "experimental_", base::CompareCase::SENSITIVE) || base::FeatureList::IsEnabled(features::kAutocorrectParamsTuning) || - input_method_specific_pref - .FindIntKey("physicalKeyboardAutoCorrectionLevel") + input_method_specific_pref.FindInt("physicalKeyboardAutoCorrectionLevel") .value_or(0) > 0; settings->predictive_writing = features::IsAssistiveMultiWordEnabled() && @@ -129,33 +128,33 @@ } mojom::KoreanSettingsPtr CreateKoreanSettings( - const base::Value& input_method_specific_pref) { + const base::Value::Dict& input_method_specific_pref) { auto settings = mojom::KoreanSettings::New(); settings->input_multiple_syllables = - !input_method_specific_pref.FindBoolKey("koreanEnableSyllableInput") + !input_method_specific_pref.FindBool("koreanEnableSyllableInput") .value_or(true); const std::string* prefs_layout = - input_method_specific_pref.FindStringKey("koreanKeyboardLayout"); + input_method_specific_pref.FindString("koreanKeyboardLayout"); settings->layout = prefs_layout ? KoreanLayoutToMojom(*prefs_layout) : mojom::KoreanLayout::kDubeolsik; return settings; } mojom::FuzzyPinyinSettingsPtr CreateFuzzyPinyinSettings( - const base::Value& pref) { + const base::Value::Dict& pref) { auto settings = mojom::FuzzyPinyinSettings::New(); - settings->an_ang = pref.FindBoolKey("an:ang").value_or(false); - settings->en_eng = pref.FindBoolKey("en:eng").value_or(false); - settings->ian_iang = pref.FindBoolKey("ian:iang").value_or(false); - settings->k_g = pref.FindBoolKey("k:g").value_or(false); - settings->r_l = pref.FindBoolKey("r:l").value_or(false); - settings->uan_uang = pref.FindBoolKey("uan:uang").value_or(false); - settings->c_ch = pref.FindBoolKey("c:ch").value_or(false); - settings->f_h = pref.FindBoolKey("f:h").value_or(false); - settings->in_ing = pref.FindBoolKey("in:ing").value_or(false); - settings->l_n = pref.FindBoolKey("l:n").value_or(false); - settings->s_sh = pref.FindBoolKey("s:sh").value_or(false); - settings->z_zh = pref.FindBoolKey("z:zh").value_or(false); + settings->an_ang = pref.FindBool("an:ang").value_or(false); + settings->en_eng = pref.FindBool("en:eng").value_or(false); + settings->ian_iang = pref.FindBool("ian:iang").value_or(false); + settings->k_g = pref.FindBool("k:g").value_or(false); + settings->r_l = pref.FindBool("r:l").value_or(false); + settings->uan_uang = pref.FindBool("uan:uang").value_or(false); + settings->c_ch = pref.FindBool("c:ch").value_or(false); + settings->f_h = pref.FindBool("f:h").value_or(false); + settings->in_ing = pref.FindBool("in:ing").value_or(false); + settings->l_n = pref.FindBool("l:n").value_or(false); + settings->s_sh = pref.FindBool("s:sh").value_or(false); + settings->z_zh = pref.FindBool("z:zh").value_or(false); return settings; } @@ -170,28 +169,28 @@ } mojom::PinyinSettingsPtr CreatePinyinSettings( - const base::Value& input_method_specific_pref) { + const base::Value::Dict& input_method_specific_pref) { auto settings = mojom::PinyinSettings::New(); settings->fuzzy_pinyin = CreateFuzzyPinyinSettings(input_method_specific_pref); const std::string* prefs_layout = - input_method_specific_pref.FindStringKey("xkbLayout"); + input_method_specific_pref.FindString("xkbLayout"); settings->layout = prefs_layout ? PinyinLayoutToMojom(*prefs_layout) : mojom::PinyinLayout::kUsQwerty; settings->use_hyphen_and_equals_to_page_candidates = - input_method_specific_pref.FindBoolKey("pinyinEnableUpperPaging") + input_method_specific_pref.FindBool("pinyinEnableUpperPaging") .value_or(true); settings->use_comma_and_period_to_page_candidates = - input_method_specific_pref.FindBoolKey("pinyinEnableLowerPaging") + input_method_specific_pref.FindBool("pinyinEnableLowerPaging") .value_or(true); settings->default_to_chinese = - input_method_specific_pref.FindBoolKey("pinyinDefaultChinese") + input_method_specific_pref.FindBool("pinyinDefaultChinese") .value_or(true); settings->default_to_full_width_characters = - input_method_specific_pref.FindBoolKey("pinyinFullWidthCharacter") + input_method_specific_pref.FindBool("pinyinFullWidthCharacter") .value_or(false); settings->default_to_full_width_punctuation = - input_method_specific_pref.FindBoolKey("pinyinChinesePunctuation") + input_method_specific_pref.FindBool("pinyinChinesePunctuation") .value_or(true); return settings; } @@ -232,14 +231,14 @@ } mojom::ZhuyinSettingsPtr CreateZhuyinSettings( - const base::Value& input_method_specific_pref) { + const base::Value::Dict& input_method_specific_pref) { auto settings = mojom::ZhuyinSettings::New(); settings->layout = ZhuyinLayoutToMojom(ValueOrEmpty( - input_method_specific_pref.FindStringKey("zhuyinKeyboardLayout"))); - settings->selection_keys = ZhuyinSelectionKeysToMojom(ValueOrEmpty( - input_method_specific_pref.FindStringKey("zhuyinSelectKeys"))); + input_method_specific_pref.FindString("zhuyinKeyboardLayout"))); + settings->selection_keys = ZhuyinSelectionKeysToMojom( + ValueOrEmpty(input_method_specific_pref.FindString("zhuyinSelectKeys"))); settings->page_size = ZhuyinPageSizeToInt( - ValueOrEmpty(input_method_specific_pref.FindStringKey("zhuyinPageSize"))); + ValueOrEmpty(input_method_specific_pref.FindString("zhuyinPageSize"))); return settings; } @@ -250,8 +249,8 @@ const std::string& engine_id) { // All input method settings are stored in a single pref whose value is a // dictionary. - const base::Value& all_input_method_pref = - *prefs.GetDictionary(::prefs::kLanguageInputMethodSpecificSettings); + const base::Value::Dict& all_input_method_pref = + prefs.GetValueDict(::prefs::kLanguageInputMethodSpecificSettings); // For each input method, the dictionary contains an entry, with the key being // a string that identifies the input method, and the value being a @@ -259,12 +258,12 @@ // The subdictionary structure depends on the type of input method it's for. // The subdictionary may be null if the user hasn't changed any settings for // that input method. - const base::Value* input_method_specific_pref_or_null = - all_input_method_pref.FindDictKey(GetPrefKeyForEngineId(engine_id)); + const base::Value::Dict* input_method_specific_pref_or_null = + all_input_method_pref.FindDict(GetPrefKeyForEngineId(engine_id)); // For convenience, pass an empty dictionary if there are no settings for this // input method yet. - base::DictionaryValue empty_value; + base::Value::Dict empty_value; const auto& input_method_specific_pref = input_method_specific_pref_or_null ? *input_method_specific_pref_or_null : empty_value;
diff --git a/chrome/browser/ash/input_method/native_input_method_engine_observer.cc b/chrome/browser/ash/input_method/native_input_method_engine_observer.cc index eaab9b4..ce1e201 100644 --- a/chrome/browser/ash/input_method/native_input_method_engine_observer.cc +++ b/chrome/browser/ash/input_method/native_input_method_engine_observer.cc
@@ -519,19 +519,20 @@ if (engine_id != "zh-t-i0-pinyin" && engine_id != "zh-hant-t-i0-und") return; - const base::Value& all_input_method_pref = - *prefs->GetDictionary(::prefs::kLanguageInputMethodSpecificSettings); + const base::Value::Dict& all_input_method_pref = + prefs->GetValueDict(::prefs::kLanguageInputMethodSpecificSettings); // Check if the settings are already migrated. - if (all_input_method_pref.FindDictKey(engine_id)) + if (all_input_method_pref.FindDict(engine_id)) return; - const base::Value* existing_pref_or_null = all_input_method_pref.FindDictKey( - engine_id == "zh-t-i0-pinyin" ? "pinyin" : "zhuyin"); + const base::Value::Dict* existing_pref_or_null = + all_input_method_pref.FindDict(engine_id == "zh-t-i0-pinyin" ? "pinyin" + : "zhuyin"); if (existing_pref_or_null) { DictionaryPrefUpdate update(prefs, ::prefs::kLanguageInputMethodSpecificSettings); - update->SetPath(engine_id, existing_pref_or_null->Clone()); + update->SetPath(engine_id, base::Value(existing_pref_or_null->Clone())); } }
diff --git a/chrome/browser/ash/input_method/ui/indexed_suggestion_candidate_button.cc b/chrome/browser/ash/input_method/ui/indexed_suggestion_candidate_button.cc index a9a8cd38..84093db 100644 --- a/chrome/browser/ash/input_method/ui/indexed_suggestion_candidate_button.cc +++ b/chrome/browser/ash/input_method/ui/indexed_suggestion_candidate_button.cc
@@ -80,7 +80,10 @@ // | | // | 1 | // +---+ - auto* candidate_wrapper = AddChildView(std::make_unique<views::View>()); + + // Wrapper uses views::Label since it doesn't override the hover state of the + // button. + auto* candidate_wrapper = AddChildView(std::make_unique<views::Label>()); views::FlexLayout* candidate_wrapper_layout = candidate_wrapper->SetLayoutManager( std::make_unique<views::FlexLayout>());
diff --git a/chrome/browser/ash/input_method/ui/suggestion_window_view.cc b/chrome/browser/ash/input_method/ui/suggestion_window_view.cc index e11aac7..b0a3922 100644 --- a/chrome/browser/ash/input_method/ui/suggestion_window_view.cc +++ b/chrome/browser/ash/input_method/ui/suggestion_window_view.cc
@@ -167,7 +167,10 @@ Orientation orientation) : delegate_(delegate) { DCHECK(parent); - + // AccessibleRole determines whether the content is announced on pop-up. + // Inner content should not be announced when the window appears since this + // is handled by AssistiveAccessibilityView to announce a custom string. + SetAccessibleRole(ax::mojom::Role::kNone); SetButtons(ui::DIALOG_BUTTON_NONE); SetCanActivate(false); set_parent_window(parent);
diff --git a/chrome/browser/ash/lock_screen_apps/first_app_run_toast_manager.cc b/chrome/browser/ash/lock_screen_apps/first_app_run_toast_manager.cc index c2bdd937..ea8fcd5 100644 --- a/chrome/browser/ash/lock_screen_apps/first_app_run_toast_manager.cc +++ b/chrome/browser/ash/lock_screen_apps/first_app_run_toast_manager.cc
@@ -78,9 +78,9 @@ DCHECK(app_window->GetNativeWindow()); const extensions::Extension* app = app_window->GetExtension(); - const base::Value* toast_shown = profile_->GetPrefs()->GetDictionary( + const base::Value::Dict& toast_shown = profile_->GetPrefs()->GetValueDict( prefs::kNoteTakingAppsLockScreenToastShown); - if (toast_shown->FindBoolPath(app->id()).value_or(false)) { + if (toast_shown.FindBoolByDottedPath(app->id()).value_or(false)) { return; }
diff --git a/chrome/browser/ash/login/app_mode/kiosk_launch_controller.cc b/chrome/browser/ash/login/app_mode/kiosk_launch_controller.cc index d1b4b71f..d745286 100644 --- a/chrome/browser/ash/login/app_mode/kiosk_launch_controller.cc +++ b/chrome/browser/ash/login/app_mode/kiosk_launch_controller.cc
@@ -458,7 +458,7 @@ StartTimerToWaitForExtensions(); // Initialize and start Lacros for preparing force-installed extensions. - crosapi::BrowserManager::Get()->InitializeAndStart(); + crosapi::BrowserManager::Get()->InitializeAndStartIfNeeded(); return; }
diff --git a/chrome/browser/ash/login/demo_mode/demo_session.cc b/chrome/browser/ash/login/demo_mode/demo_session.cc index 4fcf6809..ca05fd87 100644 --- a/chrome/browser/ash/login/demo_mode/demo_session.cc +++ b/chrome/browser/ash/login/demo_mode/demo_session.cc
@@ -542,9 +542,8 @@ void DemoSession::OnSessionStateChanged() { switch (session_manager::SessionManager::Get()->session_state()) { case session_manager::SessionState::LOGIN_PRIMARY: - EnsureResourcesLoaded( - base::BindOnce(&DemoSession::ConfigureAndStartSplashScreen, - weak_ptr_factory_.GetWeakPtr())); + EnsureResourcesLoaded(base::BindOnce(&DemoSession::ShowSplashScreen, + weak_ptr_factory_.GetWeakPtr())); break; case session_manager::SessionState::ACTIVE: if (ShouldRemoveSplashScreen()) @@ -608,13 +607,15 @@ FROM_HERE, base::BindOnce(&LaunchDemoSystemWebApp)); } -base::FilePath GetSplashScreenImagePath(base::FilePath localized_image_path, - base::FilePath fallback_path) { - return base::PathExists(localized_image_path) ? localized_image_path - : fallback_path; -} - -void DemoSession::ShowSplashScreen(base::FilePath image_path) { +void DemoSession::ShowSplashScreen() { + const std::string current_locale = g_browser_process->GetApplicationLocale(); + base::FilePath image_path = demo_resources_->path() + .Append(kSplashScreensPath) + .Append(current_locale + ".jpg"); + if (!base::PathExists(image_path)) { + image_path = + demo_resources_->path().Append(kSplashScreensPath).Append("en-US.jpg"); + } WallpaperControllerClientImpl::Get()->ShowAlwaysOnTopWallpaper(image_path); remove_splash_screen_fallback_timer_->Start( FROM_HERE, kRemoveSplashScreenTimeout, @@ -622,21 +623,6 @@ weak_ptr_factory_.GetWeakPtr())); } -void DemoSession::ConfigureAndStartSplashScreen() { - const std::string current_locale = g_browser_process->GetApplicationLocale(); - base::FilePath localized_image_path = demo_resources_->path() - .Append(kSplashScreensPath) - .Append(current_locale + ".jpg"); - base::FilePath fallback_path = - demo_resources_->path().Append(kSplashScreensPath).Append("en-US.jpg"); - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, - base::BindOnce(&GetSplashScreenImagePath, localized_image_path, - fallback_path), - base::BindOnce(&DemoSession::ShowSplashScreen, - weak_ptr_factory_.GetWeakPtr())); -} - void DemoSession::RemoveSplashScreen() { if (splash_screen_removed_) return;
diff --git a/chrome/browser/ash/login/demo_mode/demo_session.h b/chrome/browser/ash/login/demo_mode/demo_session.h index 4d488ded..2c6c3d5 100644 --- a/chrome/browser/ash/login/demo_mode/demo_session.h +++ b/chrome/browser/ash/login/demo_mode/demo_session.h
@@ -202,11 +202,8 @@ // launch the app upon installation. void InstallAppFromUpdateUrl(const std::string& id); - // Find image path then show the splash screen. - void ConfigureAndStartSplashScreen(); - - // Show, and set the fallback timeout to remove, the splash screen. - void ShowSplashScreen(base::FilePath image_path); + // Shows the splash screen after demo mode resources are installed. + void ShowSplashScreen(); // Removes the splash screen. void RemoveSplashScreen();
diff --git a/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc b/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc index bbc46569e..1027620 100644 --- a/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc +++ b/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc
@@ -13,7 +13,6 @@ #include "base/bind.h" #include "base/files/file_path.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/thread_pool/thread_pool_instance.h" #include "base/timer/mock_timer.h" #include "chrome/browser/ash/login/demo_mode/demo_resources.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" @@ -192,8 +191,6 @@ ASSERT_TRUE(FinishResourcesComponentLoad( base::FilePath(kTestDemoModeResourcesMountPoint))); - // Wait for splash screen image to load and timer to be set - task_environment_.RunUntilIdle(); EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); EXPECT_EQ(0, test_wallpaper_controller_.remove_always_on_top_wallpaper_count()); @@ -246,8 +243,6 @@ ASSERT_TRUE(FinishResourcesComponentLoad( base::FilePath(kTestDemoModeResourcesMountPoint))); - // Wait for splash screen image to load and timer to be set - task_environment_.RunUntilIdle(); EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count()); EXPECT_EQ(0, test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc index e921bbc..361282f 100644 --- a/chrome/browser/ash/login/wizard_controller.cc +++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -1671,7 +1671,7 @@ switch (result) { case DemoSetupScreen::Result::COMPLETED: PerformOOBECompletedActions(); - SwitchWebUItoMojo(); + ShowLoginScreen(); break; case DemoSetupScreen::Result::CANCELED: ShowWelcomeScreen();
diff --git a/chrome/browser/ash/login/wizard_controller_browsertest.cc b/chrome/browser/ash/login/wizard_controller_browsertest.cc index 9583176..eecc348 100644 --- a/chrome/browser/ash/login/wizard_controller_browsertest.cc +++ b/chrome/browser/ash/login/wizard_controller_browsertest.cc
@@ -67,14 +67,12 @@ #include "chrome/browser/ash/net/network_portal_detector_test_impl.h" #include "chrome/browser/ash/net/rollback_network_config/fake_rollback_network_config.h" #include "chrome/browser/ash/net/rollback_network_config/rollback_network_config_service.h" -#include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h" #include "chrome/browser/ash/policy/enrollment/auto_enrollment_client.h" #include "chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker.h" #include "chrome/browser/ash/policy/enrollment/enrollment_config.h" #include "chrome/browser/ash/policy/enrollment/fake_auto_enrollment_client.h" #include "chrome/browser/ash/policy/server_backed_state/server_backed_device_state.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/lifetime/browser_shutdown.h" #include "chrome/browser/lifetime/termination_notification.h" @@ -2525,25 +2523,6 @@ } }; -// Helper InstallAttributes::LockResultCallback implementation. -void OnEnterpriseDeviceLock(base::OnceClosure runner_quit_task, - InstallAttributes::LockResult in_locked) { - LOG(INFO) << "Enterprise lock = " << in_locked; - std::move(runner_quit_task).Run(); -} - -void LockDeviceForEnterprise() { - base::RunLoop run_loop; - policy::BrowserPolicyConnectorAsh* connector = - g_browser_process->platform_part()->browser_policy_connector_ash(); - connector->GetInstallAttributes()->LockDevice( - policy::DEVICE_MODE_ENTERPRISE, "domain.com", - std::string(), // realm - "device-id", - base::BindOnce(&OnEnterpriseDeviceLock, run_loop.QuitClosure())); - run_loop.Run(); -} - IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, OnlineDemoSetupFlowFinished) { CheckCurrentScreen(WelcomeView::kScreenId); @@ -2631,9 +2610,6 @@ CheckCurrentScreen(DemoSetupScreenView::kScreenId); EXPECT_TRUE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); - // Set Install Attributes for device so it is considered enterprise managed - // to properly switch to Mojo LoginDisplayHost - LockDeviceForEnterprise(); mock_demo_setup_screen_->ExitScreen(DemoSetupScreen::Result::COMPLETED); EXPECT_TRUE(StartupUtils::IsOobeCompleted());
diff --git a/chrome/browser/ash/os_feedback/chrome_os_feedback_delegate.cc b/chrome/browser/ash/os_feedback/chrome_os_feedback_delegate.cc index 643fcd6..f57158a 100644 --- a/chrome/browser/ash/os_feedback/chrome_os_feedback_delegate.cc +++ b/chrome/browser/ash/os_feedback/chrome_os_feedback_delegate.cc
@@ -283,6 +283,14 @@ OpenWebDialog(systemInfoUrl); } +void ChromeOsFeedbackDelegate::OpenBluetoothLogsInfoDialog() { + // TODO(http://b/233079042): Make the bluetooth_logs_info.html page a separate + // WebUI. For now, use the old Feedback tool's bluetooth_logs_info.html. + GURL system_info_url = GURL(base::StrCat( + {chrome::kChromeUIFeedbackURL, "html/bluetooth_logs_info.html"})); + OpenWebDialog(system_info_url); +} + void ChromeOsFeedbackDelegate::OpenWebDialog(GURL url) { Browser* feedback_browser = ash::FindSystemWebAppBrowser( profile_, ash::SystemWebAppType::OS_FEEDBACK);
diff --git a/chrome/browser/ash/os_feedback/chrome_os_feedback_delegate.h b/chrome/browser/ash/os_feedback/chrome_os_feedback_delegate.h index 0661663..1af96d6 100644 --- a/chrome/browser/ash/os_feedback/chrome_os_feedback_delegate.h +++ b/chrome/browser/ash/os_feedback/chrome_os_feedback_delegate.h
@@ -45,6 +45,7 @@ void OpenExploreApp() override; void OpenMetricsDialog() override; void OpenSystemInfoDialog() override; + void OpenBluetoothLogsInfoDialog() override; private: void OnSendFeedbackDone(SendReportCallback callback, bool status);
diff --git a/chrome/browser/ash/os_feedback/chrome_os_feedback_delegate_browsertest.cc b/chrome/browser/ash/os_feedback/chrome_os_feedback_delegate_browsertest.cc index 121e9b8..3d05c12 100644 --- a/chrome/browser/ash/os_feedback/chrome_os_feedback_delegate_browsertest.cc +++ b/chrome/browser/ash/os_feedback/chrome_os_feedback_delegate_browsertest.cc
@@ -395,4 +395,30 @@ EXPECT_EQ(owned_widgets_post_dialog.size(), 1); } +// Test that the bluetooth logs dialog opens +// when OpenBluetoothLogsInfoDialog is invoked. +IN_PROC_BROWSER_TEST_F(ChromeOsFeedbackDelegateTest, + OpenBluetoothLogsInfoDialog) { + Browser* feedback_browser = LaunchFeedbackAppAndGetBrowser(); + + gfx::NativeWindow feedback_window = + feedback_browser->window()->GetNativeWindow(); + + std::set<views::Widget*> owned_widgets_pre_dialog; + views::Widget::GetAllOwnedWidgets(feedback_window, &owned_widgets_pre_dialog); + + EXPECT_EQ(owned_widgets_pre_dialog.size(), 0); + + // Initialize the delegate. + ChromeOsFeedbackDelegate feedback_delegate_(browser()->profile()); + + feedback_delegate_.OpenBluetoothLogsInfoDialog(); + + std::set<views::Widget*> owned_widgets_post_dialog; + views::Widget::GetAllOwnedWidgets(feedback_window, + &owned_widgets_post_dialog); + + EXPECT_EQ(owned_widgets_post_dialog.size(), 1); +} + } // namespace ash
diff --git a/chrome/browser/ash/policy/dlp/dlp_files_controller.cc b/chrome/browser/ash/policy/dlp/dlp_files_controller.cc index 01e9ef8..dc40589 100644 --- a/chrome/browser/ash/policy/dlp/dlp_files_controller.cc +++ b/chrome/browser/ash/policy/dlp/dlp_files_controller.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ash/policy/dlp/dlp_files_controller.h" #include <sys/types.h> +#include <iterator> #include <string> #include "base/bind.h" @@ -14,9 +15,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/logging.h" -#include "base/notreached.h" -#include "base/task/task_traits.h" -#include "base/task/thread_pool.h" +#include "base/ranges/algorithm.h" #include "chrome/browser/ash/drive/drive_integration_service.h" #include "chrome/browser/ash/file_manager/path_util.h" #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h" @@ -85,6 +84,18 @@ bool is_dlp_restricted) : source_url(source_url), is_dlp_restricted(is_dlp_restricted) {} +DlpFilesController::DlpFileRestrictionDetails::DlpFileRestrictionDetails() = + default; + +DlpFilesController::DlpFileRestrictionDetails::DlpFileRestrictionDetails( + DlpFileRestrictionDetails&&) = default; +DlpFilesController::DlpFileRestrictionDetails& +DlpFilesController::DlpFileRestrictionDetails::operator=( + DlpFilesController::DlpFileRestrictionDetails&&) = default; + +DlpFilesController::DlpFileRestrictionDetails::~DlpFileRestrictionDetails() = + default; + DlpFilesController::DlpFilesController() = default; DlpFilesController::~DlpFilesController() = default; @@ -213,16 +224,53 @@ std::move(result_callback).Run(std::move(restricted_files_sources)); } -std::map<std::string, std::set<std::string>> +std::vector<DlpFilesController::DlpFileRestrictionDetails> DlpFilesController::GetDlpRestrictionDetails(const std::string& sourceUrl) { policy::DlpRulesManager* dlp_rules_manager = policy::DlpRulesManagerFactory::GetForPrimaryProfile(); if (!dlp_rules_manager) { return {}; } - // TODO(crbug.com/1346254): Call DlpRulesManager to get the restricted - // destinations and components; aggregate and convert to string format. - return {}; + + const GURL source(sourceUrl); + const DlpRulesManager::AggregatedDestinations aggregated_destinations = + dlp_rules_manager->GetAggregatedDestinations( + source, DlpRulesManager::Restriction::kFiles); + const DlpRulesManager::AggregatedComponents aggregated_components = + dlp_rules_manager->GetAggregatedComponents( + source, DlpRulesManager::Restriction::kFiles); + + std::vector<DlpFilesController::DlpFileRestrictionDetails> result; + // Add levels for which urls are set. + for (const auto& [level, urls] : aggregated_destinations) { + DlpFileRestrictionDetails details; + details.level = level; + base::ranges::move(urls.begin(), urls.end(), + std::back_inserter(details.urls)); + // Add the components for this level, if any. + const auto it = aggregated_components.find(level); + if (it != aggregated_components.end()) { + base::ranges::move(it->second.begin(), it->second.end(), + std::back_inserter(details.components)); + } + result.emplace_back(std::move(details)); + } + + // There might be levels for which only components are set, so we need to add + // those separately. + for (const auto& [level, components] : aggregated_components) { + if (aggregated_destinations.find(level) != aggregated_destinations.end()) { + // Already added in the previous loop. + continue; + } + DlpFileRestrictionDetails details; + details.level = level; + base::ranges::move(components.begin(), components.end(), + std::back_inserter(details.components)); + result.emplace_back(std::move(details)); + } + + return result; } bool DlpFilesController::IsDlpPolicyMatched(const std::string& source_url) {
diff --git a/chrome/browser/ash/policy/dlp/dlp_files_controller.h b/chrome/browser/ash/policy/dlp/dlp_files_controller.h index 268a144..6ccbb72 100644 --- a/chrome/browser/ash/policy/dlp/dlp_files_controller.h +++ b/chrome/browser/ash/policy/dlp/dlp_files_controller.h
@@ -7,9 +7,10 @@ #include <vector> -#include "base/callback.h" +#include "base/callback_forward.h" #include "base/containers/flat_map.h" #include "base/memory/weak_ptr.h" +#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h" #include "chromeos/dbus/dlp/dlp_service.pb.h" #include "storage/browser/file_system/file_system_url.h" #include "third_party/blink/public/mojom/choosers/file_chooser.mojom-forward.h" @@ -48,6 +49,26 @@ bool is_dlp_restricted; }; + // DlpFileRestrictionDetails keeps aggregated information about DLP rules + // that apply to a file. It consists of the level (e.g. block, warn) and + // destinations for which this level applies (URLs and/or components). + struct DlpFileRestrictionDetails { + DlpFileRestrictionDetails(); + DlpFileRestrictionDetails(const DlpFileRestrictionDetails&) = delete; + DlpFileRestrictionDetails& operator=(const DlpFileRestrictionDetails&) = + delete; + DlpFileRestrictionDetails(DlpFileRestrictionDetails&&); + DlpFileRestrictionDetails& operator=(DlpFileRestrictionDetails&&); + ~DlpFileRestrictionDetails(); + + // The level for which the restriction is enforced. + DlpRulesManager::Level level; + // List of URLs for which the restriction is enforced. + std::vector<std::string> urls; + // List of components for which the restriction is enforced. + std::vector<DlpRulesManager::Component> components; + }; + using GetDisallowedTransfersCallback = base::OnceCallback<void(std::vector<storage::FileSystemURL>)>; using GetFilesRestrictedByAnyRuleCallback = GetDisallowedTransfersCallback; @@ -89,8 +110,8 @@ std::string destination, IsFilesTransferRestrictedCallback result_callback); - // TODO(crbug.com/1346254): Add comments when implementation is complete. - std::map<std::string, std::set<std::string>> GetDlpRestrictionDetails( + // Returns restriction information for `sourceUrl`. + std::vector<DlpFileRestrictionDetails> GetDlpRestrictionDetails( const std::string& sourceUrl); // Returns whether a dlp policy matches for the `source_url`.
diff --git a/chrome/browser/ash/policy/dlp/dlp_files_controller_unittest.cc b/chrome/browser/ash/policy/dlp/dlp_files_controller_unittest.cc index 10b8edf0..3d9dd3e 100644 --- a/chrome/browser/ash/policy/dlp/dlp_files_controller_unittest.cc +++ b/chrome/browser/ash/policy/dlp/dlp_files_controller_unittest.cc
@@ -15,7 +15,6 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/memory/scoped_refptr.h" -#include "base/run_loop.h" #include "base/test/mock_callback.h" #include "base/test/test_future.h" #include "chrome/browser/ash/crostini/crostini_manager.h" @@ -396,6 +395,71 @@ EXPECT_EQ(dlp_metadata, future.Take()); } +TEST_F(DlpFilesControllerTest, GetDlpRestrictionDetails_Mixed) { + DlpRulesManager::AggregatedDestinations destinations; + destinations[DlpRulesManager::Level::kBlock].insert(kExample2); + destinations[DlpRulesManager::Level::kAllow].insert(kExample3); + + DlpRulesManager::AggregatedComponents components; + components[DlpRulesManager::Level::kBlock].insert( + DlpRulesManager::Component::kUsb); + components[DlpRulesManager::Level::kWarn].insert( + DlpRulesManager::Component::kDrive); + + EXPECT_CALL(*rules_manager_, GetAggregatedDestinations) + .WillOnce(testing::Return(destinations)); + EXPECT_CALL(*rules_manager_, GetAggregatedComponents) + .WillOnce(testing::Return(components)); + + auto result = files_controller_.GetDlpRestrictionDetails(kExample1); + + ASSERT_EQ(result.size(), 3); + std::vector<std::string> expected_urls; + std::vector<DlpRulesManager::Component> expected_components; + // Block: + expected_urls.push_back(kExample2); + expected_components.push_back(DlpRulesManager::Component::kUsb); + EXPECT_EQ(result[0].level, DlpRulesManager::Level::kBlock); + EXPECT_EQ(result[0].urls, expected_urls); + EXPECT_EQ(result[0].components, expected_components); + // Allow: + expected_urls.clear(); + expected_urls.push_back(kExample3); + expected_components.clear(); + EXPECT_EQ(result[1].level, DlpRulesManager::Level::kAllow); + EXPECT_EQ(result[1].urls, expected_urls); + EXPECT_EQ(result[1].components, expected_components); + // Warn: + expected_urls.clear(); + expected_components.clear(); + expected_components.push_back(DlpRulesManager::Component::kDrive); + EXPECT_EQ(result[2].level, DlpRulesManager::Level::kWarn); + EXPECT_EQ(result[2].urls, expected_urls); + EXPECT_EQ(result[2].components, expected_components); +} + +TEST_F(DlpFilesControllerTest, GetDlpRestrictionDetails_Components) { + DlpRulesManager::AggregatedDestinations destinations; + DlpRulesManager::AggregatedComponents components; + components[DlpRulesManager::Level::kBlock].insert( + DlpRulesManager::Component::kUsb); + + EXPECT_CALL(*rules_manager_, GetAggregatedDestinations) + .WillOnce(testing::Return(destinations)); + EXPECT_CALL(*rules_manager_, GetAggregatedComponents) + .WillOnce(testing::Return(components)); + + auto result = files_controller_.GetDlpRestrictionDetails(kExample1); + + ASSERT_EQ(result.size(), 1); + std::vector<std::string> expected_urls; + std::vector<DlpRulesManager::Component> expected_components; + expected_components.push_back(DlpRulesManager::Component::kUsb); + EXPECT_EQ(result[0].level, DlpRulesManager::Level::kBlock); + EXPECT_EQ(result[0].urls, expected_urls); + EXPECT_EQ(result[0].components, expected_components); +} + class DlpFilesExternalDestinationTest : public DlpFilesControllerTest, public ::testing::WithParamInterface<
diff --git a/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc b/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc index 1a9f6ff..9240d63 100644 --- a/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc +++ b/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
@@ -811,6 +811,25 @@ RunTest(test_code); } +IN_PROC_BROWSER_TEST_F(CrosWindowBrowserTest, CrosWindowEventIdl) { + const char test_code[] = R"( +async function cros_test() { + let windows = await chromeos.windowManagement.getWindows(); + assert_true(chromeos.CrosWindowEvent !== undefined, 'event'); + let window_event = new chromeos.CrosWindowEvent('windowclosed', + {window: windows[0]}); + assert_equals(window_event.type, 'windowclosed', 'event type'); + assert_equals(window_event.window, windows[0], 'Window event has correct\ + window property'); + assert_true(window_event.bubbles, 'Window event should bubble'); + assert_false(window_event.cancelable, 'Window event should not be\ + cancelable'); +} + )"; + + RunTest(test_code); +} + IN_PROC_BROWSER_TEST_F(CrosWindowExtensionBrowserTest, StartEvent) { // TODO(b/230811571): Rather than using the console to wait for the // observer to get called, we should add support for running async functions
diff --git a/chrome/browser/ash/system_extensions/system_extension.h b/chrome/browser/ash/system_extensions/system_extension.h index 40d329d..20034b53 100644 --- a/chrome/browser/ash/system_extensions/system_extension.h +++ b/chrome/browser/ash/system_extensions/system_extension.h
@@ -46,11 +46,7 @@ // Display name of the System Extension to be used where // the number of characters is limited. absl::optional<std::string> short_name; - // Web App that the System Extension is allowed to communicate with. - absl::optional<GURL> companion_web_app_url; - // Entry point to the System Extension. For now, we just open a page - // in the background, but we'll change to a Service Worker once - // chrome-untrusted:// supports Service Workers. + // Entry point to the System Extension. GURL service_worker_url; // The following fields are constructed from the System Extension's manifest.
diff --git a/chrome/browser/ash/system_extensions/system_extensions_browsertest.cc b/chrome/browser/ash/system_extensions/system_extensions_browsertest.cc index d468a7c..d2e297c 100644 --- a/chrome/browser/ash/system_extensions/system_extensions_browsertest.cc +++ b/chrome/browser/ash/system_extensions/system_extensions_browsertest.cc
@@ -37,7 +37,6 @@ constexpr SystemExtensionId kTestSystemExtensionId = {1, 2, 3, 4}; constexpr char kTestSystemExtensionManifest[] = R"({ - "companion_web_app_url": "https://example.com", "id": "01020304", "name": "Sample System Web Extension", "service_worker_url": "/sw.js",
diff --git a/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker.cc b/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker.cc index 97a4bdd..3e99e40 100644 --- a/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker.cc +++ b/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker.cc
@@ -27,7 +27,6 @@ const constexpr char kTypeKey[] = "type"; const constexpr char kNameKey[] = "name"; const constexpr char kShortNameKey[] = "short_name"; -const constexpr char kCompanionWebAppUrlKey[] = "companion_web_app_url"; const constexpr char kServiceWorkerUrlKey[] = "service_worker_url"; GURL GetBaseURL(const std::string& id, SystemExtensionType type) { @@ -101,15 +100,15 @@ return; } - base::Value& parsed_manifest = *value_or_error; + base::Value::Dict& parsed_manifest = value_or_error->GetDict(); SystemExtension system_extension; - system_extension.manifest = parsed_manifest.GetDict().Clone(); + system_extension.manifest = parsed_manifest.Clone(); // Parse mandatory fields. // Parse id. - std::string* id_str = parsed_manifest.FindStringKey(kIdKey); + std::string* id_str = parsed_manifest.FindString(kIdKey); if (!id_str) { std::move(callback).Run(SystemExtensionsInstallStatus::kFailedIdMissing); return; @@ -122,7 +121,7 @@ system_extension.id = id.value(); // Parse type. - std::string* type_str = parsed_manifest.FindStringKey(kTypeKey); + std::string* type_str = parsed_manifest.FindString(kTypeKey); if (!type_str) { std::move(callback).Run(SystemExtensionsInstallStatus::kFailedTypeMissing); return; @@ -144,7 +143,7 @@ // Parse service_worker_url. std::string* service_worker_path = - parsed_manifest.FindStringKey(kServiceWorkerUrlKey); + parsed_manifest.FindString(kServiceWorkerUrlKey); if (!service_worker_path) { std::move(callback).Run( SystemExtensionsInstallStatus::kFailedServiceWorkerUrlMissing); @@ -166,7 +165,7 @@ // Parse name. // TODO(ortuno): Decide a set of invalid characters and remove them/fail // installation. - std::string* name = parsed_manifest.FindStringKey(kNameKey); + std::string* name = parsed_manifest.FindString(kNameKey); if (!name) { std::move(callback).Run(SystemExtensionsInstallStatus::kFailedNameMissing); return; @@ -181,24 +180,11 @@ // Parse optional fields. // Parse short_name. - std::string* short_name_str = parsed_manifest.FindStringKey(kShortNameKey); + std::string* short_name_str = parsed_manifest.FindString(kShortNameKey); if (short_name_str && !short_name_str->empty()) { system_extension.short_name = *short_name_str; } - // Parse companion_web_app_url. - if (std::string* companion_web_app_url_str = - parsed_manifest.FindStringKey(kCompanionWebAppUrlKey)) { - GURL companion_web_app_url(*companion_web_app_url_str); - if (companion_web_app_url.is_valid() && - companion_web_app_url.SchemeIs(url::kHttpsScheme)) { - system_extension.companion_web_app_url = companion_web_app_url; - } else { - LOG(WARNING) << "Companion Web App URL is invalid: " - << companion_web_app_url; - } - } - std::move(callback).Run(std::move(system_extension)); }
diff --git a/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker_unittest.cc b/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker_unittest.cc index 5bb6beda..86d0ff8 100644 --- a/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker_unittest.cc +++ b/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker_unittest.cc
@@ -107,8 +107,7 @@ "type": "echo", "service_worker_url": "/sw.js", "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -124,9 +123,6 @@ EXPECT_EQ("Long Test", system_extension.name); ASSERT_TRUE(system_extension.short_name.has_value()); EXPECT_EQ("Test", system_extension.short_name); - ASSERT_TRUE(system_extension.companion_web_app_url.has_value()); - EXPECT_EQ("https://test.example/", - system_extension.companion_web_app_url->spec()); } TEST_P(SystemExtensionsSandboxedUnpackerTest, Failure_EmptyManifest) { @@ -147,8 +143,7 @@ "type": "echo", "service_worker_url": "/sw.js", "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -161,8 +156,7 @@ "type": "echo", "service_worker_url": "/sw.js", "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -175,8 +169,7 @@ "type": "echo", "service_worker_url": "/sw.js", "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -189,8 +182,7 @@ "type": "echo", "service_worker_url": "/sw.js", "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -202,8 +194,7 @@ "id": "01020304", "service_worker_url": "/sw.js", "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -216,8 +207,7 @@ "type": "foo", "service_worker_url": "/sw.js", "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -229,8 +219,7 @@ "id": "01020304", "type": "echo", "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -243,8 +232,7 @@ "type": "echo", "service_worker_url": "../", "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -257,8 +245,7 @@ "type": "echo", "service_worker_url": "", "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -272,8 +259,7 @@ "type": "echo", "service_worker_url": "https://test.example", "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -285,8 +271,7 @@ "id": "01020304", "type": "echo", "service_worker_url": "/sw.js", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -299,8 +284,7 @@ "type": "echo", "service_worker_url": "/sw.js", "name": "", - "short_name": "Test", - "companion_web_app_url": "https://test.example/" + "short_name": "Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -312,8 +296,7 @@ "id": "01020304", "type": "echo", "service_worker_url": "/sw.js", - "name": "Long Test", - "companion_web_app_url": "https://test.example/" + "name": "Long Test" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); @@ -326,57 +309,13 @@ "type": "echo", "service_worker_url": "/sw.js", "name": "Long Test", - "short_name": "", - "companion_web_app_url": "https://test.example/" + "short_name": "" })"; auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); EXPECT_FALSE(result.value().short_name.has_value()); } -TEST_P(SystemExtensionsSandboxedUnpackerTest, Success_NoCompanionWebAppUrl) { - static constexpr const char kSystemExtensionManifest[] = R"({ - "id": "01020304", - "type": "echo", - "service_worker_url": "/sw.js", - "name": "Long Test", - "short_name": "Test" - })"; - - auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); - EXPECT_FALSE(result.value().companion_web_app_url.has_value()); -} - -TEST_P(SystemExtensionsSandboxedUnpackerTest, - Success_InvalidCompanionWebAppUrl) { - static constexpr const char kSystemExtensionManifest[] = R"({ - "id": "01020304", - "type": "echo", - "service_worker_url": "/sw.js", - "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "foobar" - })"; - - auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); - EXPECT_FALSE(result.value().companion_web_app_url.has_value()); -} - -TEST_P(SystemExtensionsSandboxedUnpackerTest, - Success_InsecureCompanionWebAppUrl) { - static constexpr const char kSystemExtensionManifest[] = R"({ - "id": "01020304", - "type": "echo", - "service_worker_url": "/sw.js", - "name": "Long Test", - "short_name": "Test", - "companion_web_app_url": "http://test.example" - })"; - - auto result = CallGetSystemExtensionFrom(kSystemExtensionManifest); - EXPECT_FALSE(result.value().companion_web_app_url.has_value()); -} - TEST_P(SystemExtensionsSandboxedUnpackerFromDirTest, Failure_NoDir) { // Create a directory and delete a directory to get a unique file path to a // non existent directory.
diff --git a/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc index dcd5973..9df01a7 100644 --- a/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc
@@ -143,16 +143,25 @@ features::kHappinessTrackingMediaAppPdf.name); } - void MediaAppLaunchWithFile(); - void MediaAppWithLaunchSystemWebAppAsync(); - void MediaAppEligibleOpenTask(); + void SetUpOnMainThread() override { + SystemWebAppIntegrationTest::SetUpOnMainThread(); + WaitForTestSystemAppInstall(); + } - // Helper to initiate a test by launching a single file. + apps::AppLaunchParams MediaAppLaunchParams(); + std::string MediaAppAppId(); + + // Helper to initiate a test by launching a single file, as if from the files + // app. content::WebContents* LaunchWithOneTestFile(const char* file); // Helper to initiate a test by launching with no files (zero state). content::WebContents* LaunchWithNoFiles(); + // Launch the MediApp with the given |file_path| as a launch param, and wait + // for the application to finish loading. + content::WebContents* DirectlyLaunchWithFile(const base::FilePath& file_path); + protected: ash::NetworkPortalDetectorMixin network_portal_detector_{&mixin_host_}; @@ -498,9 +507,16 @@ EXPECT_TRUE(base::TouchFile(path, time, time)); } +apps::AppLaunchParams MediaAppIntegrationTest::MediaAppLaunchParams() { + return LaunchParamsForApp(ash::SystemWebAppType::MEDIA); +} + +std::string MediaAppIntegrationTest::MediaAppAppId() { + return *GetManager().GetAppIdForSystemApp(ash::SystemWebAppType::MEDIA); +} + content::WebContents* MediaAppIntegrationTest::LaunchWithOneTestFile( const char* file) { - WaitForTestSystemAppInstall(); launch_folder_ = std::make_unique<file_manager::test::FolderInMyFiles>(profile()); launch_folder_->Add({TestFile(file)}); @@ -510,12 +526,18 @@ } content::WebContents* MediaAppIntegrationTest::LaunchWithNoFiles() { - WaitForTestSystemAppInstall(); - content::WebContents* web_ui = LaunchApp(ash::SystemWebAppType::MEDIA); + content::WebContents* web_ui = LaunchApp(MediaAppLaunchParams()); PrepareAppForTest(web_ui); return web_ui; } +content::WebContents* MediaAppIntegrationTest::DirectlyLaunchWithFile( + const base::FilePath& file_path) { + apps::AppLaunchParams params = MediaAppLaunchParams(); + params.launch_files.push_back(file_path); + return LaunchApp(std::move(params)); +} + std::vector<apps::IntentLaunchInfo> GetAppsForMimeType( apps::AppServiceProxy* proxy, const std::string& mime_type) { @@ -541,18 +563,15 @@ // Test that the MediaApp successfully loads a file passed in on its launch // params. This exercises only web_applications logic. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationTest, MediaAppLaunchWithFile) { - WaitForTestSystemAppInstall(); // Launch the App for the first time. - content::WebContents* app = LaunchAppWithFile(ash::SystemWebAppType::MEDIA, - TestFile(kFilePng800x600)); + content::WebContents* app = DirectlyLaunchWithFile(TestFile(kFilePng800x600)); Browser* first_browser = chrome::FindBrowserWithActiveWindow(); PrepareAppForTest(app); EXPECT_EQ("800x600", WaitForImageAlt(app, kFilePng800x600)); // Launch with a different file in a new window. - app = LaunchAppWithFile(ash::SystemWebAppType::MEDIA, - TestFile(kFileJpeg640x480)); + app = DirectlyLaunchWithFile(TestFile(kFileJpeg640x480)); Browser* second_browser = chrome::FindBrowserWithActiveWindow(); PrepareAppForTest(app); @@ -565,7 +584,6 @@ // platform (a different code path than MediaAppLaunchWithFile test). IN_PROC_BROWSER_TEST_P(MediaAppIntegrationTest, MediaAppWithLaunchSystemWebAppAsync) { - WaitForTestSystemAppInstall(); // Launch the App for the first time. ash::SystemAppLaunchParams audio_params; audio_params.launch_paths.push_back(TestFile(kFilePng800x600)); @@ -592,7 +610,6 @@ // Test that the Media App launches a single window for images. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationTest, MediaAppLaunchImageMulti) { - WaitForTestSystemAppInstall(); ash::SystemAppLaunchParams image_params; image_params.launch_paths = {TestFile(kFilePng800x600), TestFile(kFileJpeg640x480)}; @@ -612,7 +629,6 @@ // Test that the Media App launches multiple windows for PDFs. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationTest, MediaAppLaunchPdfMulti) { - WaitForTestSystemAppInstall(); ash::SystemAppLaunchParams pdf_params; pdf_params.launch_paths = {TestFile(kFilePdfTall), TestFile(kFilePdfImg)}; @@ -636,10 +652,8 @@ // Test that the Media App appears as a handler for files in the App Service. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationTest, MediaAppHandlesIntents) { - WaitForTestSystemAppInstall(); auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile()); - const std::string media_app_id = - *GetManager().GetAppIdForSystemApp(ash::SystemWebAppType::MEDIA); + const std::string media_app_id = MediaAppAppId(); { // Smoke test that a binary blob is not handled by Media App. @@ -677,8 +691,7 @@ // Regression test for b/172881869. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationTest, LoadsPdf) { - WaitForTestSystemAppInstall(); - LaunchApp(ash::SystemWebAppType::MEDIA); + LaunchWithNoFiles(); content::WebContents* app = PrepareActiveBrowserForTest(); // TODO(crbug/1148090): To fully load PDFs, "frame-src" needs to be set, this // test doesn't provide coverage for that. @@ -760,9 +773,8 @@ IN_PROC_BROWSER_TEST_P(MediaAppIntegrationTest, MAYBE_LoadsInkForImageAnnotation) { - WaitForTestSystemAppInstall(); - content::WebContents* app = LaunchAppWithFile(ash::SystemWebAppType::MEDIA, - TestFile(kFileJpeg640x480)); + content::WebContents* app = + DirectlyLaunchWithFile(TestFile(kFileJpeg640x480)); PrepareAppForTest(app); EXPECT_EQ("640x480", WaitForImageAlt(app, kFileJpeg640x480)); @@ -793,9 +805,8 @@ // Tests that clicking on the 'Info' button in the app bar toggles the // information panel. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationTest, MAYBE_InformationPanel) { - WaitForTestSystemAppInstall(); - content::WebContents* app = LaunchAppWithFile(ash::SystemWebAppType::MEDIA, - TestFile(kFileJpeg640x480)); + content::WebContents* app = + DirectlyLaunchWithFile(TestFile(kFileJpeg640x480)); PrepareAppForTest(app); EXPECT_EQ("640x480", WaitForImageAlt(app, kFileJpeg640x480)); @@ -836,7 +847,6 @@ // Tests that the media app is able to overwrite the original file on save. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationWithFilesAppTest, MAYBE_SavesToOriginalFile) { - WaitForTestSystemAppInstall(); file_manager::test::FolderInMyFiles folder(profile()); folder.Add({TestFile(kFilePng800x600)}); @@ -997,8 +1007,6 @@ // Test that the MediaApp can load RAW files passed on launch params. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationWithFilesAppTest, HandleRawFiles) { - WaitForTestSystemAppInstall(); - // Initialize a folder with 2 RAW images. Note this approach doesn't guarantee // the modification times of the files so, and therefore does not suggest an // ordering to the files of the directory contents. But by having at most two @@ -1051,8 +1059,6 @@ file_paths.push_back(TestFile(kFileVideoVP9)); file_paths.push_back(TestFile(kFileAudioOgg)); - WaitForTestSystemAppInstall(); - for (const auto& file_path : file_paths) { std::vector<file_manager::file_tasks::FullTaskDescriptor> result = file_manager::test::GetTasksForFile(profile(), file_path); @@ -1070,8 +1076,7 @@ EXPECT_EQ("Gallery", task.task_title); EXPECT_EQ(extensions::api::file_manager_private::Verb::VERB_NONE, task.task_verb); - EXPECT_EQ(descriptor.app_id, - *GetManager().GetAppIdForSystemApp(ash::SystemWebAppType::MEDIA)); + EXPECT_EQ(descriptor.app_id, MediaAppAppId()); EXPECT_EQ(ash::kChromeUIMediaAppURL, descriptor.action_id); EXPECT_EQ(file_manager::file_tasks::TASK_TYPE_WEB_APP, descriptor.task_type); @@ -1080,8 +1085,6 @@ IN_PROC_BROWSER_TEST_P(MediaAppIntegrationAllProfilesTest, ShownInLauncherAndSearch) { - WaitForTestSystemAppInstall(); - // Check system_web_app_manager has the correct attributes for Media App. auto* system_app = GetManager().GetSystemApp(ash::SystemWebAppType::MEDIA); EXPECT_TRUE(system_app->ShouldShowInLauncher()); @@ -1092,8 +1095,6 @@ // features::MediaAppHandlesPdf. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationPdfDisabledTest, HiddenInLauncherAndSearch) { - WaitForTestSystemAppInstall(); - // Check system_web_app_manager has the correct attributes for Media App. auto* system_app = GetManager().GetSystemApp(ash::SystemWebAppType::MEDIA); EXPECT_FALSE(system_app->ShouldShowInLauncher()); @@ -1107,8 +1108,7 @@ MockCrashEndpoint endpoint(embedded_test_server()); ScopedMockChromeJsErrorReportProcessor processor(endpoint); - WaitForTestSystemAppInstall(); - content::WebContents* web_ui = LaunchApp(ash::SystemWebAppType::MEDIA); + content::WebContents* web_ui = LaunchWithNoFiles(); // Pass multiple arguments to console.error() to also check they are parsed // and captured in the error message correctly. @@ -1129,8 +1129,7 @@ MockCrashEndpoint endpoint(embedded_test_server()); ScopedMockChromeJsErrorReportProcessor processor(endpoint); - WaitForTestSystemAppInstall(); - content::WebContents* web_ui = LaunchApp(ash::SystemWebAppType::MEDIA); + content::WebContents* web_ui = LaunchWithNoFiles(); EXPECT_EQ(true, ExecuteScript(web_ui, kDomExceptionScript)); auto report = endpoint.WaitForReport(); @@ -1146,8 +1145,7 @@ MockCrashEndpoint endpoint(embedded_test_server()); ScopedMockChromeJsErrorReportProcessor processor(endpoint); - WaitForTestSystemAppInstall(); - content::WebContents* app = LaunchApp(ash::SystemWebAppType::MEDIA); + content::WebContents* app = LaunchWithNoFiles(); EXPECT_EQ(true, MediaAppUiBrowserTest::EvalJsInAppFrame(app, kDomExceptionScript)); @@ -1163,8 +1161,7 @@ MockCrashEndpoint endpoint(embedded_test_server()); ScopedMockChromeJsErrorReportProcessor processor(endpoint); - WaitForTestSystemAppInstall(); - content::WebContents* web_ui = LaunchApp(ash::SystemWebAppType::MEDIA); + content::WebContents* web_ui = LaunchWithNoFiles(); EXPECT_EQ(true, ExecuteScript(web_ui, kUnhandledRejectionScript)); auto report = endpoint.WaitForReport(); @@ -1180,8 +1177,7 @@ MockCrashEndpoint endpoint(embedded_test_server()); ScopedMockChromeJsErrorReportProcessor processor(endpoint); - WaitForTestSystemAppInstall(); - content::WebContents* app = LaunchApp(ash::SystemWebAppType::MEDIA); + content::WebContents* app = LaunchWithNoFiles(); EXPECT_EQ(true, MediaAppUiBrowserTest::EvalJsInAppFrame( app, kUnhandledRejectionScript)); @@ -1196,8 +1192,7 @@ MockCrashEndpoint endpoint(embedded_test_server()); ScopedMockChromeJsErrorReportProcessor processor(endpoint); - WaitForTestSystemAppInstall(); - content::WebContents* web_ui = LaunchApp(ash::SystemWebAppType::MEDIA); + content::WebContents* web_ui = LaunchWithNoFiles(); EXPECT_EQ(true, ExecuteScript(web_ui, kTypeErrorScript)); auto report = endpoint.WaitForReport(); @@ -1214,8 +1209,7 @@ MockCrashEndpoint endpoint(embedded_test_server()); ScopedMockChromeJsErrorReportProcessor processor(endpoint); - WaitForTestSystemAppInstall(); - content::WebContents* app = LaunchApp(ash::SystemWebAppType::MEDIA); + content::WebContents* app = LaunchWithNoFiles(); EXPECT_EQ(true, MediaAppUiBrowserTest::EvalJsInAppFrame(app, kTypeErrorScript)); @@ -1233,7 +1227,6 @@ FileOpenUsesMediaApp) { base::HistogramTester histograms; - WaitForTestSystemAppInstall(); Browser* test_browser = chrome::FindBrowserWithActiveWindow(); file_manager::test::FolderInMyFiles folder(profile()); @@ -1253,7 +1246,7 @@ // Check that chrome://media-app launched and the test file loads. EXPECT_NE(test_browser, app_browser); EXPECT_EQ(web_app::GetAppIdFromApplicationName(app_browser->app_name()), - *GetManager().GetAppIdForSystemApp(ash::SystemWebAppType::MEDIA)); + MediaAppAppId()); EXPECT_EQ("800x600", WaitForImageAlt(web_ui, kFilePng800x600)); // Check the metric is recorded. @@ -1309,9 +1302,7 @@ IN_PROC_BROWSER_TEST_P(MediaAppIntegrationDarkLightModeEnabledTest, HasCorrectThemeAndBackgroundColor) { - WaitForTestSystemAppInstall(); - web_app::AppId app_id = - *GetManager().GetAppIdForSystemApp(ash::SystemWebAppType::MEDIA); + web_app::AppId app_id = MediaAppAppId(); web_app::WebAppRegistrar& registrar = web_app::WebAppProvider::GetForTest(profile())->registrar(); @@ -1325,9 +1316,7 @@ IN_PROC_BROWSER_TEST_P(MediaAppIntegrationDarkLightModeDisabledTest, HasCorrectThemeAndBackgroundColor) { - WaitForTestSystemAppInstall(); - web_app::AppId app_id = - *GetManager().GetAppIdForSystemApp(ash::SystemWebAppType::MEDIA); + web_app::AppId app_id = MediaAppAppId(); web_app::WebAppRegistrar& registrar = web_app::WebAppProvider::GetForTest(profile())->registrar(); @@ -1342,8 +1331,6 @@ FileOpenCanLaunchBothAudioAndImages) { base::HistogramTester histograms; - WaitForTestSystemAppInstall(); - file_manager::test::FolderInMyFiles folder(profile()); folder.Add({TestFile(kFileJpeg640x480), TestFile(kFileAudioOgg)}); @@ -1463,8 +1450,6 @@ // that was opened, even if those files have changed since launch. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationWithFilesAppAllProfilesTest, FileOpenCanTraverseDirectory) { - WaitForTestSystemAppInstall(); - // Initialize a folder with 2 files: 1 JPEG, 1 PNG. Note this approach doesn't // guarantee the modification times of the files so, and therefore does not // suggest an ordering to the files of the directory contents. But by having @@ -1522,8 +1507,6 @@ // Integration test for rename using the WritableFileSystem and Streams APIs. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationWithFilesAppAllProfilesTest, RenameFile) { - WaitForTestSystemAppInstall(); - file_manager::test::FolderInMyFiles folder(profile()); folder.Add({TestFile(kFileJpeg640x480)}); folder.Open(TestFile(kFileJpeg640x480)); @@ -1561,8 +1544,6 @@ // Integration test for deleting a file using the WritableFiles API. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationWithFilesAppTest, DeleteFile) { - WaitForTestSystemAppInstall(); - file_manager::test::FolderInMyFiles folder(profile()); folder.Add({ TestFile(kFileJpeg640x480), @@ -1590,8 +1571,6 @@ // Integration test for deleting a special file using the WritableFiles API. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationWithFilesAppTest, FailToDeleteReservedFile) { - WaitForTestSystemAppInstall(); - file_manager::test::FolderInMyFiles folder(profile()); // Files like "thumbs.db" can't be accessed by filename using WritableFiles. @@ -1622,8 +1601,6 @@ } IN_PROC_BROWSER_TEST_P(MediaAppIntegrationWithFilesAppTest, CheckArcWritable) { - WaitForTestSystemAppInstall(); - base::ScopedAllowBlockingForTesting allow_blocking; // Create a new filesystem which represents a mounted archive. ARC should @@ -1664,8 +1641,6 @@ IN_PROC_BROWSER_TEST_P(MediaAppIntegrationWithFilesAppTest, CheckBrowserWritable) { - WaitForTestSystemAppInstall(); - file_manager::test::FolderInMyFiles folder(profile()); folder.Add({ TestFile(kFileJpeg640x480),
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 530cb72..59e66dc 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -6532,14 +6532,14 @@ // ScreenAI service needs read access to ScreenAI component path, so that it // would be able to find the latest downloaded version, and load its binary // and all enclosed model files. - base::FilePath screen_ai_component_path = screen_ai::GetComponentPath(); - if (screen_ai_component_path.empty()) { - VLOG(1) << "Screen AI library not found."; + base::FilePath screen_ai_component_dir = screen_ai::GetComponentDir(); + if (screen_ai_component_dir.empty()) { + VLOG(1) << "Screen AI component not found."; return false; } CHECK(client->SetParameter(sandbox::policy::kParamScreenAiComponentPath, - screen_ai_component_path.value())); + screen_ai_component_dir.value())); return true; #endif }
diff --git a/chrome/browser/chromeos/extensions/default_app_order.cc b/chrome/browser/chromeos/extensions/default_app_order.cc index 96bc7f05..125d8214 100644 --- a/chrome/browser/chromeos/extensions/default_app_order.cc +++ b/chrome/browser/chromeos/extensions/default_app_order.cc
@@ -173,17 +173,18 @@ web_app::kCalculatorAppId, extension_misc::kCalculatorAppId, + web_app::kMediaAppId, web_app::kCursiveAppId, web_app::kCanvasAppId, + + ash::kChromeUITrustedProjectorSwaAppId, extension_misc::kTextEditorAppId, + guest_os::kTerminalSystemAppId, + web_app::kYoutubeTVAppId, web_app::kGoogleNewsAppId, extensions::kWebStoreAppId, - guest_os::kTerminalSystemAppId, - web_app::kMediaAppId, - ash::kChromeUITrustedProjectorSwaAppId, - arc::kLightRoomAppId, arc::kInfinitePainterAppId, web_app::kShowtimeAppId,
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc index a195f10..f62cc0b 100644 --- a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc +++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
@@ -273,11 +273,10 @@ for (size_t i = 0; i < std::size(kTestMountPoints); i++) { mount_points_.insert(DiskMountManager::MountPointMap::value_type( kTestMountPoints[i].mount_path, - DiskMountManager::MountPointInfo(kTestMountPoints[i].source_path, - kTestMountPoints[i].mount_path, - kTestMountPoints[i].mount_type, - kTestMountPoints[i].mount_condition) - )); + DiskMountManager::MountPoint{kTestMountPoints[i].source_path, + kTestMountPoints[i].mount_path, + kTestMountPoints[i].mount_type, + kTestMountPoints[i].mount_condition})); int disk_info_index = kTestMountPoints[i].disk_info_index; if (kTestMountPoints[i].disk_info_index >= 0) { EXPECT_GT(std::size(kTestDisks), static_cast<size_t>(disk_info_index)); @@ -333,10 +332,9 @@ ash::MountType type, chromeos::MountAccessMode access_mode, DiskMountManager::MountPathCallback callback) { - auto mount_point_info = DiskMountManager::MountPointInfo( + DiskMountManager::MountPoint mount_point_info{ source_path, "/media/fuse/" + mount_label, - ash::MountType::kNetworkStorage, - ash::disks::MountCondition::MOUNT_CONDITION_NONE); + ash::MountType::kNetworkStorage}; disk_mount_manager_mock_->NotifyMountEvent( DiskMountManager::MountEvent::MOUNTING, chromeos::MountError::kNone, mount_point_info); @@ -777,11 +775,7 @@ base::BindRepeating(&FileManagerPrivateApiDlpTest::SetDlpRulesManager, base::Unretained(this))); ASSERT_TRUE(policy::DlpRulesManagerFactory::GetForPrimaryProfile()); - EXPECT_CALL(*mock_rules_manager_, IsFilesPolicyEnabled).Times(2); - // TODO(crbug.com/1346254): When implementation is completed, add following - // checks: EXPECT_CALL(*mock_rules_manager_, - // GetAggregatedComponents).Times(1); EXPECT_CALL(*mock_rules_manager_, - // GetAggregatedDestinations).Times(1); + EXPECT_CALL(*mock_rules_manager_, IsFilesPolicyEnabled).Times(1); AddLocalFileSystem(browser()->profile(), temp_dir_.GetPath()); @@ -828,6 +822,40 @@ {.load_as_component = true})); } +IN_PROC_BROWSER_TEST_F(FileManagerPrivateApiDlpTest, DlpRestrictionDetails) { + policy::DlpRulesManagerFactory::GetInstance()->SetTestingFactory( + browser()->profile(), + base::BindRepeating(&FileManagerPrivateApiDlpTest::SetDlpRulesManager, + base::Unretained(this))); + ASSERT_TRUE(policy::DlpRulesManagerFactory::GetForPrimaryProfile()); + EXPECT_CALL(*mock_rules_manager_, IsFilesPolicyEnabled).Times(1); + + policy::DlpRulesManager::AggregatedDestinations destinations; + destinations[policy::DlpRulesManager::Level::kBlock].insert( + "https://external.com"); + destinations[policy::DlpRulesManager::Level::kAllow].insert( + "https://internal.com"); + policy::DlpRulesManager::AggregatedComponents components; + components[policy::DlpRulesManager::Level::kBlock].insert( + policy::DlpRulesManager::Component::kArc); + components[policy::DlpRulesManager::Level::kBlock].insert( + policy::DlpRulesManager::Component::kCrostini); + components[policy::DlpRulesManager::Level::kBlock].insert( + policy::DlpRulesManager::Component::kPluginVm); + components[policy::DlpRulesManager::Level::kBlock].insert( + policy::DlpRulesManager::Component::kUsb); + components[policy::DlpRulesManager::Level::kAllow].insert( + policy::DlpRulesManager::Component::kDrive); + EXPECT_CALL(*mock_rules_manager_, GetAggregatedDestinations) + .WillOnce(testing::Return(destinations)); + EXPECT_CALL(*mock_rules_manager_, GetAggregatedComponents) + .WillOnce(testing::Return(components)); + + EXPECT_TRUE(RunExtensionTest("file_browser/dlp_metadata", + {.custom_arg = "restriction_details"}, + {.load_as_component = true})); +} + IN_PROC_BROWSER_TEST_F(FileManagerPrivateApiDlpTest, DlpMetadata_Disabled) { policy::DlpRulesManagerFactory::GetInstance()->SetTestingFactory( browser()->profile(),
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc index dda9156..81ce5443 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -10,6 +10,7 @@ #include <algorithm> #include <cctype> #include <cstdint> +#include <iterator> #include <memory> #include <utility> #include <vector> @@ -21,8 +22,10 @@ #include "base/files/file.h" #include "base/files/file_enumerator.h" #include "base/files/file_util.h" +#include "base/notreached.h" #include "base/numerics/safe_conversions.h" #include "base/posix/eintr_wrapper.h" +#include "base/ranges/algorithm.h" #include "base/strings/escape.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" @@ -424,6 +427,53 @@ return {}; } +extensions::api::file_manager_private::DlpLevel DlpRulesManagerLevelToApiEnum( + policy::DlpRulesManager::Level level) { + using extensions::api::file_manager_private::DlpLevel; + switch (level) { + case policy::DlpRulesManager::Level::kAllow: + return DlpLevel::DLP_LEVEL_ALLOW; + case policy::DlpRulesManager::Level::kBlock: + return DlpLevel::DLP_LEVEL_BLOCK; + case policy::DlpRulesManager::Level::kWarn: + case policy::DlpRulesManager::Level::kReport: + NOTIMPLEMENTED() + << "Warn and Report DLP levels for Files are not supported yet."; + // TODO(https://crbug.com/1172959): Implement Warn level for Files. + // TODO: Implement Report level for Files. + return DlpLevel::DLP_LEVEL_NONE; + case policy::DlpRulesManager::Level::kNotSet: + NOTREACHED() << "DLP level not set."; + return DlpLevel::DLP_LEVEL_NONE; + } + NOTREACHED() << "Unknown DLP level."; + return {}; +} + +extensions::api::file_manager_private::VolumeType +DlpRulesManagerComponentToApiEnum( + policy::DlpRulesManager::Component component) { + using extensions::api::file_manager_private::VolumeType; + using Component = policy::DlpRulesManager::Component; + switch (component) { + case policy::DlpRulesManager::Component::kArc: + return VolumeType::VOLUME_TYPE_ANDROID_FILES; + case policy::DlpRulesManager::Component::kCrostini: + return VolumeType::VOLUME_TYPE_CROSTINI; + case policy::DlpRulesManager::Component::kPluginVm: + return VolumeType::VOLUME_TYPE_GUEST_OS; + case policy::DlpRulesManager::Component::kUsb: + return VolumeType::VOLUME_TYPE_REMOVABLE; + case policy::DlpRulesManager::Component::kDrive: + return VolumeType::VOLUME_TYPE_DRIVE; + case policy::DlpRulesManager::Component::kUnknownComponent: + NOTREACHED() << "DLP component not set."; + return {}; + } + NOTREACHED() << "Unknown component type."; + return {}; +} + } // namespace ExtensionFunction::ResponseAction @@ -1127,7 +1177,7 @@ FileManagerPrivateGetDlpRestrictionDetailsFunction::Run() { if (!base::FeatureList::IsEnabled( features::kDataLeakPreventionFilesRestriction)) { - return RespondNow(NoArguments()); + return RespondNow(OneArgument(base::Value(base::Value::Type::LIST))); } policy::DlpRulesManager* rules_manager = @@ -1140,9 +1190,30 @@ const std::unique_ptr<Params> params(Params::Create(args())); EXTENSION_FUNCTION_VALIDATE(params); - // TODO(crbug.com/1346254): Call DlpFilesController to get the details. + std::unique_ptr<policy::DlpFilesController> files_controller = + std::make_unique<policy::DlpFilesController>(); + const std::vector<policy::DlpFilesController::DlpFileRestrictionDetails> + dlp_restriction_details = + files_controller->GetDlpRestrictionDetails(params->source_url); - return RespondNow(OneArgument(base::Value(base::Value::Type::LIST))); + using extensions::api::file_manager_private::DlpRestrictionDetails; + std::vector<DlpRestrictionDetails> converted_list; + + for (const auto& [level, urls, components] : dlp_restriction_details) { + DlpRestrictionDetails details; + details.level = DlpRulesManagerLevelToApiEnum(level); + base::ranges::move(urls.begin(), urls.end(), + std::back_inserter(details.urls)); + for (const auto& component : components) { + details.components.push_back( + DlpRulesManagerComponentToApiEnum(component)); + } + converted_list.emplace_back(std::move(details)); + } + + return RespondNow(ArgumentList( + api::file_manager_private::GetDlpRestrictionDetails::Results::Create( + converted_list))); } FileManagerPrivateInternalStartCopyFunction::
diff --git a/chrome/browser/component_updater/screen_ai_component_installer.cc b/chrome/browser/component_updater/screen_ai_component_installer.cc index 4502262..3a9ff6a 100644 --- a/chrome/browser/component_updater/screen_ai_component_installer.cc +++ b/chrome/browser/component_updater/screen_ai_component_installer.cc
@@ -76,10 +76,8 @@ bool ScreenAIComponentInstallerPolicy::VerifyInstallation( const base::Value& manifest, const base::FilePath& install_dir) const { - // TODO(https://crbug.com/1278249): Consider trying to open and initialize the - // library. - VLOG(1) << "Verifying Screen AI Library in " << install_dir.value(); - return screen_ai::GetLatestLibraryFilePath().DirName() == install_dir; + VLOG(1) << "Verifying Screen AI component in " << install_dir.value(); + return screen_ai::GetLatestComponentBinaryPath().DirName() == install_dir; } base::FilePath ScreenAIComponentInstallerPolicy::GetRelativeInstallDir() const { @@ -104,8 +102,9 @@ // static void ScreenAIComponentInstallerPolicy::DeleteLibraryOrScheduleDeletionIfNeeded( PrefService* global_prefs) { - base::FilePath library_path = screen_ai::GetLatestLibraryFilePath(); - if (library_path.empty()) + base::FilePath component_binary_path = + screen_ai::GetLatestComponentBinaryPath(); + if (component_binary_path.empty()) return; base::Time deletion_time = @@ -122,9 +121,9 @@ if (deletion_time <= base::Time::Now()) { // If there are more than one instance of the library, delete them as well. do { - base::DeletePathRecursively(library_path.DirName()); - library_path = screen_ai::GetLatestLibraryFilePath(); - } while (!library_path.empty()); + base::DeletePathRecursively(component_binary_path.DirName()); + component_binary_path = screen_ai::GetLatestComponentBinaryPath(); + } while (!component_binary_path.empty()); global_prefs->SetTime(prefs::kScreenAIScheduledDeletionTimePrefName, base::Time()); }
diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc index 58646c0..2ade21ba 100644 --- a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc +++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
@@ -98,7 +98,7 @@ DCHECK(!g_instance); g_instance = this; -#if !BUILDFLAG(IS_CHROMEOS_ASH) +#if !BUILDFLAG(IS_CHROMEOS) // Only create and hold keep alive for automation test for non ChromeOS. // ChromeOS automation test (aka tast) manages chrome instance via session // manager daemon. The extra keep alive is not needed and makes ChromeOS
diff --git a/chrome/browser/extensions/api/virtual_keyboard_private/virtual_keyboard_private_apitest.cc b/chrome/browser/extensions/api/virtual_keyboard_private/virtual_keyboard_private_apitest.cc index 0ad00574..304c582 100644 --- a/chrome/browser/extensions/api/virtual_keyboard_private/virtual_keyboard_private_apitest.cc +++ b/chrome/browser/extensions/api/virtual_keyboard_private/virtual_keyboard_private_apitest.cc
@@ -77,7 +77,13 @@ } }; -IN_PROC_BROWSER_TEST_F(VirtualKeyboardPrivateApiTest, Multipaste) { +// TODO(crbug.com/1352320): Flaky on release bots. +#if defined(NDEBUG) +#define MAYBE_Multipaste DISABLED_Multipaste +#else +#define MAYBE_Multipaste Multipaste +#endif +IN_PROC_BROWSER_TEST_F(VirtualKeyboardPrivateApiTest, MAYBE_Multipaste) { // Copy to the clipboard an item of each display format type. CopyHtmlItem(); CopyTextItem();
diff --git a/chrome/browser/fast_checkout/fast_checkout_capabilities_results_cache.cc b/chrome/browser/fast_checkout/fast_checkout_capabilities_results_cache.cc new file mode 100644 index 0000000..9b6401c --- /dev/null +++ b/chrome/browser/fast_checkout/fast_checkout_capabilities_results_cache.cc
@@ -0,0 +1,84 @@ +// Copyright 2022 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/fast_checkout/fast_checkout_capabilities_results_cache.h" + +#include <map> +#include <utility> +#include <vector> + +#include "base/time/time.h" +#include "components/autofill/core/common/signatures.h" +#include "url/origin.h" + +FastCheckoutCapabilitiesResult::FastCheckoutCapabilitiesResult( + base::span<const autofill::FormSignature> signatures) + : form_signatures_(signatures.begin(), signatures.end()) {} + +FastCheckoutCapabilitiesResult::~FastCheckoutCapabilitiesResult() = default; + +FastCheckoutCapabilitiesResult::FastCheckoutCapabilitiesResult( + const FastCheckoutCapabilitiesResult& other) = default; + +bool FastCheckoutCapabilitiesResult::SupportsForm( + autofill::FormSignature form_signature) const { + return form_signatures_.contains(form_signature); +} + +FastCheckoutCapabilitiesResultsCache::FastCheckoutCapabilitiesResultsCache() = + default; + +FastCheckoutCapabilitiesResultsCache::~FastCheckoutCapabilitiesResultsCache() = + default; + +FastCheckoutCapabilitiesResultsCache::FastCheckoutCapabilitiesResultsCache( + const FastCheckoutCapabilitiesResultsCache& other) = default; + +void FastCheckoutCapabilitiesResultsCache::AddToCache( + const url::Origin& origin, + const FastCheckoutCapabilitiesResult& result) { + RemoveStaleEntries(); + DCHECK(retrieval_times_.size() <= kMaxSize); + if (retrieval_times_.size() == kMaxSize) { + // TODO(crbug.com/1350456): Record a UMA metric to indicate cache overflow. + RemoveOldestEntry(); + } + + if (ContainsOrigin(origin)) + return; + + capabilities_.emplace(origin, result); + retrieval_times_.emplace(origin, base::TimeTicks::Now()); +} + +bool FastCheckoutCapabilitiesResultsCache::ContainsOrigin( + const url::Origin& origin) { + RemoveStaleEntries(); + return capabilities_.find(origin) != capabilities_.end(); +} + +bool FastCheckoutCapabilitiesResultsCache::ContainsTriggerForm( + const url::Origin& origin, + autofill::FormSignature form_signature) { + RemoveStaleEntries(); + std::map<url::Origin, FastCheckoutCapabilitiesResult>::iterator entry = + capabilities_.find(origin); + return (entry != capabilities_.end() && + entry->second.SupportsForm(form_signature)); +} + +void FastCheckoutCapabilitiesResultsCache::RemoveOldestEntry() { + DCHECK(!retrieval_times_.empty()); + capabilities_.erase(retrieval_times_.front().first); + retrieval_times_.pop(); +} + +void FastCheckoutCapabilitiesResultsCache::RemoveStaleEntries() { + base::TimeTicks now = base::TimeTicks::Now(); + + while (!retrieval_times_.empty() && + now - retrieval_times_.front().second > kLifetime) { + RemoveOldestEntry(); + } +}
diff --git a/chrome/browser/fast_checkout/fast_checkout_capabilities_results_cache.h b/chrome/browser/fast_checkout/fast_checkout_capabilities_results_cache.h new file mode 100644 index 0000000..1a441e3 --- /dev/null +++ b/chrome/browser/fast_checkout/fast_checkout_capabilities_results_cache.h
@@ -0,0 +1,82 @@ +// Copyright 2022 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_FAST_CHECKOUT_FAST_CHECKOUT_CAPABILITIES_RESULTS_CACHE_H_ +#define CHROME_BROWSER_FAST_CHECKOUT_FAST_CHECKOUT_CAPABILITIES_RESULTS_CACHE_H_ + +#include <map> +#include <utility> + +#include "base/containers/flat_set.h" +#include "base/containers/queue.h" +#include "base/containers/span.h" +#include "base/time/time.h" +#include "components/autofill/core/common/signatures.h" + +namespace url { +class Origin; +} // namespace url + +// A data structure that contains the signatures of forms that may trigger +// a FastCheckout flow on a given origin. +class FastCheckoutCapabilitiesResult { + public: + explicit FastCheckoutCapabilitiesResult( + base::span<const autofill::FormSignature> signatures); + virtual ~FastCheckoutCapabilitiesResult(); + + FastCheckoutCapabilitiesResult(const FastCheckoutCapabilitiesResult& other); + + bool SupportsForm(autofill::FormSignature form_signature) const; + + private: + // The set of signatures supported. The number of entries is expected to be + // `O(1)` and often zero. + base::flat_set<autofill::FormSignature> form_signatures_; +}; + +// A cache of `CapabilitiesResult` entries that has both a maximum age and a +// maximum size. +class FastCheckoutCapabilitiesResultsCache { + public: + // The maximum number of cache entries. + static constexpr size_t kMaxSize = 100u; + // The lifetime of a cache entry - entries older than this are purged. + static constexpr base::TimeDelta kLifetime = base::Minutes(10); + + FastCheckoutCapabilitiesResultsCache(); + virtual ~FastCheckoutCapabilitiesResultsCache(); + + FastCheckoutCapabilitiesResultsCache( + const FastCheckoutCapabilitiesResultsCache& other); + + // Adds a new `result` for `origin` to the cache. If the cache is already + // full (i.e. it has `kMaxSize` entries), it removes the oldest entry. + void AddToCache(const url::Origin& origin, + const FastCheckoutCapabilitiesResult& result); + + // Returns whether an up-to-date entry for `origin` exists in the cache. + bool ContainsOrigin(const url::Origin& origin); + + // Returns whether there is a cache entry that the form with `form_signature` + // on `origin` is supported. + bool ContainsTriggerForm(const url::Origin& origin, + autofill::FormSignature form_signature); + + private: + // Removes the oldest cache entry. Assumes that the cache is non-empty. + void RemoveOldestEntry(); + + // Removes entries that are older than `kLifetime`. + void RemoveStaleEntries(); + + // The `CapabilitiesResult`s contained in the cache. + std::map<url::Origin, FastCheckoutCapabilitiesResult> capabilities_; + + // The contained origins by their retrieval time. The container is ordered + // ascendingly by retrieval time. + base::queue<std::pair<url::Origin, base::TimeTicks>> retrieval_times_; +}; + +#endif // CHROME_BROWSER_FAST_CHECKOUT_FAST_CHECKOUT_CAPABILITIES_RESULTS_CACHE_H_
diff --git a/chrome/browser/fast_checkout/fast_checkout_capabilities_results_cache_unittest.cc b/chrome/browser/fast_checkout/fast_checkout_capabilities_results_cache_unittest.cc new file mode 100644 index 0000000..9453abe --- /dev/null +++ b/chrome/browser/fast_checkout/fast_checkout_capabilities_results_cache_unittest.cc
@@ -0,0 +1,144 @@ +// Copyright 2022 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/fast_checkout/fast_checkout_capabilities_results_cache.h" + +#include <array> +#include <vector> + +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "base/test/task_environment.h" +#include "base/time/time.h" +#include "components/autofill/core/common/signatures.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace { + +using autofill::FormSignature; + +constexpr char kOrigin1[] = "example.co.uk"; +constexpr char kOrigin2[] = "example.com"; +constexpr char kOrigin3[] = "another-example.com"; + +constexpr std::array<FormSignature, 3> kSignatures1 = { + FormSignature(1), FormSignature(2456), FormSignature(365)}; +constexpr std::array<FormSignature, 2> kSignatures2 = {FormSignature(10), + FormSignature(246)}; +constexpr std::array<FormSignature, 4> kSignatures3 = { + FormSignature(1), FormSignature(23), FormSignature(39), FormSignature(100)}; +constexpr std::array<FormSignature, 0> kEmptySignatures = {}; + +constexpr FormSignature kSignatureNotIn1 = FormSignature(5); + +// Tests of `FastCheckoutCapabilitiesResultsCache`. +class FastCheckoutCapabilitiesResultsCacheTest : public ::testing::Test { + protected: + FastCheckoutCapabilitiesResultsCache& cache() { return cache_; } + + void AdvanceClock(base::TimeDelta duration) { + task_environment_.AdvanceClock(duration); + } + + private: + // Test support. + base::test::TaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + + // The object to test. + FastCheckoutCapabilitiesResultsCache cache_; +}; + +TEST(CapabilitiesResultTest, SupportsForm) { + FastCheckoutCapabilitiesResult result{kSignatures1}; + + for (auto signature : kSignatures1) { + EXPECT_TRUE(result.SupportsForm(signature)) + << "signature should be supported: " << signature; + } + EXPECT_FALSE(result.SupportsForm(kSignatureNotIn1)); +} + +TEST_F(FastCheckoutCapabilitiesResultsCacheTest, AddToCache) { + url::Origin origin1 = url::Origin::Create(GURL(kOrigin1)); + url::Origin origin2 = url::Origin::Create(GURL(kOrigin2)); + url::Origin origin3 = url::Origin::Create(GURL(kOrigin3)); + + EXPECT_FALSE(cache().ContainsOrigin(origin1)); + EXPECT_FALSE(cache().ContainsTriggerForm(origin1, kSignatures1.front())); + EXPECT_FALSE(cache().ContainsOrigin(origin2)); + EXPECT_FALSE(cache().ContainsTriggerForm(origin2, kSignatures2.front())); + EXPECT_FALSE(cache().ContainsOrigin(origin3)); + EXPECT_FALSE(cache().ContainsTriggerForm(origin3, kSignatures3.front())); + + cache().AddToCache(origin1, FastCheckoutCapabilitiesResult(kSignatures1)); + cache().AddToCache(origin2, FastCheckoutCapabilitiesResult(kSignatures2)); + cache().AddToCache(origin3, FastCheckoutCapabilitiesResult(kSignatures3)); + + EXPECT_TRUE(cache().ContainsOrigin(origin1)); + EXPECT_TRUE(cache().ContainsTriggerForm(origin1, kSignatures1.front())); + EXPECT_FALSE(cache().ContainsTriggerForm(origin1, kSignatureNotIn1)); + EXPECT_TRUE(cache().ContainsOrigin(origin2)); + EXPECT_TRUE(cache().ContainsTriggerForm(origin2, kSignatures2.front())); + EXPECT_TRUE(cache().ContainsOrigin(origin3)); + EXPECT_TRUE(cache().ContainsTriggerForm(origin3, kSignatures3.front())); +} + +TEST_F(FastCheckoutCapabilitiesResultsCacheTest, AddToCacheWithAdvancedClock) { + url::Origin origin1 = url::Origin::Create(GURL(kOrigin1)); + url::Origin origin2 = url::Origin::Create(GURL(kOrigin2)); + + EXPECT_FALSE(cache().ContainsOrigin(origin1)); + EXPECT_FALSE(cache().ContainsTriggerForm(origin1, kSignatures1.front())); + EXPECT_FALSE(cache().ContainsOrigin(origin2)); + EXPECT_FALSE(cache().ContainsTriggerForm(origin2, kSignatures2.front())); + + cache().AddToCache(origin1, FastCheckoutCapabilitiesResult(kSignatures1)); + + EXPECT_TRUE(cache().ContainsOrigin(origin1)); + EXPECT_FALSE(cache().ContainsOrigin(origin2)); + + AdvanceClock(base::Minutes(6)); + cache().AddToCache(origin2, FastCheckoutCapabilitiesResult(kSignatures2)); + + EXPECT_TRUE(cache().ContainsOrigin(origin1)); + EXPECT_TRUE(cache().ContainsOrigin(origin2)); + + AdvanceClock(base::Minutes(6)); + + EXPECT_FALSE(cache().ContainsOrigin(origin1)); + EXPECT_TRUE(cache().ContainsOrigin(origin2)); + + AdvanceClock(base::Minutes(6)); + EXPECT_FALSE(cache().ContainsOrigin(origin1)); + EXPECT_FALSE(cache().ContainsOrigin(origin2)); +} + +TEST_F(FastCheckoutCapabilitiesResultsCacheTest, AddToCacheWithMaxSizeReached) { + url::Origin origin1 = url::Origin::Create(GURL(kOrigin1)); + cache().AddToCache(origin1, FastCheckoutCapabilitiesResult(kSignatures1)); + EXPECT_TRUE(cache().ContainsOrigin(origin1)); + + // Add generic origins until the cache is full. + for (size_t index = 1; index < FastCheckoutCapabilitiesResultsCache::kMaxSize; + ++index) { + cache().AddToCache( + url::Origin::Create(GURL(base::StrCat( + {"example-page", base::NumberToString(index), ".de"}))), + FastCheckoutCapabilitiesResult(kEmptySignatures)); + } + + // The earliest entry should still be contained in the cache. + EXPECT_TRUE(cache().ContainsOrigin(origin1)); + + // Adding another entry purges the earliest one. + url::Origin origin2 = url::Origin::Create(GURL(kOrigin2)); + cache().AddToCache(origin2, FastCheckoutCapabilitiesResult(kSignatures2)); + EXPECT_FALSE(cache().ContainsOrigin(origin1)); + EXPECT_TRUE(cache().ContainsOrigin(origin2)); +} + +} // namespace
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index e54012eec..6ed002de 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1901,7 +1901,7 @@ { "name": "enable-cros-system-japanese-physical-typing", "owners": [ "keithlee", "essential-inputs-team@google.com" ], - "expiry_milestone": 105 + "expiry_milestone": 108 }, { "name": "enable-cros-system-korean-physical-typing", @@ -3448,6 +3448,11 @@ "expiry_milestone": 110 }, { + "name": "file-transfer-enterprise-connector", + "owners": [ "sseckler@google.com", "marcgrimme", "poromov" ], + "expiry_milestone": 130 + }, + { "name": "files-app-experimental", "owners": ["lucmult", "benreich", "simmonsjosh@google.com"], "expiry_milestone": 116 @@ -3842,20 +3847,9 @@ "expiry_milestone": -1 }, { - "name": "incognito-brand-consistency-for-android", - "owners": [ "sideyilmaz", "chrome-incognito@google.com" ], - "expiry_milestone": 105 - }, - - { - "name": "incognito-brand-consistency-for-ios", - "owners": [ "sideyilmaz", "chrome-incognito@google.com" ], - "expiry_milestone": 105 - }, - { "name": "incognito-downloads-warning", "owners": [ "sideyilmaz", "chrome-incognito@google.com" ], - "expiry_milestone": 105 + "expiry_milestone": 110 }, { "name": "incognito-ntp-revamp", @@ -6307,7 +6301,7 @@ { "name": "update-history-entry-points-in-incognito", "owners": [ "sideyilmaz", "chrome-incognito@google.com" ], - "expiry_milestone": 105 + "expiry_milestone": 108 }, { "name": "update-menu-item-custom-summary",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 2e8460d..f2c3510 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1648,12 +1648,6 @@ "Ensure keyboard shortcuts work consistently with international keyboard " "layouts and deprecate legacy shortcuts."; -const char kIncognitoBrandConsistencyForAndroidName[] = - "Enable Incognito brand consistency in Android."; -const char kIncognitoBrandConsistencyForAndroidDescription[] = - "When enabled, keeps Incognito UI consistent regardless of any selected " - "theme."; - const char kIncognitoDownloadsWarningName[] = "Enable Incognito downloads warning"; const char kIncognitoDownloadsWarningDescription[] = @@ -5230,6 +5224,11 @@ "Enable feature which adds ability for user to grab and resize divider of " "Docked Magnifier."; +const char kFileTransferEnterpriseConnectorName[] = + "Enable Files Transfer Enterprise Connector."; +const char kFileTransferEnterpriseConnectorDescription[] = + "Enable the File Transfer Enterprise Connector."; + const char kFilesAppExperimentalName[] = "Experimental UI features for Files app"; const char kFilesAppExperimentalDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 6e6a6b0..2fc50a4 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -922,9 +922,6 @@ extern const char kCompositorThreadedScrollbarScrollingName[]; extern const char kCompositorThreadedScrollbarScrollingDescription[]; -extern const char kIncognitoBrandConsistencyForAndroidName[]; -extern const char kIncognitoBrandConsistencyForAndroidDescription[]; - extern const char kIncognitoReauthenticationForAndroidName[]; extern const char kIncognitoReauthenticationForAndroidDescription[]; @@ -2983,6 +2980,9 @@ extern const char kDockedMagnifierResizingName[]; extern const char kDockedMagnifierResizingDescription[]; +extern const char kFileTransferEnterpriseConnectorName[]; +extern const char kFileTransferEnterpriseConnectorDescription[]; + extern const char kFilesAppExperimentalName[]; extern const char kFilesAppExperimentalDescription[];
diff --git a/chrome/browser/hid/hid_policy_allowed_devices.cc b/chrome/browser/hid/hid_policy_allowed_devices.cc index 628bb17..b0d56371 100644 --- a/chrome/browser/hid/hid_policy_allowed_devices.cc +++ b/chrome/browser/hid/hid_policy_allowed_devices.cc
@@ -120,14 +120,12 @@ device_policy_.clear(); vendor_policy_.clear(); - const auto* pref_value = pref_change_registrar_.prefs()->Get( + const auto& pref_value = pref_change_registrar_.prefs()->GetValueList( prefs::kManagedWebHidAllowDevicesForUrls); - if (!pref_value) - return; // The pref value has already been validated by the policy handler, so it is // safe to assume that |pref_value| follows the policy template. - for (const auto& item : pref_value->GetListDeprecated()) { + for (const auto& item : pref_value) { const base::Value* urls_value = item.FindKey(kPrefUrlsKey); DCHECK(urls_value);
diff --git a/chrome/browser/media/android/cdm/media_drm_origin_id_manager.cc b/chrome/browser/media/android/cdm/media_drm_origin_id_manager.cc index fe4d872..cc7720c 100644 --- a/chrome/browser/media/android/cdm/media_drm_origin_id_manager.cc +++ b/chrome/browser/media/android/cdm/media_drm_origin_id_manager.cc
@@ -133,19 +133,15 @@ return true; } -int CountAvailableOriginIds(const base::Value* origin_id_dict) { +int CountAvailableOriginIds(const base::Value::Dict& origin_id_dict) { DVLOG(3) << __func__; - if (!origin_id_dict || !origin_id_dict->is_dict()) - return 0; - - const base::Value* origin_ids = - origin_id_dict->FindKeyOfType(kOriginIds, base::Value::Type::LIST); + const base::Value::List* origin_ids = origin_id_dict.FindList(kOriginIds); if (!origin_ids) return 0; - DVLOG(3) << "count: " << origin_ids->GetListDeprecated().size(); - return origin_ids->GetListDeprecated().size(); + DVLOG(3) << "count: " << origin_ids->size(); + return origin_ids->size(); } base::UnguessableToken TakeFirstOriginId(PrefService* const pref_service) { @@ -391,7 +387,8 @@ // No need to pre-provision if there are already enough existing // pre-provisioned origin IDs. - if (CountAvailableOriginIds(update.Get()) >= kMaxPreProvisionedOriginIds) { + if (CountAvailableOriginIds(update->GetDict()) >= + kMaxPreProvisionedOriginIds) { // Disable any network monitoring, if it exists. network_observer_.reset(); return; @@ -515,7 +512,8 @@ // If we already have enough pre-provisioned origin IDs, we're done. // Stop watching for network change events. - if (CountAvailableOriginIds(update.Get()) >= kMaxPreProvisionedOriginIds) { + if (CountAvailableOriginIds(update->GetDict()) >= + kMaxPreProvisionedOriginIds) { network_observer_.reset(); RemoveExpirableToken(update.Get()); is_provisioning_ = false; @@ -529,9 +527,8 @@ void MediaDrmOriginIdManager::RecordCountOfPreprovisionedOriginIds() { int available_origin_ids = 0; - const auto* pref = pref_service_->GetDictionary(kMediaDrmOriginIds); - if (pref) - available_origin_ids = CountAvailableOriginIds(pref); + const auto& pref = pref_service_->GetValueDict(kMediaDrmOriginIds); + available_origin_ids = CountAvailableOriginIds(pref); if (media::MediaDrmBridge::IsPerApplicationProvisioningSupported()) { UMA_HISTOGRAM_EXACT_LINEAR(
diff --git a/chrome/browser/media/cdm_pref_service_helper.cc b/chrome/browser/media/cdm_pref_service_helper.cc index 046ccd8..49a59bd 100644 --- a/chrome/browser/media/cdm_pref_service_helper.cc +++ b/chrome/browser/media/cdm_pref_service_helper.cc
@@ -70,10 +70,10 @@ // id and the time it was first created as well as the client token and the time // it was set/updated. Return nullptr if `cdm_data_dict` has any corruption, // e.g. format error, missing fields, invalid value. -std::unique_ptr<CdmPrefData> FromDictValue(const base::Value& cdm_data_dict) { - DCHECK(cdm_data_dict.is_dict()); +std::unique_ptr<CdmPrefData> FromDictValue( + const base::Value::Dict& cdm_data_dict) { // Origin ID - const base::Value* origin_id_value = cdm_data_dict.FindKey(kOriginId); + const base::Value* origin_id_value = cdm_data_dict.Find(kOriginId); if (!origin_id_value) return nullptr; @@ -82,7 +82,7 @@ if (!origin_id) return nullptr; - const base::Value* time_value = cdm_data_dict.FindKey(kOriginIdCreationTime); + const base::Value* time_value = cdm_data_dict.Find(kOriginIdCreationTime); if (!time_value) return nullptr; @@ -95,7 +95,7 @@ // Client Token const std::string* encoded_client_token = - cdm_data_dict.FindStringKey(kClientToken); + cdm_data_dict.FindString(kClientToken); if (encoded_client_token) { std::string decoded_client_token; if (!base::Base64Decode(*encoded_client_token, &decoded_client_token)) @@ -104,7 +104,7 @@ std::vector<uint8_t> client_token(decoded_client_token.begin(), decoded_client_token.end()); - time_value = cdm_data_dict.FindKey(kClientTokenCreationTime); + time_value = cdm_data_dict.Find(kClientTokenCreationTime); // If we have a client token but no creation time, this is an error. if (!time_value) @@ -191,7 +191,8 @@ continue; } - std::unique_ptr<CdmPrefData> cdm_pref_data = FromDictValue(origin_dict); + std::unique_ptr<CdmPrefData> cdm_pref_data = + FromDictValue(origin_dict.GetDict()); if (!cdm_pref_data) { origins_to_delete.push_back(origin); @@ -222,8 +223,8 @@ // Access to the PrefService must be made from the UI thread. DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - const base::Value* dict = - user_prefs->GetDictionary(prefs::kMediaCdmOriginData); + const base::Value::Dict& dict = + user_prefs->GetValueDict(prefs::kMediaCdmOriginData); DCHECK(!cdm_origin.opaque()); if (cdm_origin.opaque()) { @@ -234,8 +235,7 @@ const std::string serialized_cdm_origin = cdm_origin.Serialize(); DCHECK(!serialized_cdm_origin.empty()); - const base::Value* cdm_data_dict = - dict->FindKeyOfType(serialized_cdm_origin, base::Value::Type::DICTIONARY); + const base::Value::Dict* cdm_data_dict = dict.FindDict(serialized_cdm_origin); std::unique_ptr<CdmPrefData> cdm_pref_data; if (cdm_data_dict) @@ -269,10 +269,9 @@ DCHECK(!serialized_cdm_origin.empty()); DictionaryPrefUpdate update(user_prefs, prefs::kMediaCdmOriginData); - base::Value* dict = update.Get(); + base::Value::Dict& dict = update->GetDict(); - base::Value* dict_value = - dict->FindKeyOfType(serialized_cdm_origin, base::Value::Type::DICTIONARY); + base::Value::Dict* dict_value = dict.FindDict(serialized_cdm_origin); if (!dict_value) { // If there is no preference associated with the origin at this point, this // means that the preference data was deleted by the user recently. No need @@ -285,21 +284,21 @@ DVLOG(ERROR) << "The CDM preference data for origin \"" << serialized_cdm_origin << "\" could not be parsed. Removing entry from preferences."; - dict->RemoveKey(serialized_cdm_origin); + dict.Remove(serialized_cdm_origin); return; } cdm_pref_data->SetClientToken(client_token, base::Time::Now()); - dict->SetKey(serialized_cdm_origin, ToDictValue(*cdm_pref_data)); + dict.Set(serialized_cdm_origin, ToDictValue(*cdm_pref_data)); } std::map<std::string, url::Origin> CdmPrefServiceHelper::GetOriginIdMapping( PrefService* user_prefs) { std::map<std::string, url::Origin> mapping; - const base::Value* dict = - user_prefs->GetDictionary(prefs::kMediaCdmOriginData); + const base::Value::Dict& dict = + user_prefs->GetValueDict(prefs::kMediaCdmOriginData); - for (auto key_value : dict->DictItems()) { + for (auto key_value : dict) { const base::Value* origin_id_value = key_value.second.FindKey(kOriginId); if (!origin_id_value) continue;
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater.cc index 47926fe..08839a97 100644 --- a/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater.cc +++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater.cc
@@ -72,8 +72,8 @@ device_time_pref->SetKey(sink_id, base::TimeToValue(base::Time::Now())); } -const base::Value* AccessCodeCastPrefUpdater::GetDevicesDict() { - return pref_service_->GetDictionary(prefs::kAccessCodeCastDevices); +const base::Value::Dict& AccessCodeCastPrefUpdater::GetDevicesDict() { + return pref_service_->GetValueDict(prefs::kAccessCodeCastDevices); } const base::Value* AccessCodeCastPrefUpdater::GetDeviceAddedTimeDict() { @@ -83,24 +83,20 @@ const base::Value::List AccessCodeCastPrefUpdater::GetSinkIdsFromDevicesDict() { auto sink_ids = base::Value::List(); - auto* devices_dict = GetDevicesDict(); - if (devices_dict) { - for (auto sink_id_keypair : devices_dict->GetDict()) { - sink_ids.Append(sink_id_keypair.first); - } + const auto& devices_dict = GetDevicesDict(); + for (auto sink_id_keypair : devices_dict) { + sink_ids.Append(sink_id_keypair.first); } return sink_ids; } const base::Value* AccessCodeCastPrefUpdater::GetMediaSinkInternalValueBySinkId( const MediaSink::Id sink_id) { - auto* device_dict = GetDevicesDict(); - if (!device_dict) - return nullptr; + const auto& device_dict = GetDevicesDict(); // If found, it returns a pointer to the element. Otherwise it returns // nullptr. - auto* device_value = device_dict->FindKey(sink_id); + const auto* device_value = device_dict.Find(sink_id); if (!device_value) return nullptr;
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater.h b/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater.h index d1cac565..7df6a58 100644 --- a/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater.h +++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater.h
@@ -36,9 +36,8 @@ // exist, then update the value of that |sink_id| with a new time. void UpdateDeviceAddedTimeDict(const MediaSink::Id sink_id); - // Returns a nullptr if the device dictionary does not exist in the pref - // service for some reason. - const base::Value* GetDevicesDict(); + // Returns a the device dictionary from the pref service. + const base::Value::Dict& GetDevicesDict(); // Returns a nullptr if the device Added dictionary does not exist in the // pref service for some reason.
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater_unittest.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater_unittest.cc index 1d69f54a..989d4b4 100644 --- a/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater_unittest.cc +++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater_unittest.cc
@@ -177,11 +177,11 @@ pref_updater()->UpdateDevicesDict(cast_sink); pref_updater()->UpdateDevicesDict(cast_sink2); - EXPECT_FALSE(pref_updater()->GetDevicesDict()->GetDict().empty()); + EXPECT_FALSE(pref_updater()->GetDevicesDict().empty()); pref_updater()->ClearDevicesDict(); - EXPECT_TRUE(pref_updater()->GetDevicesDict()->GetDict().empty()); + EXPECT_TRUE(pref_updater()->GetDevicesDict().empty()); } TEST_F(AccessCodeCastPrefUpdaterTest, TestClearDeviceAddedTimeDict) {
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_unittest.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_unittest.cc index cb64d99..9dc04583 100644 --- a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_unittest.cc +++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_unittest.cc
@@ -421,9 +421,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .empty()); - EXPECT_TRUE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .empty()); + EXPECT_TRUE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().empty()); } TEST_F(AccessCodeCastSinkServiceTest, TestFetchAndAddStoredDevices) { @@ -534,9 +533,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .empty()); - EXPECT_FALSE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .empty()); + EXPECT_FALSE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().empty()); // When the network changes, the sinks on that network should be removed. EXPECT_CALL(*mock_cast_media_sink_service_impl(), @@ -567,9 +565,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .size()); - EXPECT_FALSE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .size()); + EXPECT_FALSE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().size()); } TEST_F(AccessCodeCastSinkServiceTest, TestChangeNetworksNoExpiration) { @@ -632,9 +629,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .empty()); - EXPECT_FALSE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .empty()); + EXPECT_FALSE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().empty()); content::RunAllTasksUntilIdle(); mock_time_task_runner()->FastForwardUntilNoTasksRemain(); @@ -669,9 +665,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .size()); - EXPECT_TRUE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .size()); + EXPECT_TRUE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().size()); } TEST_F(AccessCodeCastSinkServiceTest, @@ -705,9 +700,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .empty()); - EXPECT_TRUE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .empty()); + EXPECT_TRUE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().empty()); // Expect that the sink id is removed from all instance in the pref service // when we try to init connections with a corrupted device entry. @@ -790,9 +784,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .empty()); - EXPECT_FALSE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .empty()); + EXPECT_FALSE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().empty()); // Add the device again, the expiration timer should be reset and 150 seconds // passed will not reset the cast device. @@ -810,9 +803,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .empty()); - EXPECT_FALSE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .empty()); + EXPECT_FALSE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().empty()); mock_time_task_runner()->FastForwardUntilNoTasksRemain(); } @@ -925,9 +917,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .empty()); - EXPECT_FALSE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .empty()); + EXPECT_FALSE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().empty()); EXPECT_CALL(*mock_cast_media_sink_service_impl(), DisconnectAndRemoveSink(cast_sink1)); @@ -940,9 +931,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .empty()); - EXPECT_TRUE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .empty()); + EXPECT_TRUE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().empty()); FastForwardUiAndIoTasks(); content::RunAllTasksUntilIdle(); mock_time_task_runner_->FastForwardUntilNoTasksRemain(); @@ -1032,9 +1022,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .empty()); - EXPECT_FALSE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .empty()); + EXPECT_FALSE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().empty()); } TEST_F(AccessCodeCastSinkServiceTest, @@ -1099,9 +1088,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .empty()); - EXPECT_TRUE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .empty()); + EXPECT_TRUE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().empty()); } TEST_F(AccessCodeCastSinkServiceTest, DiscoverSinkWithNoMediaRouter) { @@ -1188,9 +1176,8 @@ access_code_cast_sink_service_->pref_updater_->GetDeviceAddedTimeDict() ->GetDict() .empty()); - EXPECT_TRUE(access_code_cast_sink_service_->pref_updater_->GetDevicesDict() - ->GetDict() - .empty()); + EXPECT_TRUE( + access_code_cast_sink_service_->pref_updater_->GetDevicesDict().empty()); } } // namespace media_router
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc index 6e82d522..f58586f 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc
@@ -430,9 +430,15 @@ expected_page_density_height); } +// TODO(crbug.com/1352329): Flaky on Lacros bots. +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#define MAYBE_PageAdDensityMultipleFrames DISABLED_PageAdDensityMultipleFrames +#else +#define MAYBE_PageAdDensityMultipleFrames PageAdDensityMultipleFrames +#endif // Creates multiple overlapping frames and verifies the page ad density. IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, - PageAdDensityMultipleFrames) { + MAYBE_PageAdDensityMultipleFrames) { base::HistogramTester histogram_tester; ukm::TestAutoSetUkmRecorder ukm_recorder; auto waiter = CreatePageLoadMetricsTestWaiter();
diff --git a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc index 15f21c3..1e34646 100644 --- a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc +++ b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
@@ -43,6 +43,10 @@ #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/performance_manager/policies/oom_score_policy_lacros.h" +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + #if BUILDFLAG(ENABLE_EXTENSIONS) #include "chrome/browser/performance_manager/extension_watcher.h" #endif @@ -109,6 +113,11 @@ #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_LACROS) + graph->PassToGraph( + std::make_unique<performance_manager::policies::OomScorePolicyLacros>()); +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + #if !BUILDFLAG(IS_ANDROID) graph->PassToGraph(FormInteractionTabHelper::CreateGraphObserver());
diff --git a/chrome/browser/performance_manager/policies/oom_score_policy_lacros.cc b/chrome/browser/performance_manager/policies/oom_score_policy_lacros.cc new file mode 100644 index 0000000..a2a4db6 --- /dev/null +++ b/chrome/browser/performance_manager/policies/oom_score_policy_lacros.cc
@@ -0,0 +1,136 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/performance_manager/policies/oom_score_policy_lacros.h" + +#include <algorithm> +#include <set> + +#include "base/process/memory.h" // For AdjustOOMScore +#include "components/performance_manager/public/graph/frame_node.h" +#include "components/performance_manager/public/graph/process_node.h" +#include "content/public/common/content_constants.h" // For kLowestRendererOomScore + +namespace performance_manager { +namespace policies { + +namespace { + +constexpr base::TimeDelta kOomScoreAssignmentInterval = base::Seconds(10); + +} // namespace + +OomScorePolicyLacros::OomScorePolicyLacros() = default; +OomScorePolicyLacros::~OomScorePolicyLacros() = default; + +void OomScorePolicyLacros::OnPassedToGraph(Graph* graph) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + graph_ = graph; + timer_.Start(FROM_HERE, kOomScoreAssignmentInterval, + base::BindRepeating(&OomScorePolicyLacros::AssignOomScores, + weak_factory_.GetWeakPtr())); +} + +void OomScorePolicyLacros::OnTakenFromGraph(Graph* graph) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + graph_ = nullptr; + timer_.Stop(); +} + +void OomScorePolicyLacros::AssignOomScores() { + PageDiscardingHelper* discarding_helper = + PageDiscardingHelper::GetFromGraph(graph_); + + std::vector<const PageNode*> page_nodes = graph_->GetAllPageNodes(); + + std::vector<PageNodeSortProxy> candidates; + for (const auto* page_node : page_nodes) { + PageDiscardingHelper::CanUrgentlyDiscardResult can_discard_result = + discarding_helper->CanUrgentlyDiscard(page_node); + bool is_marked = (can_discard_result == + PageDiscardingHelper::CanUrgentlyDiscardResult::kMarked); + bool is_protected = + (can_discard_result == + PageDiscardingHelper::CanUrgentlyDiscardResult::kProtected); + candidates.emplace_back(page_node, is_marked, is_protected, + page_node->GetTimeSinceLastVisibilityChange()); + } + // Sorts with descending importance. + std::sort(candidates.begin(), candidates.end(), + [](const PageNodeSortProxy& lhs, const PageNodeSortProxy& rhs) { + return rhs < lhs; + }); + + oom_score_map_ = DistributeOomScore(candidates); +} + +OomScorePolicyLacros::ProcessScoreMap OomScorePolicyLacros::DistributeOomScore( + const std::vector<PageNodeSortProxy>& candidates) { + ProcessScoreMap score_map; + + std::vector<base::ProcessId> pids = GetUniqueSortedPids(candidates); + + const int pid_count = pids.size(); + if (pid_count == 0) + return score_map; + + // Now we distribute oom_score_adj evenly in the range based on the sorted + // list. We're assigning priorities in the range of kLowestRendererOomScore + // to kHighestRendererOomScore (defined in chrome_constants.h). oom_score_adj + // takes values from -1000 to 1000. Negative values are reserved for system + // processes. Higher values are more likely to be killed by the Linux kernel + // OOM killer. + const float range = static_cast<float>(content::kHighestRendererOomScore - + content::kLowestRendererOomScore); + const float adj_increment = (pid_count == 1) ? 0 : range / (pid_count - 1); + + float adj_raw = content::kLowestRendererOomScore; + for (base::ProcessId pid : pids) { + const int adj = round(adj_raw); + + score_map[pid] = adj; + + if (GetCachedOomScore(pid) != adj) { + VLOG(3) << "Update OOM score " << adj << " for " << pid; + if (!base::AdjustOOMScore(pid, adj)) + LOG(ERROR) << "Failed to set oom_score_adj to " << adj + << " for process " << pid; + } + adj_raw += adj_increment; + } + + return score_map; +} + +std::vector<base::ProcessId> OomScorePolicyLacros::GetUniqueSortedPids( + const std::vector<PageNodeSortProxy>& candidates) { + std::vector<base::ProcessId> pids; + + std::set<base::ProcessId> pid_set; + + for (const auto& candidate : candidates) { + base::ProcessId pid = candidate.page_node() + ->GetMainFrameNode() + ->GetProcessNode() + ->GetProcessId(); + + if (pid == base::kNullProcessId || pid_set.find(pid) != pid_set.end()) + continue; + + pids.push_back(pid); + pid_set.insert(pid); + } + + return pids; +} + +int OomScorePolicyLacros::GetCachedOomScore(base::ProcessHandle pid) { + auto it = oom_score_map_.find(pid); + if (it == oom_score_map_.end()) + return -1; + return it->second; +} + +} // namespace policies +} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/policies/oom_score_policy_lacros.h b/chrome/browser/performance_manager/policies/oom_score_policy_lacros.h new file mode 100644 index 0000000..e48547bb --- /dev/null +++ b/chrome/browser/performance_manager/policies/oom_score_policy_lacros.h
@@ -0,0 +1,72 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_POLICIES_OOM_SCORE_POLICY_LACROS_H_ +#define CHROME_BROWSER_PERFORMANCE_MANAGER_POLICIES_OOM_SCORE_POLICY_LACROS_H_ + +#include <vector> + +#include "base/process/process_handle.h" // For ProcessId +#include "base/sequence_checker.h" +#include "base/timer/timer.h" +#include "chrome/browser/performance_manager/policies/page_discarding_helper.h" +#include "components/performance_manager/public/graph/graph.h" +#include "components/performance_manager/public/graph/system_node.h" + +namespace performance_manager { + +namespace policies { + +// Assigning oom score adj to renderer processes. Process with lowest oom score +// adj is the last to be killed by Linux oom killer. The more important process +// would be assigned lower oom score adj. See the following web page for more +// explanation on Linux oom score adj(adjust). +// [1]: https://man7.org/linux/man-pages/man1/choom.1.html +class OomScorePolicyLacros : public GraphOwned { + public: + OomScorePolicyLacros(); + ~OomScorePolicyLacros() override; + OomScorePolicyLacros(const OomScorePolicyLacros& other) = delete; + OomScorePolicyLacros& operator=(const OomScorePolicyLacros&) = delete; + + // GraphOwned implementation: + void OnPassedToGraph(Graph* graph) override; + void OnTakenFromGraph(Graph* graph) override; + + protected: + // These members are protected for testing. + void AssignOomScores(); + + // Returns the cached oom score adj. If the pid is not cached, returns -1 (a + // value not in the valid oom score adj range for renderer processes). + int GetCachedOomScore(base::ProcessId pid); + + raw_ptr<Graph> graph_ = nullptr; + + private: + // Cache OOM scores in memory. + using ProcessScoreMap = base::flat_map<base::ProcessId, int>; + + ProcessScoreMap DistributeOomScore( + const std::vector<PageNodeSortProxy>& candidates); + + // Returns a vector of pids from most important process to least important + // process. + std::vector<base::ProcessId> GetUniqueSortedPids( + const std::vector<PageNodeSortProxy>& candidates); + + base::RepeatingTimer timer_; + + // Map maintaining the process handle - oom_score mapping. + ProcessScoreMap oom_score_map_; + + SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory<OomScorePolicyLacros> weak_factory_{this}; +}; + +} // namespace policies +} // namespace performance_manager + +#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_POLICIES_OOM_SCORE_POLICY_LACROS_H_
diff --git a/chrome/browser/performance_manager/policies/oom_score_policy_lacros_unittest.cc b/chrome/browser/performance_manager/policies/oom_score_policy_lacros_unittest.cc new file mode 100644 index 0000000..26e0386 --- /dev/null +++ b/chrome/browser/performance_manager/policies/oom_score_policy_lacros_unittest.cc
@@ -0,0 +1,254 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/performance_manager/policies/oom_score_policy_lacros.h" + +#include "chrome/browser/performance_manager/test_support/page_discarding_utils.h" // For GraphTestHarnessWithMockDiscarder +#include "components/performance_manager/test_support/mock_graphs.h" // For TestProcessNodeImpl +#include "content/public/common/content_constants.h" // For kLowestRendererOomScore +#include "testing/gtest/include/gtest/gtest.h" + +namespace performance_manager { +namespace policies { + +class MockOomScorePolicyLacros : public OomScorePolicyLacros { + public: + // Overrides OnPassedToGraph to avoid starting the timer. + void OnPassedToGraph(Graph* graph) override { graph_ = graph; } + + void AssignOomScores() { OomScorePolicyLacros::AssignOomScores(); } + + int GetCachedOomScore(base::ProcessId pid) { + return OomScorePolicyLacros::GetCachedOomScore(pid); + } +}; + +class OomScorePolicyLacrosTest + : public testing::GraphTestHarnessWithMockDiscarder { + public: + OomScorePolicyLacrosTest() = default; + ~OomScorePolicyLacrosTest() override = default; + OomScorePolicyLacrosTest(const OomScorePolicyLacrosTest& other) = delete; + OomScorePolicyLacrosTest& operator=(const OomScorePolicyLacrosTest&) = delete; + + void SetUp() override { + testing::GraphTestHarnessWithMockDiscarder::SetUp(); + + // Create the policy and pass it to the graph. + auto policy = std::make_unique<MockOomScorePolicyLacros>(); + policy_ = policy.get(); + graph()->PassToGraph(std::move(policy)); + } + + void TearDown() override { + graph()->TakeFromGraph(policy_); + testing::GraphTestHarnessWithMockDiscarder::TearDown(); + } + + MockOomScorePolicyLacros* policy() { return policy_; } + + private: + raw_ptr<MockOomScorePolicyLacros> policy_; +}; + +TEST_F(OomScorePolicyLacrosTest, DistributeOomScores) { + constexpr base::ProcessId kProcessId1 = 1; + constexpr base::ProcessId kProcessId2 = 2; + constexpr base::ProcessId kProcessId3 = 3; + + // Creates 3 pages. + auto process_node1 = TestNodeWrapper<TestProcessNodeImpl>::Create(graph()); + process_node1->SetProcessWithPid(kProcessId1, base::Process::Current(), + /* launch_time=*/base::TimeTicks::Now()); + auto page_node1 = CreateNode<performance_manager::PageNodeImpl>(); + auto main_frame_node1 = + CreateFrameNodeAutoId(process_node1.get(), page_node1.get()); + main_frame_node1->SetIsCurrent(true); + testing::MakePageNodeDiscardable(page_node1.get(), task_env()); + AdvanceClock(base::Minutes(30)); + main_frame_node1->SetIsCurrent(false); + AdvanceClock(base::Minutes(30)); + + auto process_node2 = TestNodeWrapper<TestProcessNodeImpl>::Create(graph()); + process_node2->SetProcessWithPid(kProcessId2, base::Process::Current(), + /* launch_time=*/base::TimeTicks::Now()); + auto page_node2 = CreateNode<performance_manager::PageNodeImpl>(); + auto main_frame_node2 = + CreateFrameNodeAutoId(process_node2.get(), page_node2.get()); + main_frame_node2->SetIsCurrent(true); + testing::MakePageNodeDiscardable(page_node2.get(), task_env()); + AdvanceClock(base::Minutes(30)); + main_frame_node2->SetIsCurrent(false); + AdvanceClock(base::Minutes(30)); + + auto process_node3 = TestNodeWrapper<TestProcessNodeImpl>::Create(graph()); + process_node3->SetProcessWithPid(kProcessId3, base::Process::Current(), + /* launch_time=*/base::TimeTicks::Now()); + auto page_node3 = CreateNode<performance_manager::PageNodeImpl>(); + auto main_frame_node3 = + CreateFrameNodeAutoId(process_node3.get(), page_node3.get()); + main_frame_node3->SetIsCurrent(true); + testing::MakePageNodeDiscardable(page_node3.get(), task_env()); + AdvanceClock(base::Minutes(30)); + main_frame_node3->SetIsCurrent(false); + AdvanceClock(base::Minutes(30)); + + policy()->AssignOomScores(); + + const int kMiddleRendererOomScore = + (content::kHighestRendererOomScore + content::kLowestRendererOomScore) / + 2; + ASSERT_EQ(policy()->GetCachedOomScore(process_node1->process_id()), + content::kHighestRendererOomScore); + ASSERT_EQ(policy()->GetCachedOomScore(process_node2->process_id()), + kMiddleRendererOomScore); + ASSERT_EQ(policy()->GetCachedOomScore(process_node3->process_id()), + content::kLowestRendererOomScore); + // GetCachedOomScore should return -1 for non-cached pid. + ASSERT_EQ(policy()->GetCachedOomScore(0), -1); +} + +TEST_F(OomScorePolicyLacrosTest, DistributeOomScoresWithPriority) { + constexpr base::ProcessId kProcessId1 = 1; + constexpr base::ProcessId kProcessId2 = 2; + constexpr base::ProcessId kProcessId3 = 3; + + // Creates 3 pages. + auto process_node1 = TestNodeWrapper<TestProcessNodeImpl>::Create(graph()); + process_node1->SetProcessWithPid(kProcessId1, base::Process::Current(), + /* launch_time=*/base::TimeTicks::Now()); + auto page_node1 = CreateNode<performance_manager::PageNodeImpl>(); + auto main_frame_node1 = + CreateFrameNodeAutoId(process_node1.get(), page_node1.get()); + main_frame_node1->SetIsCurrent(true); + testing::MakePageNodeDiscardable(page_node1.get(), task_env()); + AdvanceClock(base::Minutes(30)); + main_frame_node1->SetIsCurrent(false); + AdvanceClock(base::Minutes(30)); + // Set page node 1 audible to raise its priority. + page_node1->SetIsAudible(true); + + auto process_node2 = TestNodeWrapper<TestProcessNodeImpl>::Create(graph()); + process_node2->SetProcessWithPid(kProcessId2, base::Process::Current(), + /* launch_time=*/base::TimeTicks::Now()); + auto page_node2 = CreateNode<performance_manager::PageNodeImpl>(); + auto main_frame_node2 = + CreateFrameNodeAutoId(process_node2.get(), page_node2.get()); + main_frame_node2->SetIsCurrent(true); + testing::MakePageNodeDiscardable(page_node2.get(), task_env()); + AdvanceClock(base::Minutes(30)); + main_frame_node2->SetIsCurrent(false); + AdvanceClock(base::Minutes(30)); + + auto process_node3 = TestNodeWrapper<TestProcessNodeImpl>::Create(graph()); + process_node3->SetProcessWithPid(kProcessId3, base::Process::Current(), + /* launch_time=*/base::TimeTicks::Now()); + auto page_node3 = CreateNode<performance_manager::PageNodeImpl>(); + auto main_frame_node3 = + CreateFrameNodeAutoId(process_node3.get(), page_node3.get()); + main_frame_node3->SetIsCurrent(true); + testing::MakePageNodeDiscardable(page_node3.get(), task_env()); + AdvanceClock(base::Minutes(30)); + main_frame_node3->SetIsCurrent(false); + AdvanceClock(base::Minutes(30)); + + policy()->AssignOomScores(); + + const int kMiddleRendererOomScore = + (content::kHighestRendererOomScore + content::kLowestRendererOomScore) / + 2; + + // Because page node 1 is audible, the corresponding process should have + // lowest oom score adj. + ASSERT_EQ(policy()->GetCachedOomScore(process_node2->process_id()), + content::kHighestRendererOomScore); + ASSERT_EQ(policy()->GetCachedOomScore(process_node3->process_id()), + kMiddleRendererOomScore); + ASSERT_EQ(policy()->GetCachedOomScore(process_node1->process_id()), + content::kLowestRendererOomScore); +} + +TEST_F(OomScorePolicyLacrosTest, DistributeOomScoresSharedPid) { + constexpr base::ProcessId kProcessId1 = 1; + constexpr base::ProcessId kProcessId2 = 2; + constexpr base::ProcessId kProcessId3 = 3; + + // Creates 4 pages. 2 of the 4pages share the same renderer process. + // + // From earliest visible to latest visible pages: + // page_node1, page_node2, page_node3, page_node4 + // + // Page to process relation: + // page_node1 -> process_node1 + // page_node2 -> process_node2 + // page_node3 -> process_node3 + // page_node4 -> process_node2 + // + // process_node2 is used by both page_node2 and page_node4, the latest visible + // page of the 2 pages would be used to estimate process priority. + // + // From most important process to least important process: + // process_node2, process_node3, process_node1 + auto process_node1 = TestNodeWrapper<TestProcessNodeImpl>::Create(graph()); + process_node1->SetProcessWithPid(kProcessId1, base::Process::Current(), + /* launch_time=*/base::TimeTicks::Now()); + auto page_node1 = CreateNode<performance_manager::PageNodeImpl>(); + auto main_frame_node1 = + CreateFrameNodeAutoId(process_node1.get(), page_node1.get()); + main_frame_node1->SetIsCurrent(true); + testing::MakePageNodeDiscardable(page_node1.get(), task_env()); + AdvanceClock(base::Minutes(30)); + main_frame_node1->SetIsCurrent(false); + AdvanceClock(base::Minutes(30)); + + auto process_node2 = TestNodeWrapper<TestProcessNodeImpl>::Create(graph()); + process_node2->SetProcessWithPid(kProcessId2, base::Process::Current(), + /* launch_time=*/base::TimeTicks::Now()); + + // page_node2 and page_node4 share the same renderer process. + auto page_node2 = CreateNode<performance_manager::PageNodeImpl>(); + auto main_frame_node2 = + CreateFrameNodeAutoId(process_node2.get(), page_node2.get()); + main_frame_node2->SetIsCurrent(true); + testing::MakePageNodeDiscardable(page_node2.get(), task_env()); + AdvanceClock(base::Minutes(30)); + main_frame_node2->SetIsCurrent(false); + AdvanceClock(base::Minutes(30)); + + auto process_node3 = TestNodeWrapper<TestProcessNodeImpl>::Create(graph()); + process_node3->SetProcessWithPid(kProcessId3, base::Process::Current(), + /* launch_time=*/base::TimeTicks::Now()); + + auto page_node3 = CreateNode<performance_manager::PageNodeImpl>(); + auto main_frame_node3 = + CreateFrameNodeAutoId(process_node3.get(), page_node3.get()); + main_frame_node3->SetIsCurrent(true); + testing::MakePageNodeDiscardable(page_node3.get(), task_env()); + AdvanceClock(base::Minutes(30)); + main_frame_node3->SetIsCurrent(false); + AdvanceClock(base::Minutes(30)); + + auto page_node4 = CreateNode<performance_manager::PageNodeImpl>(); + auto main_frame_node4 = + CreateFrameNodeAutoId(process_node2.get(), page_node4.get()); + main_frame_node4->SetIsCurrent(true); + testing::MakePageNodeDiscardable(page_node4.get(), task_env()); + AdvanceClock(base::Minutes(30)); + main_frame_node4->SetIsCurrent(false); + AdvanceClock(base::Minutes(30)); + + policy()->AssignOomScores(); + + const int kMiddleRendererOomScore = + (content::kHighestRendererOomScore + content::kLowestRendererOomScore) / + 2; + ASSERT_EQ(policy()->GetCachedOomScore(process_node1->process_id()), + content::kHighestRendererOomScore); + ASSERT_EQ(policy()->GetCachedOomScore(process_node3->process_id()), + kMiddleRendererOomScore); + ASSERT_EQ(policy()->GetCachedOomScore(process_node2->process_id()), + content::kLowestRendererOomScore); +} +} // namespace policies +} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/policies/page_discarding_helper.cc b/chrome/browser/performance_manager/policies/page_discarding_helper.cc index 195f916..6faa7d97 100644 --- a/chrome/browser/performance_manager/policies/page_discarding_helper.cc +++ b/chrome/browser/performance_manager/policies/page_discarding_helper.cc
@@ -59,33 +59,6 @@ const char kDescriberName[] = "PageDiscardingHelper"; -// Caches page node properties to facilitate sorting. -class PageNodeSortProxy { - public: - PageNodeSortProxy(const PageNode* page_node, - bool is_protected, - base::TimeDelta last_visible) - : page_node_(page_node), - is_protected_(is_protected), - last_visible_(last_visible) {} - const PageNode* page_node() { return page_node_; } - - // Returns true if the rhs is more important. - bool operator<(const PageNodeSortProxy& rhs) const { - if (is_protected_ && !rhs.is_protected_) - return false; - if (!is_protected_ && rhs.is_protected_) - return true; - return last_visible_ > rhs.last_visible_; - } - - private: - const PageNode* page_node_; - bool is_protected_; - // Delta between current time and last visibility change time. - base::TimeDelta last_visible_; -}; - using NodeRssMap = base::flat_map<const PageNode*, uint64_t>; // Returns the mapping from page_node to its RSS estimation. @@ -169,7 +142,7 @@ (can_discard_result == CanUrgentlyDiscardResult::kProtected); if (!discard_protected_tabs && is_protected) continue; - candidates.emplace_back(page_node, is_protected, + candidates.emplace_back(page_node, false, is_protected, page_node->GetTimeSinceLastVisibilityChange()); } // Sorts with ascending importance.
diff --git a/chrome/browser/performance_manager/policies/page_discarding_helper.h b/chrome/browser/performance_manager/policies/page_discarding_helper.h index 111dbc62..e2a9f29 100644 --- a/chrome/browser/performance_manager/policies/page_discarding_helper.h +++ b/chrome/browser/performance_manager/policies/page_discarding_helper.h
@@ -30,6 +30,40 @@ namespace policies { +// Caches page node properties to facilitate sorting. +class PageNodeSortProxy { + public: + PageNodeSortProxy(const PageNode* page_node, + bool is_marked, + bool is_protected, + base::TimeDelta last_visible) + : page_node_(page_node), + is_marked_(is_marked), + is_protected_(is_protected), + last_visible_(last_visible) {} + const PageNode* page_node() const { return page_node_; } + + // Returns true if the rhs is more important. + bool operator<(const PageNodeSortProxy& rhs) const { + if (is_marked_ && !rhs.is_marked_) + return false; + if (!is_marked_ && rhs.is_marked_) + return true; + if (is_protected_ && !rhs.is_protected_) + return false; + if (!is_protected_ && rhs.is_protected_) + return true; + return last_visible_ > rhs.last_visible_; + } + + private: + const PageNode* page_node_; + bool is_marked_; + bool is_protected_; + // Delta between current time and last visibility change time. + base::TimeDelta last_visible_; +}; + // Helper class to be used by the policies that want to discard tabs. // // This is a GraphRegistered object and should be accessed via @@ -39,6 +73,15 @@ public GraphRegisteredImpl<PageDiscardingHelper>, public NodeDataDescriberDefaultImpl { public: + enum class CanUrgentlyDiscardResult { + // Discarding eligible nodes is hard to notice for user. + kEligible, + // Discarding protected nodes is noticeable to user. + kProtected, + // Marked nodes can never be discarded. + kMarked, + }; + PageDiscardingHelper(); ~PageDiscardingHelper() override; PageDiscardingHelper(const PageDiscardingHelper& other) = delete; @@ -77,6 +120,15 @@ return CanUrgentlyDiscard(page_node, consider_minimum_protection_time) == CanUrgentlyDiscardResult::kEligible; } + // Indicates if a PageNode can be urgently discarded. If + // `consider_minimum_protection_time` is false, the check that ensures the + // page hasn't been visible recently is ignored. This is to support cases + // where the time before a tab is discarded is known and shorter than the + // grace period. + CanUrgentlyDiscardResult CanUrgentlyDiscard( + const PageNode* page_node, + bool consider_minimum_protection_time = true) const; + void SetGraphForTesting(Graph* graph) { graph_ = graph; } static void AddDiscardAttemptMarkerForTesting(PageNode* page_node); static void RemovesDiscardAttemptMarkerForTesting(PageNode* page_node); @@ -91,24 +143,6 @@ const PageNode* page_node) const; private: - enum class CanUrgentlyDiscardResult { - // Discarding eligible nodes is hard to notice for user. - kEligible, - // Discarding protected nodes is noticeable to user. - kProtected, - // Marked nodes can never be discarded. - kMarked, - }; - - // Indicates if a PageNode can be urgently discarded. If - // `consider_minimum_protection_time` is false, the check that ensures the - // page hasn't been visible recently is ignored. This is to support cases - // where the time before a tab is discarded is known and shorter than the - // grace period. - CanUrgentlyDiscardResult CanUrgentlyDiscard( - const PageNode* page_node, - bool consider_minimum_protection_time = true) const; - bool IsPageOptedOutOfDiscarding(const std::string& browser_context_id, const GURL& url) const;
diff --git a/chrome/browser/printing/prefs_util.cc b/chrome/browser/printing/prefs_util.cc index 2879595f..39bf1680 100644 --- a/chrome/browser/printing/prefs_util.cc +++ b/chrome/browser/printing/prefs_util.cc
@@ -20,12 +20,9 @@ if (!prefs.HasPrefPath(prefs::kPrintingPaperSizeDefault)) return absl::nullopt; - const base::Value* paper_size_value = - prefs.GetDictionary(prefs::kPrintingPaperSizeDefault); - if (!paper_size_value) - return absl::nullopt; + const base::Value::Dict& paper_size_dict = + prefs.GetValueDict(prefs::kPrintingPaperSizeDefault); - const base::Value::Dict& paper_size_dict = paper_size_value->GetDict(); if (paper_size_dict.empty()) return absl::nullopt;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing_test.js index d48f5527..806efee 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing_test.js
@@ -2131,36 +2131,39 @@ await mockFeedback.replay(); }); -AX_TEST_F('ChromeVoxEditingTest', 'NativeCharWordCommands', async function() { - const mockFeedback = this.createMockFeedback(); - const site = ` +// TODO(crbug.com/1352225): Flaky. +AX_TEST_F( + 'ChromeVoxEditingTest', 'DISABLED_NativeCharWordCommands', + async function() { + const mockFeedback = this.createMockFeedback(); + const site = ` <p>start</p> <div role="textbox" contenteditable>This is a test</div> `; - const root = await this.runWithLoadedTree(site); - await this.focusFirstTextField(root); + const root = await this.runWithLoadedTree(site); + await this.focusFirstTextField(root); - const textField = root.find({role: RoleType.TEXT_FIELD}); - mockFeedback.expectSpeech('Text area') - .call(this.press(KeyCode.HOME, {ctrl: true})) - .call(this.press(KeyCode.RIGHT)) - .expectSpeech('h') - .call(this.press(KeyCode.RIGHT)) - .expectSpeech('i') - .call(this.press(KeyCode.LEFT)) - .expectSpeech('h') + const textField = root.find({role: RoleType.TEXT_FIELD}); + mockFeedback.expectSpeech('Text area') + .call(this.press(KeyCode.HOME, {ctrl: true})) + .call(this.press(KeyCode.RIGHT)) + .expectSpeech('h') + .call(this.press(KeyCode.RIGHT)) + .expectSpeech('i') + .call(this.press(KeyCode.LEFT)) + .expectSpeech('h') - .call(this.press(KeyCode.RIGHT, {ctrl: true})) - .expectSpeech('This') - .call(this.press(KeyCode.RIGHT, {ctrl: true})) - .expectSpeech('is') - .call(this.press(KeyCode.LEFT, {ctrl: true})) - .expectSpeech('is') - .call(this.press(KeyCode.LEFT, {ctrl: true})) - .expectSpeech('This'); + .call(this.press(KeyCode.RIGHT, {ctrl: true})) + .expectSpeech('This') + .call(this.press(KeyCode.RIGHT, {ctrl: true})) + .expectSpeech('is') + .call(this.press(KeyCode.LEFT, {ctrl: true})) + .expectSpeech('is') + .call(this.press(KeyCode.LEFT, {ctrl: true})) + .expectSpeech('This'); - await mockFeedback.replay(); -}); + await mockFeedback.replay(); + }); AX_TEST_F('ChromeVoxEditingTest', 'TablesWithEmptyCells', async function() { const mockFeedback = this.createMockFeedback();
diff --git a/chrome/browser/resources/chromeos/cloud_upload/.gitignore b/chrome/browser/resources/chromeos/cloud_upload/.gitignore new file mode 100644 index 0000000..ec7fda7 --- /dev/null +++ b/chrome/browser/resources/chromeos/cloud_upload/.gitignore
@@ -0,0 +1,2 @@ +# Generated from ash/webui/personalization_app/tools/gen_tsconfig.py +tsconfig.json
diff --git a/chrome/browser/resources/chromeos/cloud_upload/cloud_upload_dialog.html b/chrome/browser/resources/chromeos/cloud_upload/cloud_upload_dialog.html index 71ed20c..afbe98d 100644 --- a/chrome/browser/resources/chromeos/cloud_upload/cloud_upload_dialog.html +++ b/chrome/browser/resources/chromeos/cloud_upload/cloud_upload_dialog.html
@@ -16,7 +16,8 @@ </div> <div slot="body"> Upload your file to Google Drive to open with Google Docs. - <div id="upload-location" hidden></div> + <div id="path" style="margin-top: 1rem"></div> + <div id="upload-location" style="margin-top: 1rem" hidden></div> </div> <div slot="button-container"> <cr-button id="cancel-button" class="cancel-button">
diff --git a/chrome/browser/resources/chromeos/cloud_upload/cloud_upload_dialog.ts b/chrome/browser/resources/chromeos/cloud_upload/cloud_upload_dialog.ts index dcef32c..43eb7f0 100644 --- a/chrome/browser/resources/chromeos/cloud_upload/cloud_upload_dialog.ts +++ b/chrome/browser/resources/chromeos/cloud_upload/cloud_upload_dialog.ts
@@ -5,8 +5,10 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js'; +import {assert} from 'chrome://resources/js/assert_ts.js'; import {BrowserProxy} from './browser_proxy.js'; +import {UserAction} from './cloud_upload.mojom-webui.js'; import {getTemplate} from './cloud_upload_dialog.html.js'; /** @@ -31,25 +33,38 @@ return this.$('cr-dialog') as CrDialogElement; } - connectedCallback(): void { + get proxy() { + return BrowserProxy.getInstance().handler; + } + + async connectedCallback() { + const dialogArgs = chrome.getVariableValue('dialogArguments'); + assert(dialogArgs); + var args = JSON.parse(dialogArgs); + assert(args); + assert(args.path); + const pathElement = this.$('#path') as HTMLElement; + pathElement.innerText = `File name: ${args.path}`; + this.dialog.showModal(); const cancelButton = this.$('#cancel-button'); cancelButton.addEventListener('click', () => this.onCancelButtonClick()); const uploadButton = this.$('#upload-button'); uploadButton.addEventListener('click', () => this.onUploadButtonClick()); - } - private onCancelButtonClick(): void { - chrome.send('dialogClose'); - } - - private async onUploadButtonClick() { - const proxy = BrowserProxy.getInstance().handler; - const {uploadPath} = await proxy.getUploadPath(); + const {uploadPath} = await this.proxy.getUploadPath(); const uploadLocationElement = this.$('#upload-location') as HTMLElement; uploadLocationElement.innerText = `Upload location: ${uploadPath.path}`; uploadLocationElement.toggleAttribute('hidden', false); } + + private onCancelButtonClick(): void { + this.proxy.respondAndClose(UserAction.kCancel); + } + + private onUploadButtonClick(): void { + this.proxy.respondAndClose(UserAction.kUpload); + } } customElements.define('cloud-upload-dialog', CloudUploadDialogElement);
diff --git a/chrome/browser/storage_access_api/storage_access_grant_permission_context.h b/chrome/browser/storage_access_api/storage_access_grant_permission_context.h index 34f4b1c..80c28c9 100644 --- a/chrome/browser/storage_access_api/storage_access_grant_permission_context.h +++ b/chrome/browser/storage_access_api/storage_access_grant_permission_context.h
@@ -24,10 +24,10 @@ ~StorageAccessGrantPermissionContext() override; private: - FRIEND_TEST_ALL_PREFIXES(StorageAccessGrantPermissionContextTest, - PermissionBlockedWhenFeatureDisabled); + FRIEND_TEST_ALL_PREFIXES(StorageAccessGrantPermissionContextAPIDisabledTest, + PermissionBlocked); FRIEND_TEST_ALL_PREFIXES(StorageAccessGrantPermissionContextAPIEnabledTest, - PermissionDecidedWhenFeatureEnabled); + PermissionDecided); FRIEND_TEST_ALL_PREFIXES(StorageAccessGrantPermissionContextAPIEnabledTest, PermissionDeniedWithoutUserGesture); FRIEND_TEST_ALL_PREFIXES(StorageAccessGrantPermissionContextAPIEnabledTest,
diff --git a/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc b/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc index 4fc59c52..b4ba391 100644 --- a/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc +++ b/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc
@@ -10,11 +10,11 @@ #include "components/content_settings/core/common/content_settings.h" #include "components/permissions/permission_request_id.h" #include "components/permissions/permission_request_manager.h" +#include "components/permissions/permission_util.h" #include "components/permissions/test/mock_permission_prompt_factory.h" #include "content/public/browser/web_contents.h" #include "net/base/features.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/features.h" namespace { @@ -41,6 +41,11 @@ class StorageAccessGrantPermissionContextTest : public ChromeRenderViewHostTestHarness { public: + explicit StorageAccessGrantPermissionContextTest(bool saa_enabled) { + features_.InitWithFeatureState(net::features::kStorageAccessAPI, + saa_enabled); + } + void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); @@ -96,13 +101,22 @@ } private: + base::test::ScopedFeatureList features_; std::unique_ptr<permissions::MockPermissionPromptFactory> mock_permission_prompt_factory_; permissions::PermissionRequestID::RequestLocalId::Generator request_id_generator_; }; -TEST_F(StorageAccessGrantPermissionContextTest, InsecureOriginsAreAllowed) { +class StorageAccessGrantPermissionContextAPIDisabledTest + : public StorageAccessGrantPermissionContextTest { + public: + StorageAccessGrantPermissionContextAPIDisabledTest() + : StorageAccessGrantPermissionContextTest(false) {} +}; + +TEST_F(StorageAccessGrantPermissionContextAPIDisabledTest, + InsecureOriginsAreAllowed) { GURL insecure_url = GURL("http://www.example.com"); StorageAccessGrantPermissionContext permission_context(profile()); EXPECT_TRUE(permission_context.IsPermissionAvailableToOrigins(insecure_url, @@ -113,8 +127,7 @@ // When the Storage Access API feature is disabled (the default) we // should block the permission request. -TEST_F(StorageAccessGrantPermissionContextTest, - PermissionBlockedWhenFeatureDisabled) { +TEST_F(StorageAccessGrantPermissionContextAPIDisabledTest, PermissionBlocked) { StorageAccessGrantPermissionContext permission_context(profile()); permissions::PermissionRequestID fake_id = CreateFakeID(); @@ -127,15 +140,14 @@ class StorageAccessGrantPermissionContextAPIEnabledTest : public StorageAccessGrantPermissionContextTest { - private: - base::test::ScopedFeatureList scoped_feature_list_{ - net::features::kStorageAccessAPI}; + public: + StorageAccessGrantPermissionContextAPIEnabledTest() + : StorageAccessGrantPermissionContextTest(true) {} }; // When the Storage Access API feature is enabled and we have a user gesture we // should get a decision. -TEST_F(StorageAccessGrantPermissionContextAPIEnabledTest, - PermissionDecidedWhenFeatureEnabled) { +TEST_F(StorageAccessGrantPermissionContextAPIEnabledTest, PermissionDecided) { StorageAccessGrantPermissionContext permission_context(profile()); permissions::PermissionRequestID fake_id = CreateFakeID(); @@ -177,8 +189,8 @@ EXPECT_EQ(CONTENT_SETTING_BLOCK, result); } -TEST_F(StorageAccessGrantPermissionContextTest, - PermissionStatusBlockedWhenFeatureDisabled) { +TEST_F(StorageAccessGrantPermissionContextAPIDisabledTest, + PermissionStatusBlocked) { StorageAccessGrantPermissionContext permission_context(profile()); EXPECT_EQ(CONTENT_SETTING_BLOCK, @@ -212,7 +224,7 @@ ExhaustImplicitGrants(GetRequesterURL(), permission_context); histogram_tester.ExpectTotalCount(kGrantIsImplicitHistogram, 5); histogram_tester.ExpectBucketCount(kGrantIsImplicitHistogram, - /*implicit_grant=*/1, 5); + /*sample=*/true, 5); ContentSetting result = CONTENT_SETTING_DEFAULT; permission_context.DecidePermission( @@ -233,10 +245,11 @@ histogram_tester.ExpectTotalCount(kGrantIsImplicitHistogram, 5); histogram_tester.ExpectBucketCount(kGrantIsImplicitHistogram, - /*implicit_grant=*/1, 5); + /*sample=*/true, 5); histogram_tester.ExpectTotalCount(kPromptResultHistogram, 1); - histogram_tester.ExpectBucketCount(kPromptResultHistogram, - /*DISMISSED=*/2, 1); + histogram_tester.ExpectBucketCount( + kPromptResultHistogram, + /*sample=*/permissions::PermissionAction::DISMISSED, 1); GURL alternate_requester_url = GURL("https://requester2_example.com"); @@ -254,9 +267,10 @@ histogram_tester.ExpectTotalCount(kGrantIsImplicitHistogram, 6); histogram_tester.ExpectBucketCount(kGrantIsImplicitHistogram, - /*implicit_grant=*/1, 6); - histogram_tester.ExpectBucketCount(kPromptResultHistogram, - /*DISMISSED=*/2, 1); + /*sample=*/true, 6); + histogram_tester.ExpectBucketCount( + kPromptResultHistogram, + /*sample=*/permissions::PermissionAction::DISMISSED, 1); } TEST_F(StorageAccessGrantPermissionContextAPIEnabledTest, ExplicitGrantDenial) { @@ -270,7 +284,7 @@ ExhaustImplicitGrants(GetRequesterURL(), permission_context); histogram_tester.ExpectTotalCount(kGrantIsImplicitHistogram, 5); histogram_tester.ExpectBucketCount(kGrantIsImplicitHistogram, - /*implicit_grant=*/1, 5); + /*sample=*/true, 5); ContentSetting result = CONTENT_SETTING_DEFAULT; permission_context.DecidePermission( @@ -291,10 +305,11 @@ histogram_tester.ExpectTotalCount(kGrantIsImplicitHistogram, 5); histogram_tester.ExpectBucketCount(kGrantIsImplicitHistogram, - /*implicit_grant=*/1, 5); + /*sample=*/true, 5); histogram_tester.ExpectTotalCount(kPromptResultHistogram, 1); - histogram_tester.ExpectBucketCount(kPromptResultHistogram, - /*DENIED=*/1, 1); + histogram_tester.ExpectBucketCount( + kPromptResultHistogram, + /*sample=*/permissions::PermissionAction::DENIED, 1); } TEST_F(StorageAccessGrantPermissionContextAPIEnabledTest, ExplicitGrantAccept) { @@ -308,7 +323,7 @@ ExhaustImplicitGrants(GetRequesterURL(), permission_context); histogram_tester.ExpectTotalCount(kGrantIsImplicitHistogram, 5); histogram_tester.ExpectBucketCount(kGrantIsImplicitHistogram, - /*implicit_grant=*/1, 5); + /*sample=*/true, 5); ContentSetting result = CONTENT_SETTING_DEFAULT; permission_context.DecidePermission( @@ -329,10 +344,11 @@ histogram_tester.ExpectTotalCount(kGrantIsImplicitHistogram, 6); histogram_tester.ExpectBucketCount(kGrantIsImplicitHistogram, - /*implicit_grant=*/1, 5); + /*sample=*/true, 5); histogram_tester.ExpectBucketCount(kGrantIsImplicitHistogram, - /*explicit_grant=*/0, 1); + /*sample=*/false, 1); histogram_tester.ExpectTotalCount(kPromptResultHistogram, 1); - histogram_tester.ExpectBucketCount(kPromptResultHistogram, - /*GRANTED=*/0, 1); + histogram_tester.ExpectBucketCount( + kPromptResultHistogram, + /*sample=*/permissions::PermissionAction::GRANTED, 1); }
diff --git a/chrome/browser/ui/ash/system_tray_client_impl_browsertest.cc b/chrome/browser/ui/ash/system_tray_client_impl_browsertest.cc index 72000f86..0a1764c 100644 --- a/chrome/browser/ui/ash/system_tray_client_impl_browsertest.cc +++ b/chrome/browser/ui/ash/system_tray_client_impl_browsertest.cc
@@ -563,8 +563,16 @@ ash::LoginManagerMixin login_mixin_{&mixin_host_}; }; +// TODO(crbug.com/1352326): Flaky on release bots. +#if defined(NDEBUG) +#define MAYBE_RecordFeedbackSourceChannelIndicator \ + DISABLED_RecordFeedbackSourceChannelIndicator +#else +#define MAYBE_RecordFeedbackSourceChannelIndicator \ + RecordFeedbackSourceChannelIndicator +#endif IN_PROC_BROWSER_TEST_F(SystemTrayClientShowChannelInfoGiveFeedbackTest, - RecordFeedbackSourceChannelIndicator) { + MAYBE_RecordFeedbackSourceChannelIndicator) { base::HistogramTester histograms; auto tray_test_api = ash::SystemTrayTestApi::Create();
diff --git a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload.mojom b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload.mojom index ce1e4ec..d173245 100644 --- a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload.mojom +++ b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload.mojom
@@ -6,6 +6,12 @@ import "mojo/public/mojom/base/file_path.mojom"; +// The selected action when the user closes the dialog. +enum UserAction { + kCancel, + kUpload, +}; + // Lives in the browser process. A renderer uses this to create a page handler // that enables communication between a renderer and the browser process. interface PageHandlerFactory { @@ -18,4 +24,6 @@ interface PageHandler { // Returns the path of the Office file to upload. GetUploadPath() => (mojo_base.mojom.FilePath upload_path); + // Returns the user selected action and requests the dialog to be closed. + RespondAndClose(UserAction response); };
diff --git a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_dialog.cc b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_dialog.cc index 96cf4c1..8d2bdf36 100644 --- a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_dialog.cc +++ b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_dialog.cc
@@ -4,13 +4,23 @@ #include "chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_dialog.h" +#include "base/callback.h" +#include "base/json/json_writer.h" #include "base/logging.h" #include "chrome/common/webui_url_constants.h" namespace chromeos::cloud_upload { +namespace { + +void OnUploadActionReceived(const std::string& action) { + LOG(ERROR) << "ACTION: " << action; +} + +} // namespace // static -bool CloudUploadDialog::Show() { +bool CloudUploadDialog::Show( + const std::vector<storage::FileSystemURL>& file_urls) { // Allow no more than one upload dialog at a time. In the case of multiple // upload requests, they should either be handled simultaneously or queued. if (SystemWebDialogDelegate::HasInstance( @@ -18,19 +28,43 @@ return false; } + DCHECK(!file_urls.empty()); + // TODO(crbug.com/1336924) Add support for multi-file selection. + const storage::FileSystemURL file_url = file_urls[0]; + // The pointer is managed by an instance of `views::WebDialogView` and removed // in `SystemWebDialogDelegate::OnDialogClosed`. - CloudUploadDialog* dialog = new CloudUploadDialog(); + CloudUploadDialog* dialog = + new CloudUploadDialog(file_url, base::BindOnce(&OnUploadActionReceived)); + dialog->ShowSystemDialog(); return true; } -CloudUploadDialog::CloudUploadDialog() +void CloudUploadDialog::OnDialogClosed(const std::string& json_retval) { + if (callback_) { + std::move(callback_).Run(json_retval); + } + SystemWebDialogDelegate::OnDialogClosed(json_retval); +} + +CloudUploadDialog::CloudUploadDialog(const storage::FileSystemURL& file_url, + UploadRequestCallback callback) : SystemWebDialogDelegate(GURL(chrome::kChromeUICloudUploadURL), - std::u16string() /* title */) {} + std::u16string() /* title */), + file_url_(file_url), + callback_(std::move(callback)) {} CloudUploadDialog::~CloudUploadDialog() = default; +std::string CloudUploadDialog::GetDialogArgs() const { + base::DictionaryValue args; + args.SetKey("path", base::Value(file_url_.path().BaseName().value())); + std::string json; + base::JSONWriter::Write(args, &json); + return json; +} + bool CloudUploadDialog::ShouldShowCloseButton() const { return false; }
diff --git a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_dialog.h b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_dialog.h index 55aa2c9..bb0e48f 100644 --- a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_dialog.h +++ b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_dialog.h
@@ -5,24 +5,42 @@ #ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_CLOUD_UPLOAD_CLOUD_UPLOAD_DIALOG_H_ #define CHROME_BROWSER_UI_WEBUI_CHROMEOS_CLOUD_UPLOAD_CLOUD_UPLOAD_DIALOG_H_ +#include <vector> + #include "chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h" +#include "storage/browser/file_system/file_system_url.h" namespace chromeos::cloud_upload { +// The string conversions of chromeos::cloud_upload::mojom::UserAction. +const char kUserActionCancel[] = "cancel"; +const char kUserActionUpload[] = "upload"; + // Defines the web dialog used to help users upload Office files to the cloud. class CloudUploadDialog : public SystemWebDialogDelegate { public: + using UploadRequestCallback = + base::OnceCallback<void(const std::string& action)>; + CloudUploadDialog(const CloudUploadDialog&) = delete; CloudUploadDialog& operator=(const CloudUploadDialog&) = delete; // Creates and shows a new dialog for the cloud upload workflow. Returns true // if a new dialog has been effectively created. - static bool Show(); + static bool Show(const std::vector<storage::FileSystemURL>& file_urls); + + void OnDialogClosed(const std::string& json_retval) override; protected: - CloudUploadDialog(); + explicit CloudUploadDialog(const storage::FileSystemURL& file_url, + UploadRequestCallback callback); + std::string GetDialogArgs() const override; ~CloudUploadDialog() override; bool ShouldShowCloseButton() const override; + + private: + const storage::FileSystemURL file_url_; + UploadRequestCallback callback_; }; } // namespace chromeos::cloud_upload
diff --git a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_page_handler.cc b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_page_handler.cc index ff3570f6..63b5775 100644 --- a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_page_handler.cc +++ b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_page_handler.cc
@@ -10,8 +10,10 @@ CloudUploadPageHandler::CloudUploadPageHandler( mojo::PendingReceiver<chromeos::cloud_upload::mojom::PageHandler> - pending_page_handler) - : receiver_{this, std::move(pending_page_handler)} {} + pending_page_handler, + RespondAndCloseCallback callback) + : receiver_{this, std::move(pending_page_handler)}, + callback_{std::move(callback)} {} CloudUploadPageHandler::~CloudUploadPageHandler() = default; @@ -19,4 +21,10 @@ std::move(callback).Run(std::move(base::FilePath("/from Chromebook"))); } +void CloudUploadPageHandler::RespondAndClose(mojom::UserAction action) { + if (callback_) { + std::move(callback_).Run(action); + } +} + } // namespace chromeos::cloud_upload
diff --git a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_page_handler.h b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_page_handler.h index cdd43d30..84109e0 100644 --- a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_page_handler.h +++ b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_page_handler.h
@@ -7,6 +7,7 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" +#include "chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload.mojom-shared.h" #include "chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -20,9 +21,12 @@ class CloudUploadPageHandler : public chromeos::cloud_upload::mojom::PageHandler { public: + using RespondAndCloseCallback = + base::OnceCallback<void(mojom::UserAction action)>; explicit CloudUploadPageHandler( mojo::PendingReceiver<chromeos::cloud_upload::mojom::PageHandler> - pending_page_handler); + pending_page_handler, + RespondAndCloseCallback callback); CloudUploadPageHandler(const CloudUploadPageHandler&) = delete; CloudUploadPageHandler& operator=(const CloudUploadPageHandler&) = delete; @@ -31,9 +35,11 @@ // chromeos::cloud_upload::mojom::PageHandler: void GetUploadPath(GetUploadPathCallback callback) override; + void RespondAndClose(mojom::UserAction action) override; private: mojo::Receiver<chromeos::cloud_upload::mojom::PageHandler> receiver_; + RespondAndCloseCallback callback_; base::WeakPtrFactory<CloudUploadPageHandler> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_ui.cc b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_ui.cc index 849507b..d2a2620 100644 --- a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_ui.cc +++ b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_ui.cc
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_dialog.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/cloud_upload_resources.h" @@ -38,7 +39,24 @@ void CloudUploadUI::CreatePageHandler( mojo::PendingReceiver<chromeos::cloud_upload::mojom::PageHandler> receiver) { - page_handler_ = std::make_unique<CloudUploadPageHandler>(std::move(receiver)); + page_handler_ = std::make_unique<CloudUploadPageHandler>( + std::move(receiver), + // base::Unretained() because |page_handler_| will not out-live |this|. + base::BindOnce(&CloudUploadUI::RespondAndCloseDialog, + base::Unretained(this))); +} + +void CloudUploadUI::RespondAndCloseDialog(mojom::UserAction action) { + base::Value::List args; + switch (action) { + case mojom::UserAction::kCancel: + args.Append(kUserActionCancel); + break; + case mojom::UserAction::kUpload: + args.Append(kUserActionUpload); + break; + } + ui::MojoWebDialogUI::CloseDialog(args); } WEB_UI_CONTROLLER_TYPE_IMPL(CloudUploadUI);
diff --git a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_ui.h b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_ui.h index 0acdeb2..05366946 100644 --- a/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_ui.h +++ b/chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_ui.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_CLOUD_UPLOAD_CLOUD_UPLOAD_UI_H_ #define CHROME_BROWSER_UI_WEBUI_CHROMEOS_CLOUD_UPLOAD_CLOUD_UPLOAD_UI_H_ +#include "chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload.mojom-shared.h" #include "chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload.mojom.h" #include "chrome/browser/ui/webui/chromeos/cloud_upload/cloud_upload_page_handler.h" #include "ui/web_dialogs/web_dialog_ui.h" @@ -33,6 +34,8 @@ pending_page_handler) override; private: + void RespondAndCloseDialog(mojom::UserAction action); + std::unique_ptr<CloudUploadPageHandler> page_handler_; mojo::Receiver<chromeos::cloud_upload::mojom::PageHandlerFactory> factory_receiver_{this};
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index a0055ba..60faaa5 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1660262319-df4d2aa61d0ecf909385d6a8319a74ef4a051909.profdata +chrome-linux-main-1660283194-614a76bc5cb34a2be7e2e574e2de628b31c81dc1.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 5475c767..971e602 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1660262319-6f26dea356e87174d81e0ff907331abc64d4a442.profdata +chrome-mac-arm-main-1660283194-4fa820ca7e0d1fad4dc4f0154af2d5d5f0960255.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index f37fca7..9460942 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1660262319-2d6fb5df5e257782a18671b08771487af6b3c845.profdata +chrome-win32-main-1660272724-605bef00abb30293d48db5c16ecf9820a4056c82.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 671598c..ccfa001 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1660251404-8fed9aa357653c106ce422227a3d84de2b09bef2.profdata +chrome-win64-main-1660272724-a341adc354e2bd5e6471230013b7d0c75e8bf3f4.profdata
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index b6a0b9f..f25c9f0 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -244,6 +244,7 @@ "$root_gen_dir/chrome/audio_resources.pak", "$root_gen_dir/chrome/bluetooth_pairing_dialog_resources.pak", "$root_gen_dir/chrome/browser/supervised_user/supervised_user_unscaled_resources.pak", + "$root_gen_dir/chrome/cloud_upload_resources.pak", "$root_gen_dir/chrome/emoji_picker_resources.pak", "$root_gen_dir/chrome/gaia_action_buttons_resources.pak", "$root_gen_dir/chrome/internet_config_dialog_resources.pak",
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 06419f3..0cfcd6da 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -385,6 +385,12 @@ const base::Feature kExternalExtensionDefaultButtonControl{ "ExternalExtensionDefaultButtonControl", base::FEATURE_DISABLED_BY_DEFAULT}; +#if BUILDFLAG(IS_CHROMEOS_ASH) +COMPONENT_EXPORT(CHROME_FEATURES) +const base::Feature kFileTransferEnterpriseConnector{ + "FileTransferEnterpriseConnector", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif + #if BUILDFLAG(ENABLE_PLUGINS) // Show Flash deprecation warning to users who have manually enabled Flash. // https://crbug.com/918428 @@ -578,12 +584,6 @@ #endif #if BUILDFLAG(IS_ANDROID) -// When enabled, keeps Incognito UI consistent regardless of any selected theme. -const base::Feature kIncognitoBrandConsistencyForAndroid{ - "IncognitoBrandConsistencyForAndroid", base::FEATURE_DISABLED_BY_DEFAULT}; -#endif - -#if BUILDFLAG(IS_ANDROID) // When enabled, users will see a warning when downloading from Incognito. const base::Feature kIncognitoDownloadsWarning{ "IncognitoDownloadsWarning", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 7462850..efd14d7 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -272,6 +272,11 @@ COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kExternalExtensionDefaultButtonControl; +#if BUILDFLAG(IS_CHROMEOS_ASH) +COMPONENT_EXPORT(CHROME_FEATURES) +extern const base::Feature kFileTransferEnterpriseConnector; +#endif + #if BUILDFLAG(ENABLE_PLUGINS) COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kFlashDeprecationWarning; @@ -407,11 +412,6 @@ #if BUILDFLAG(IS_ANDROID) COMPONENT_EXPORT(CHROME_FEATURES) -extern const base::Feature kIncognitoBrandConsistencyForAndroid; -#endif - -#if BUILDFLAG(IS_ANDROID) -COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kIncognitoDownloadsWarning; #endif
diff --git a/chrome/renderer/cart/commerce_hint_agent.cc b/chrome/renderer/cart/commerce_hint_agent.cc index c006dce3..7b8d40ba 100644 --- a/chrome/renderer/cart/commerce_hint_agent.cc +++ b/chrome/renderer/cart/commerce_hint_agent.cc
@@ -804,53 +804,36 @@ blink::WebScriptSource source = blink::WebScriptSource( GetProductExtractionScript(product_id_json, cart_extraction_script)); - if (!javascript_request_) { - // This singleton never gets deleted, and will out-live CommerceHintAgen. - javascript_request_ = new JavaScriptRequest(weak_factory_.GetWeakPtr()); - } main_frame->RequestExecuteScript( ISOLATED_WORLD_ID_CHROME_INTERNAL, base::make_span(&source, 1), blink::mojom::UserActivationOption::kDoNotActivate, blink::mojom::EvaluationTiming::kAsynchronous, - blink::mojom::LoadEventBlockingOption::kDoNotBlock, javascript_request_, + blink::mojom::LoadEventBlockingOption::kDoNotBlock, + base::BindOnce(&CommerceHintAgent::OnProductsExtracted, + weak_factory_.GetWeakPtr()), blink::BackForwardCacheAware::kAllow, blink::mojom::PromiseResultOption::kAwait); } -CommerceHintAgent::JavaScriptRequest::JavaScriptRequest( - base::WeakPtr<CommerceHintAgent> agent) - : agent_(std::move(agent)) {} - -CommerceHintAgent::JavaScriptRequest::~JavaScriptRequest() = default; - -void CommerceHintAgent::JavaScriptRequest::WillExecute() { - start_time_ = base::TimeTicks::Now(); -} - -void CommerceHintAgent::JavaScriptRequest::Completed( - const blink::WebVector<v8::Local<v8::Value>>& result) { +void CommerceHintAgent::OnProductsExtracted( + const blink::WebVector<v8::Local<v8::Value>>& result, + base::TimeTicks start_time) { // Only record when the start time is correctly captured. - DCHECK(!start_time_.is_null()); - if (!agent_) - return; + DCHECK(!start_time.is_null()); if (result.empty() || result[0].IsEmpty()) return; - blink::WebLocalFrame* main_frame = agent_->render_frame()->GetWebFrame(); + blink::WebLocalFrame* main_frame = render_frame()->GetWebFrame(); v8::Local<v8::Context> context = main_frame->MainWorldScriptContext(); std::unique_ptr<base::Value> results = content::V8ValueConverter::Create()->FromV8Value(result[0], context); if (!results->is_dict()) return; - if (!start_time_.is_null()) { + if (!start_time.is_null()) { results->GetDict().Set( "execution_ms", - (base::TimeTicks::Now() - start_time_).InMillisecondsF()); + (base::TimeTicks::Now() - start_time).InMillisecondsF()); } - agent_->OnProductsExtracted(std::move(results)); -} -void CommerceHintAgent::OnProductsExtracted( - std::unique_ptr<base::Value> results) { if (!results) { DLOG(ERROR) << "OnProductsExtracted() got empty results"; return;
diff --git a/chrome/renderer/cart/commerce_hint_agent.h b/chrome/renderer/cart/commerce_hint_agent.h index b2f3dd40..d82c2550 100644 --- a/chrome/renderer/cart/commerce_hint_agent.h +++ b/chrome/renderer/cart/commerce_hint_agent.h
@@ -13,13 +13,8 @@ #include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_frame_observer_tracker.h" #include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/web/web_script_execution_callback.h" #include "url/gurl.h" -namespace base { -class Value; -} - namespace ukm { class MojoUkmRecorder; } @@ -56,7 +51,6 @@ // as |request_url| should be skipped for AddToCart detection. static bool ShouldSkipAddToCartRequest(const GURL& navigation_url, const GURL& request_url); - void OnProductsExtracted(std::unique_ptr<base::Value> result); static const std::vector<std::string> ExtractButtonTexts( const blink::WebFormElement& form); @@ -68,9 +62,9 @@ mojo::Remote<mojom::CommerceHintObserver> observer, const std::string& product_id_json, const std::string& cart_extraction_script); - class JavaScriptRequest; + void OnProductsExtracted(const blink::WebVector<v8::Local<v8::Value>>& result, + base::TimeTicks start_time); - JavaScriptRequest* javascript_request_{nullptr}; GURL starting_url_; bool has_finished_loading_{false}; int extraction_count_{0}; @@ -81,21 +75,6 @@ std::unique_ptr<ukm::MojoUkmRecorder> ukm_recorder_; base::WeakPtrFactory<CommerceHintAgent> weak_factory_{this}; - class JavaScriptRequest : public blink::WebScriptExecutionCallback { - public: - explicit JavaScriptRequest(base::WeakPtr<CommerceHintAgent> agent); - JavaScriptRequest(const JavaScriptRequest&) = delete; - JavaScriptRequest& operator=(const JavaScriptRequest&) = delete; - void WillExecute() override; - void Completed( - const blink::WebVector<v8::Local<v8::Value>>& result) override; - - private: - ~JavaScriptRequest() override; - base::WeakPtr<CommerceHintAgent> agent_; - base::TimeTicks start_time_; - }; - // content::RenderFrameObserver overrides void OnDestruct() override; void WillSendRequest(const blink::WebURLRequest& request) override;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 86d187f..b125c392 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -6299,6 +6299,7 @@ "../browser/download/android/available_offline_content_provider_unittest.cc", "../browser/download/android/download_manager_service_unittest.cc", "../browser/enterprise/util/android_enterprise_info_unittest.cc", + "../browser/fast_checkout/fast_checkout_capabilities_results_cache_unittest.cc", "../browser/fast_checkout/fast_checkout_client_impl_unittest.cc", "../browser/fast_checkout/fast_checkout_external_action_delegate_unittest.cc", "../browser/fast_checkout/fast_checkout_util_unittest.cc", @@ -7481,6 +7482,7 @@ "../browser/lacros/sync/sync_user_settings_client_lacros_unittest.cc", "../browser/metrics/lacros_metrics_provider_unittest.cc", "../browser/notifications/notification_platform_bridge_lacros_unittest.cc", + "../browser/performance_manager/policies/oom_score_policy_lacros_unittest.cc", "../browser/policy/restricted_mgs_policy_provider_lacros_unittest.cc", "../browser/signin/signin_ui_delegate_impl_lacros_unittest.cc", "../browser/upgrade_detector/get_installed_version_lacros_unittest.cc",
diff --git a/chrome/test/base/chromeos/fake_ash_test_chrome_browser_main_extra_parts.cc b/chrome/test/base/chromeos/fake_ash_test_chrome_browser_main_extra_parts.cc index 05ac6f6..0ca468ae 100644 --- a/chrome/test/base/chromeos/fake_ash_test_chrome_browser_main_extra_parts.cc +++ b/chrome/test/base/chromeos/fake_ash_test_chrome_browser_main_extra_parts.cc
@@ -66,7 +66,6 @@ crosapi::CrosapiManager::Get()->crosapi_ash()->SetTestControllerForTesting( test_controller_ash_.get()); - crosapi::BrowserManager::Get()->DisableAutoLaunchForTesting(); views::InputEventActivationProtector::DisableForTesting(); ignore_signin_errors_ =
diff --git a/chrome/test/data/app_deduplication_service/binary_test_data.pb b/chrome/test/data/app_deduplication_service/binary_test_data.pb new file mode 100644 index 0000000..b5ee5267 --- /dev/null +++ b/chrome/test/data/app_deduplication_service/binary_test_data.pb
@@ -0,0 +1,17 @@ + +^ +SkypeU + +com.skype.raiderJphonehub + +com.skype.raiderJarc + +http://web.skype.com/Jweb +\ +WhatsAppP + +com.whatsappJphonehub + +com.whatsappJarc + +http://web.whatsapp.com/Jweb \ No newline at end of file
diff --git a/chrome/test/data/extensions/api_test/file_browser/dlp_metadata/test.js b/chrome/test/data/extensions/api_test/file_browser/dlp_metadata/test.js index 4c9bb96..52dc7fb 100644 --- a/chrome/test/data/extensions/api_test/file_browser/dlp_metadata/test.js +++ b/chrome/test/data/extensions/api_test/file_browser/dlp_metadata/test.js
@@ -118,6 +118,30 @@ } ]); break; + case 'restriction_details': + chrome.test.runTests([async function getDlpRestrictionDetails() { + chrome.fileManagerPrivate.getDlpRestrictionDetails( + 'https://example1.com', + chrome.test.callbackPass(dlpRestrictionDetails => { + chrome.test.assertEq( + [ + { + 'components': [ + 'android_files', 'crostini', 'guest_os', 'removable' + ], + 'level': 'block', + 'urls': ['https://external.com'] + }, + { + 'components': ['drive'], + 'level': 'allow', + 'urls': ['https://internal.com'] + } + ], + dlpRestrictionDetails); + })); + }]); + break; case 'default': chrome.test.runTests([ async function getDlpMetadata() { @@ -141,13 +165,6 @@ ], dlpMetadata); })) - }, - async function getDlpRestrictionDetails() { - chrome.fileManagerPrivate.getDlpRestrictionDetails( - 'https://example1.com', - chrome.test.callbackPass(dlpRestrictionDetails => { - chrome.test.assertEq([], dlpRestrictionDetails); - })); } ]); break;
diff --git a/chrome/test/data/system_extensions/basic_system_extension/manifest.json b/chrome/test/data/system_extensions/basic_system_extension/manifest.json index 2c8a867..6815034f 100644 --- a/chrome/test/data/system_extensions/basic_system_extension/manifest.json +++ b/chrome/test/data/system_extensions/basic_system_extension/manifest.json
@@ -1,7 +1,6 @@ { "name": "Sample System Web Extension", "short_name": "Sample SWX", - "companion_web_app_url": "https://example.com", "service_worker_url": "/sw.js", "id": "01020304", "type": "echo"
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js index 04bfbae..3ff1de4 100644 --- a/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js +++ b/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js
@@ -620,4 +620,20 @@ assertEquals(1, feedbackServiceProvider.getOpenSystemInfoDialogCallCount()); }); + + /** + * Test that feedbackServiceProvider.openBluetoothLogsInfoDialog is called + * when #bluetoothLogsLink link is clicked. + */ + test('openBluetoothLogsInfoDialog', async () => { + await initializePage(); + + assertEquals( + 0, feedbackServiceProvider.getOpenBluetoothLogsInfoDialogCallCount()); + + getElement('#bluetoothLogsInfoLink').click(); + + assertEquals( + 1, feedbackServiceProvider.getOpenBluetoothLogsInfoDialogCallCount()); + }); }
diff --git a/chrome/updater/persisted_data.cc b/chrome/updater/persisted_data.cc index 534e29c..ed59e69 100644 --- a/chrome/updater/persisted_data.cc +++ b/chrome/updater/persisted_data.cc
@@ -151,10 +151,9 @@ // The prefs is a dictionary of dictionaries, where each inner dictionary // corresponds to an app: // {"updateclientdata":{"apps":{"{44FC7FE2-65CE-487C-93F4-EDEE46EEAAAB}":{... - const auto* pref = pref_service_->GetDictionary(kPersistedDataPreference); - if (!pref) - return {}; - const auto* apps = pref->GetDict().FindDict("apps"); + const base::Value::Dict& dict = + pref_service_->GetValueDict(kPersistedDataPreference); + const base::Value::Dict* apps = dict.FindDict("apps"); if (!apps) return {}; std::vector<std::string> app_ids;
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 8b89290..443088e 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -3457,6 +3457,9 @@ <message name="IDS_FEEDBACK_TOOL_INCLUDE_SYSTEM_INFO_AND_METRICS_CHECKBOX_LABEL" desc="Checkbox for including system information and metrics on the bug report dialog box"> Send <ph name="BEGIN_LINK1"><a id="sysInfoLink"></ph>system and app info<ph name="END_LINK1"></a></ph> and <ph name="BEGIN_LINK2"><a id="histogramsLink"></ph>metrics<ph name="END_LINK2"></a></ph> </message> + <message name="IDS_FEEDBACK_TOOL_BLUETOOTH_LOGS_CHECKBOX" translateable="false" desc="Checkbox for Google internal account to attach bluetooth logs from the current session."> + Attach <ph name="BEGIN_LINK1"><a id="bluetoothLogsInfoLink"></ph>Bluetooth Logs<ph name="END_LINK1"></a></ph> (Google internal) + </message> <message name="IDS_FEEDBACK_TOOL_PRIVACY_NOTE" desc="Text for the privacy note included in the feedback app"> Go to the <ph name="BEGIN_LINK1"><a id="legalHelpPageUrl"></ph>Legal Help page<ph name="END_LINK1"></a></ph> to request content changes for legal reasons. Some account and system information may be sent to Google. We will use the information you give us to help address technical issues and to improve our services, subject to our <ph name="BEGIN_LINK2"><a id="privacyPolicyUrl"></ph>Privacy Policy<ph name="END_LINK2"></a></ph> and <ph name="BEGIN_LINK3"><a id="termsOfServiceUrl"></ph>Terms of Service<ph name="END_LINK3"></a></ph>. </message>
diff --git a/components/autofill/core/browser/address_profile_save_manager_unittest.cc b/components/autofill/core/browser/address_profile_save_manager_unittest.cc index 99ed61bc..08faa9e 100644 --- a/components/autofill/core/browser/address_profile_save_manager_unittest.cc +++ b/components/autofill/core/browser/address_profile_save_manager_unittest.cc
@@ -427,28 +427,23 @@ } if (is_confirmable_merge && - test_scenario.user_decision == UserDecision::kAccepted) { - histogram_tester.ExpectTotalCount( - kProfileUpdateAffectedTypesHistogram, - test_scenario.expected_affeceted_types_in_merge_for_metrics.size()); + (test_scenario.user_decision == UserDecision::kAccepted || + test_scenario.user_decision == UserDecision::kDeclined)) { + std::string changed_histogram_suffix; + switch (test_scenario.user_decision) { + case UserDecision::kAccepted: + changed_histogram_suffix = ".Accepted"; + break; + case UserDecision::kDeclined: + changed_histogram_suffix = ".Declined"; + break; + + default: + NOTREACHED() << "Decision not covered by test logic."; + } for (auto changed_type : test_scenario.expected_affeceted_types_in_merge_for_metrics) { - histogram_tester.ExpectBucketCount(kProfileUpdateAffectedTypesHistogram, - changed_type, 1); - std::string changed_histogram_suffix; - switch (test_scenario.user_decision) { - case UserDecision::kAccepted: - changed_histogram_suffix = ".Accepted"; - break; - - case UserDecision::kDeclined: - changed_histogram_suffix = ".Declined"; - break; - - default: - NOTREACHED() << "Decision not covered by test logic."; - } histogram_tester.ExpectBucketCount( base::StrCat({kProfileUpdateAffectedTypesHistogram, changed_histogram_suffix}), @@ -456,7 +451,8 @@ } histogram_tester.ExpectUniqueSample( - kProfileUpdateNumberOfAffectedTypesHistogram, + base::StrCat({kProfileUpdateNumberOfAffectedTypesHistogram, + changed_histogram_suffix}), test_scenario.expected_affeceted_types_in_merge_for_metrics.size(), 1); } @@ -907,7 +903,10 @@ .is_profile_change_expected = false, .merge_candidate = mergeable_profile, .import_candidate = final_profile, - .expected_final_profiles = {mergeable_profile}}; + .expected_final_profiles = {mergeable_profile}, + .expected_affeceted_types_in_merge_for_metrics = { + AutofillMetrics::SettingsVisibleFieldTypeForMetrics::kZip, + AutofillMetrics::SettingsVisibleFieldTypeForMetrics::kCity}}; TestImportScenario(test_scenario); } @@ -1070,7 +1069,10 @@ .merge_candidate = mergeable_profile, .import_candidate = merged_profile, .expected_final_profiles = {existing_duplicate, updated_profile, - mergeable_profile}}; + mergeable_profile}, + .expected_affeceted_types_in_merge_for_metrics = { + AutofillMetrics::SettingsVisibleFieldTypeForMetrics::kZip, + AutofillMetrics::SettingsVisibleFieldTypeForMetrics::kCity}}; TestImportScenario(test_scenario); }
diff --git a/components/autofill/core/browser/metrics/autofill_metrics.cc b/components/autofill/core/browser/metrics/autofill_metrics.cc index 0c7eca4..d77e28d 100644 --- a/components/autofill/core/browser/metrics/autofill_metrics.cc +++ b/components/autofill/core/browser/metrics/autofill_metrics.cc
@@ -3132,16 +3132,6 @@ void AutofillMetrics::LogProfileUpdateAffectedType( ServerFieldType affected_type, AutofillClient::SaveAddressProfileOfferUserDecision decision) { - // TODO(crbug.com/1253798): Remove the special-case metric in favor of more - // general one once the majority of clients contribute to the more general - // one. - if (decision == - AutofillClient::SaveAddressProfileOfferUserDecision::kAccepted) { - base::UmaHistogramEnumeration( - "Autofill.ProfileImport.UpdateProfileAffectedType", - ConvertSettingsVisibleFieldTypeForMetrics(affected_type)); - } - // Record the decision-specific metric. base::UmaHistogramEnumeration( base::StrCat({"Autofill.ProfileImport.UpdateProfileAffectedType", @@ -3176,25 +3166,16 @@ void AutofillMetrics::LogUpdateProfileNumberOfAffectedFields( int number_of_edited_fields, AutofillClient::SaveAddressProfileOfferUserDecision decision) { - // TODO(crbug.com/1253798): Remove the special-case metric in favor of more - // general one once the majority of clients contribute to the more general - // one. - if (decision == - AutofillClient::SaveAddressProfileOfferUserDecision::kAccepted) { - base::UmaHistogramExactLinear( - "Autofill.ProfileImport.UpdateProfileNumberOfAffectedFields", - number_of_edited_fields, /*exclusive_max=*/15); - } - // Record the decision-specific metric. base::UmaHistogramExactLinear( - base::StrCat({"Autofill.ProfileImport.UpdateProfileAffectedType", - GetSaveAndUpdatePromptDecisionMetricsSuffix(decision)}), + base::StrCat( + {"Autofill.ProfileImport.UpdateProfileNumberOfAffectedFields", + GetSaveAndUpdatePromptDecisionMetricsSuffix(decision)}), number_of_edited_fields, /*exclusive_max=*/15); // But also collect an histogram for any decision. base::UmaHistogramExactLinear( - "Autofill.ProfileImport.UpdateProfileAffectedType.Any", + "Autofill.ProfileImport.UpdateProfileNumberOfAffectedFields.Any", number_of_edited_fields, /*exclusive_max=*/15); }
diff --git a/components/js_injection/renderer/js_binding.cc b/components/js_injection/renderer/js_binding.cc index c8efbd2..bad08b8 100644 --- a/components/js_injection/renderer/js_binding.cc +++ b/components/js_injection/renderer/js_binding.cc
@@ -116,8 +116,7 @@ v8::Local<v8::Object> self = GetWrapper(isolate).ToLocalChecked(); v8::Local<v8::Function> on_message = GetOnMessage(isolate); if (!on_message.IsEmpty()) { - web_frame->RequestExecuteV8Function(context, on_message, self, 1, argv, - nullptr); + web_frame->RequestExecuteV8Function(context, on_message, self, 1, argv, {}); } // Copy the listeners so that if the listener modifies the list in some way @@ -130,8 +129,7 @@ for (const auto& listener : listeners_copy) { // Ensure the listener is still registered. if (base::Contains(listeners_, listener)) { - web_frame->RequestExecuteV8Function(context, listener, self, 1, argv, - nullptr); + web_frame->RequestExecuteV8Function(context, listener, self, 1, argv, {}); } } }
diff --git a/components/safe_browsing/core/browser/safe_browsing_metrics_collector_unittest.cc b/components/safe_browsing/core/browser/safe_browsing_metrics_collector_unittest.cc index 79da958..ca4f9d5 100644 --- a/components/safe_browsing/core/browser/safe_browsing_metrics_collector_unittest.cc +++ b/components/safe_browsing/core/browser/safe_browsing_metrics_collector_unittest.cc
@@ -44,24 +44,22 @@ time.ToDeltaSinceWindowsEpoch().InSeconds()); } - const base::Value* GetTsFromUserStateAndEventType(UserState state, - EventType event_type) { - const base::Value* state_dict = - pref_service_.GetDictionary(prefs::kSafeBrowsingEventTimestamps); - const base::Value* event_dict = - state_dict->FindDictKey(base::NumberToString(static_cast<int>(state))); + const base::Value::List& GetTsFromUserStateAndEventType( + UserState state, + EventType event_type) { + const base::Value::Dict& state_dict = + pref_service_.GetValueDict(prefs::kSafeBrowsingEventTimestamps); + const base::Value::Dict* event_dict = + state_dict.FindDict(base::NumberToString(static_cast<int>(state))); DCHECK(event_dict); - DCHECK(event_dict->is_dict()); - const base::Value* timestamps = event_dict->FindListKey( + const base::Value::List* timestamps = event_dict->FindList( base::NumberToString(static_cast<int>(event_type))); DCHECK(timestamps); - DCHECK(timestamps->is_list()); - return timestamps; + return *timestamps; } - bool IsSortedInChronologicalOrder(const base::Value* ts) { - return std::is_sorted(ts->GetListDeprecated().begin(), - ts->GetListDeprecated().end(), + bool IsSortedInChronologicalOrder(const base::Value::List& ts) { + return std::is_sorted(ts.begin(), ts.end(), [](const base::Value& ts_a, const base::Value& ts_b) { return base::ValueToInt64(ts_a).value_or(0) < base::ValueToInt64(ts_b).value_or(0); @@ -213,23 +211,21 @@ EventType::DATABASE_INTERSTITIAL_BYPASS); } - const base::Value* timestamps = GetTsFromUserStateAndEventType( + const base::Value::List& timestamps = GetTsFromUserStateAndEventType( UserState::kEnhancedProtection, EventType::DATABASE_INTERSTITIAL_BYPASS); - EXPECT_EQ(30u, timestamps->GetListDeprecated().size()); + EXPECT_EQ(30u, timestamps.size()); EXPECT_TRUE(IsSortedInChronologicalOrder(timestamps)); task_environment_.FastForwardBy(base::Days(1)); metrics_collector_->AddSafeBrowsingEventToPref( EventType::DATABASE_INTERSTITIAL_BYPASS); - EXPECT_EQ(30u, timestamps->GetListDeprecated().size()); + EXPECT_EQ(30u, timestamps.size()); EXPECT_TRUE(IsSortedInChronologicalOrder(timestamps)); // The oldest timestamp should be removed. - EXPECT_EQ(timestamps->GetListDeprecated()[0], - timestamps->GetListDeprecated()[1]); + EXPECT_EQ(timestamps[0], timestamps[1]); // The newest timestamp should be added as the last element. - EXPECT_NE(timestamps->GetListDeprecated()[28], - timestamps->GetListDeprecated()[29]); + EXPECT_NE(timestamps[28], timestamps[29]); } TEST_F(SafeBrowsingMetricsCollectorTest, @@ -246,12 +242,12 @@ metrics_collector_->AddSafeBrowsingEventToPref( EventType::DATABASE_INTERSTITIAL_BYPASS); - const base::Value* enhanced_timestamps = GetTsFromUserStateAndEventType( + const base::Value::List& enhanced_timestamps = GetTsFromUserStateAndEventType( UserState::kEnhancedProtection, EventType::DATABASE_INTERSTITIAL_BYPASS); - EXPECT_EQ(1u, enhanced_timestamps->GetListDeprecated().size()); - const base::Value* managed_timestamps = GetTsFromUserStateAndEventType( + EXPECT_EQ(1u, enhanced_timestamps.size()); + const base::Value::List& managed_timestamps = GetTsFromUserStateAndEventType( UserState::kManaged, EventType::DATABASE_INTERSTITIAL_BYPASS); - EXPECT_EQ(2u, managed_timestamps->GetListDeprecated().size()); + EXPECT_EQ(2u, managed_timestamps.size()); } TEST_F(SafeBrowsingMetricsCollectorTest, @@ -798,18 +794,18 @@ FastForwardAndAddEvent(base::Days(1), EventType::CSD_INTERSTITIAL_BYPASS); task_environment_.FastForwardBy(base::Days(30)); - const base::Value* db_timestamps = GetTsFromUserStateAndEventType( + const base::Value::List& db_timestamps = GetTsFromUserStateAndEventType( UserState::kStandardProtection, EventType::DATABASE_INTERSTITIAL_BYPASS); // The event is removed from pref because it was logged more than 30 days. - EXPECT_EQ(0u, db_timestamps->GetListDeprecated().size()); - const base::Value* csd_timestamps = GetTsFromUserStateAndEventType( + EXPECT_EQ(0u, db_timestamps.size()); + const base::Value::List& csd_timestamps = GetTsFromUserStateAndEventType( UserState::kStandardProtection, EventType::CSD_INTERSTITIAL_BYPASS); // The CSD event is still in pref because it was logged less than 30 days. - EXPECT_EQ(1u, csd_timestamps->GetListDeprecated().size()); + EXPECT_EQ(1u, csd_timestamps.size()); task_environment_.FastForwardBy(base::Days(1)); // The CSD event is also removed because it was logged more than 30 days now. - EXPECT_EQ(0u, csd_timestamps->GetListDeprecated().size()); + EXPECT_EQ(0u, csd_timestamps.size()); histograms.ExpectUniqueSample("SafeBrowsing.MetricsCollector.IsPrefValid", /* sample */ 1,
diff --git a/components/services/screen_ai/proto/proto_convertor_unittest.cc b/components/services/screen_ai/proto/proto_convertor_unittest.cc index 653380d..5b36dbf 100644 --- a/components/services/screen_ai/proto/proto_convertor_unittest.cc +++ b/components/services/screen_ai/proto/proto_convertor_unittest.cc
@@ -435,7 +435,7 @@ ProtoConvertorViewHierarchyTest, testing::Range(0, kProtoConversionTestCasesCount)); -TEST_P(ProtoConvertorViewHierarchyTest, EndToEndTest) { +TEST_P(ProtoConvertorViewHierarchyTest, AxTreeJsonToProtoTest) { const base::FilePath kInputJsonPath = GetInputFilePath(); const base::FilePath kExpectedProtoPath = GetExpectedFilePath();
diff --git a/components/services/screen_ai/public/cpp/utilities.cc b/components/services/screen_ai/public/cpp/utilities.cc index 490ae84..6d324fb 100644 --- a/components/services/screen_ai/public/cpp/utilities.cc +++ b/components/services/screen_ai/public/cpp/utilities.cc
@@ -15,7 +15,7 @@ const base::FilePath::CharType kScreenAISubDirName[] = FILE_PATH_LITERAL("screen_ai"); -const base::FilePath::CharType kScreenAILibraryFileName[] = +const base::FilePath::CharType kScreenAIComponentBinaryName[] = FILE_PATH_LITERAL("libchrome_screen_ai.so"); enum { @@ -34,7 +34,7 @@ return base::FilePath(kScreenAISubDirName); } -base::FilePath GetComponentPath() { +base::FilePath GetComponentDir() { base::FilePath components_dir; base::PathService::Get(component_updater::DIR_COMPONENT_USER, &components_dir); @@ -44,8 +44,8 @@ return components_dir.Append(kScreenAISubDirName); } -base::FilePath GetLatestLibraryFilePath() { - base::FilePath screen_ai_dir = GetComponentPath(); +base::FilePath GetLatestComponentBinaryPath() { + base::FilePath screen_ai_dir = GetComponentDir(); if (screen_ai_dir.empty()) return base::FilePath(); @@ -60,19 +60,19 @@ latest_version_dir < version_dir ? version_dir : latest_version_dir; } - base::FilePath library_path = - latest_version_dir.Append(kScreenAILibraryFileName); - if (!base::PathExists(library_path)) + base::FilePath component_path = + latest_version_dir.Append(kScreenAIComponentBinaryName); + if (!base::PathExists(component_path)) return base::FilePath(); - return library_path; + return component_path; } -void StoreLibraryBinaryPath(const base::FilePath& path) { +void StoreComponentBinaryPath(const base::FilePath& path) { base::PathService::Override(PATH_SCREEN_AI_LIBRARY_BINARY, path); } -base::FilePath GetStoredLibraryBinaryPath() { +base::FilePath GetStoredComponentBinaryPath() { base::FilePath path; base::PathService::Get(PATH_SCREEN_AI_LIBRARY_BINARY, &path); return path;
diff --git a/components/services/screen_ai/public/cpp/utilities.h b/components/services/screen_ai/public/cpp/utilities.h index 143cb18..7538507 100644 --- a/components/services/screen_ai/public/cpp/utilities.h +++ b/components/services/screen_ai/public/cpp/utilities.h
@@ -9,22 +9,22 @@ namespace screen_ai { -// Get the absolute path of the ScreenAI library. -base::FilePath GetLatestLibraryFilePath(); +// Get the absolute path of the ScreenAI component. +base::FilePath GetLatestComponentBinaryPath(); // Returns the install directory relative to components folder. base::FilePath GetRelativeInstallDir(); // Returns the folder in which ScreenAI component is installed. -base::FilePath GetComponentPath(); +base::FilePath GetComponentDir(); -// Stores the path to the library binary. This value is kept in memory and is +// Stores the path to the component binary. This value is kept in memory and is // not kept between sessions or shared between processes. -void StoreLibraryBinaryPath(const base::FilePath& path); +void StoreComponentBinaryPath(const base::FilePath& path); -// Returns the library binary path if it is already stored by -// |StoreLibraryBinaryPath|. -base::FilePath GetStoredLibraryBinaryPath(); +// Returns the component binary path if it is already stored by +// |StoreComponentBinaryPath|. +base::FilePath GetStoredComponentBinaryPath(); } // namespace screen_ai #endif // COMPONENTS_SERVICES_SCREEN_AI_PUBLIC_CPP_UTILITIES_H_
diff --git a/components/services/screen_ai/sandbox/screen_ai_sandbox_hook_linux.cc b/components/services/screen_ai/sandbox/screen_ai_sandbox_hook_linux.cc index eb72269..1f4efaa 100644 --- a/components/services/screen_ai/sandbox/screen_ai_sandbox_hook_linux.cc +++ b/components/services/screen_ai/sandbox/screen_ai_sandbox_hook_linux.cc
@@ -18,9 +18,9 @@ namespace screen_ai { bool ScreenAIPreSandboxHook(sandbox::policy::SandboxLinux::Options options) { - base::FilePath library_path = screen_ai::GetLatestLibraryFilePath(); + base::FilePath library_path = screen_ai::GetLatestComponentBinaryPath(); if (library_path.empty()) { - VLOG(1) << "Screen AI library not found."; + VLOG(1) << "Screen AI component binary not found."; } else { void* screen_ai_library = dlopen(library_path.value().c_str(), RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE); @@ -34,7 +34,7 @@ VLOG(2) << "Screen AI library loaded pre-sandboxing:" << library_path; } } - screen_ai::StoreLibraryBinaryPath(library_path); + screen_ai::StoreComponentBinaryPath(library_path); auto* instance = sandbox::policy::SandboxLinux::GetInstance();
diff --git a/components/services/screen_ai/screen_ai_service_impl.cc b/components/services/screen_ai/screen_ai_service_impl.cc index ef7f8de..92170c6 100644 --- a/components/services/screen_ai/screen_ai_service_impl.cc +++ b/components/services/screen_ai/screen_ai_service_impl.cc
@@ -18,7 +18,7 @@ namespace { base::FilePath GetLibraryFilePath() { - base::FilePath library_path = GetStoredLibraryBinaryPath(); + base::FilePath library_path = GetStoredComponentBinaryPath(); if (!library_path.empty()) return library_path; @@ -26,8 +26,8 @@ // Binary file path is set while setting the sandbox on Linux, or the first // time this function is called. So in all other cases we need to look for // the library binary in its component folder. - library_path = GetLatestLibraryFilePath(); - StoreLibraryBinaryPath(library_path); + library_path = GetLatestComponentBinaryPath(); + StoreComponentBinaryPath(library_path); return library_path; }
diff --git a/content/browser/web_package/prefetched_signed_exchange_cache.cc b/content/browser/web_package/prefetched_signed_exchange_cache.cc index 4ecaf23a..19beb5377 100644 --- a/content/browser/web_package/prefetched_signed_exchange_cache.cc +++ b/content/browser/web_package/prefetched_signed_exchange_cache.cc
@@ -221,7 +221,7 @@ if (network::cors::ShouldCheckCors(request.url, request.request_initiator, request.mode)) { - const auto error_status = network::cors::CheckAccessAndReportMetrics( + const auto result = network::cors::CheckAccessAndReportMetrics( request.url, GetHeaderString( *response_, @@ -230,8 +230,8 @@ *response_, network::cors::header_names::kAccessControlAllowCredentials), request.credentials_mode, *request.request_initiator); - if (error_status) { - client_->OnComplete(network::URLLoaderCompletionStatus(*error_status)); + if (!result.has_value()) { + client_->OnComplete(network::URLLoaderCompletionStatus(result.error())); return; } }
diff --git a/docs/code_reviews.md b/docs/code_reviews.md index 2ee4d62..7516ffc 100644 --- a/docs/code_reviews.md +++ b/docs/code_reviews.md
@@ -122,6 +122,14 @@ * If there are objections, then the decision should be escalated to the [../CHROME_ENG_REVIEW](//CHROME_ENG_REVIEW) for resolution. +Note: For the purpose of not slowing down code review, Chromium removes +inactive owners (e.g., those who made no contributions for multiple quarters) +on a regular basis. The script does not take into account personal situations +like a long leave. If you were inactive only for a certain period of time +while you were on a long leave and have been meeting the above owner's +expectations in other times, you can create a CL to re-add yourself and land +after getting local owner's approval (you can refer to this policy in the CL). + ### OWNERS file details Refer to the [owners plugin](https://github.com/GerritCodeReview/plugins_code-owners/blob/master/resources/Documentation/backend-find-owners.md)
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn index 3594e5d..113fc2d 100644 --- a/extensions/renderer/BUILD.gn +++ b/extensions/renderer/BUILD.gn
@@ -190,8 +190,6 @@ "script_context_set_iterable.h", "script_injection.cc", "script_injection.h", - "script_injection_callback.cc", - "script_injection_callback.h", "script_injection_manager.cc", "script_injection_manager.h", "script_injector.h",
diff --git a/extensions/renderer/extension_js_runner.cc b/extensions/renderer/extension_js_runner.cc index 1fa10a9f..9c97c29 100644 --- a/extensions/renderer/extension_js_runner.cc +++ b/extensions/renderer/extension_js_runner.cc
@@ -7,8 +7,8 @@ #include "base/bind.h" #include "content/public/renderer/worker_thread.h" #include "extensions/renderer/script_context.h" -#include "extensions/renderer/script_injection_callback.h" #include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_script_execution_callback.h" #include "v8/include/v8-function.h" #include "v8/include/v8-isolate.h" #include "v8/include/v8-microtask-queue.h" @@ -24,7 +24,7 @@ int argc, v8::Local<v8::Value> argv[], ResultCallback callback) { - ScriptInjectionCallback::CompleteCallback wrapper_callback; + blink::WebScriptExecutionCallback wrapper_callback; if (callback) { wrapper_callback = base::BindOnce(&ExtensionJSRunner::OnFunctionComplete, @@ -75,7 +75,8 @@ void ExtensionJSRunner::OnFunctionComplete( ResultCallback callback, - const std::vector<v8::Local<v8::Value>>& results) { + const blink::WebVector<v8::Local<v8::Value>>& results, + base::TimeTicks start_time) { DCHECK(script_context_->is_valid()); v8::MaybeLocal<v8::Value> result;
diff --git a/extensions/renderer/extension_js_runner.h b/extensions/renderer/extension_js_runner.h index 591abb6..d88139b 100644 --- a/extensions/renderer/extension_js_runner.h +++ b/extensions/renderer/extension_js_runner.h
@@ -6,7 +6,9 @@ #define EXTENSIONS_RENDERER_EXTENSION_JS_RUNNER_H_ #include "base/memory/weak_ptr.h" +#include "base/time/time.h" #include "extensions/renderer/bindings/js_runner.h" +#include "third_party/blink/public/platform/web_vector.h" #include "v8/include/v8-forward.h" namespace extensions { @@ -37,7 +39,8 @@ private: // Called with the result of executing the JS function. void OnFunctionComplete(ResultCallback callback, - const std::vector<v8::Local<v8::Value>>& results); + const blink::WebVector<v8::Local<v8::Value>>& results, + base::TimeTicks start_time); // The associated ScriptContext. Guaranteed to outlive this object. ScriptContext* const script_context_;
diff --git a/extensions/renderer/module_system.cc b/extensions/renderer/module_system.cc index ae06cd97..b6ea1359 100644 --- a/extensions/renderer/module_system.cc +++ b/extensions/renderer/module_system.cc
@@ -323,7 +323,7 @@ v8::HandleScope handle_scope(GetIsolate()); v8::Local<v8::Value> no_args; CallModuleMethodSafe(module_name, method_name, 0, &no_args, - ScriptInjectionCallback::CompleteCallback()); + blink::WebScriptExecutionCallback()); } void ModuleSystem::CallModuleMethodSafe( @@ -331,7 +331,7 @@ const std::string& method_name, std::vector<v8::Local<v8::Value>>* args) { CallModuleMethodSafe(module_name, method_name, args->size(), args->data(), - ScriptInjectionCallback::CompleteCallback()); + blink::WebScriptExecutionCallback()); } void ModuleSystem::CallModuleMethodSafe(const std::string& module_name, @@ -339,7 +339,7 @@ int argc, v8::Local<v8::Value> argv[]) { CallModuleMethodSafe(module_name, method_name, argc, argv, - ScriptInjectionCallback::CompleteCallback()); + blink::WebScriptExecutionCallback()); } void ModuleSystem::CallModuleMethodSafe( @@ -347,7 +347,7 @@ const std::string& method_name, int argc, v8::Local<v8::Value> argv[], - ScriptInjectionCallback::CompleteCallback callback) { + blink::WebScriptExecutionCallback callback) { TRACE_EVENT2("v8", "v8.callModuleMethodSafe", "module_name", module_name, "method_name", method_name);
diff --git a/extensions/renderer/module_system.h b/extensions/renderer/module_system.h index 11d4571..1830092b 100644 --- a/extensions/renderer/module_system.h +++ b/extensions/renderer/module_system.h
@@ -15,7 +15,7 @@ #include "base/compiler_specific.h" #include "extensions/renderer/native_handler.h" #include "extensions/renderer/object_backed_native_handler.h" -#include "extensions/renderer/script_injection_callback.h" +#include "third_party/blink/public/web/web_script_execution_callback.h" #include "v8/include/v8-forward.h" #include "v8/include/v8-object.h" #include "v8/include/v8-persistent-handle.h" @@ -104,7 +104,7 @@ const std::string& method_name, int argc, v8::Local<v8::Value> argv[], - ScriptInjectionCallback::CompleteCallback callback); + blink::WebScriptExecutionCallback callback); // Register |native_handler| as a potential target for requireNative(), so // calls to requireNative(|name|) from JS will return a new object created by
diff --git a/extensions/renderer/script_context.cc b/extensions/renderer/script_context.cc index 8f86fc15..b01ddac 100644 --- a/extensions/renderer/script_context.cc +++ b/extensions/renderer/script_context.cc
@@ -279,15 +279,14 @@ void ScriptContext::SafeCallFunction(const v8::Local<v8::Function>& function, int argc, v8::Local<v8::Value> argv[]) { - SafeCallFunction(function, argc, argv, - ScriptInjectionCallback::CompleteCallback()); + SafeCallFunction(function, argc, argv, blink::WebScriptExecutionCallback()); } void ScriptContext::SafeCallFunction( const v8::Local<v8::Function>& function, int argc, v8::Local<v8::Value> argv[], - ScriptInjectionCallback::CompleteCallback callback) { + blink::WebScriptExecutionCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); v8::HandleScope handle_scope(isolate()); v8::Context::Scope scope(v8_context()); @@ -295,20 +294,16 @@ v8::MicrotasksScope::kDoNotRunMicrotasks); v8::Local<v8::Object> global = v8_context()->Global(); if (web_frame_) { - ScriptInjectionCallback* wrapper_callback = nullptr; - if (!callback.is_null()) { - // ScriptInjectionCallback manages its own lifetime. - wrapper_callback = new ScriptInjectionCallback(std::move(callback)); - } web_frame_->RequestExecuteV8Function(v8_context(), function, global, argc, - argv, wrapper_callback); + argv, std::move(callback)); } else { + auto start_time = base::TimeTicks::Now(); v8::MaybeLocal<v8::Value> maybe_result = function->Call(v8_context(), global, argc, argv); v8::Local<v8::Value> result; if (!callback.is_null() && maybe_result.ToLocal(&result)) { std::vector<v8::Local<v8::Value>> results(1, result); - std::move(callback).Run(results); + std::move(callback).Run(results, start_time); } } }
diff --git a/extensions/renderer/script_context.h b/extensions/renderer/script_context.h index 0116c52..adbf770 100644 --- a/extensions/renderer/script_context.h +++ b/extensions/renderer/script_context.h
@@ -20,7 +20,7 @@ #include "extensions/common/script_constants.h" #include "extensions/renderer/module_system.h" #include "extensions/renderer/safe_builtins.h" -#include "extensions/renderer/script_injection_callback.h" +#include "third_party/blink/public/web/web_script_execution_callback.h" #include "url/gurl.h" #include "v8-exception.h" #include "v8/include/v8-context.h" @@ -129,7 +129,7 @@ void SafeCallFunction(const v8::Local<v8::Function>& function, int argc, v8::Local<v8::Value> argv[], - ScriptInjectionCallback::CompleteCallback callback); + blink::WebScriptExecutionCallback callback); // Returns the availability of the API |api_name|. Feature::Availability GetAvailability(const std::string& api_name);
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc index 19c8ff67..032ef69 100644 --- a/extensions/renderer/script_injection.cc +++ b/extensions/renderer/script_injection.cc
@@ -27,7 +27,6 @@ #include "extensions/renderer/dom_activity_logger.h" #include "extensions/renderer/extension_frame_helper.h" #include "extensions/renderer/extensions_renderer_client.h" -#include "extensions/renderer/script_injection_callback.h" #include "extensions/renderer/scripts_run_info.h" #include "extensions/renderer/trace_util.h" #include "services/metrics/public/cpp/ukm_source_id.h" @@ -36,6 +35,7 @@ #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_script_execution_callback.h" #include "third_party/blink/public/web/web_script_source.h" #include "url/gurl.h" @@ -93,38 +93,6 @@ return id; } -// This class manages its own lifetime. -class TimedScriptInjectionCallback : public ScriptInjectionCallback { - public: - TimedScriptInjectionCallback(base::WeakPtr<ScriptInjection> injection) - : ScriptInjectionCallback( - base::BindOnce(&TimedScriptInjectionCallback::OnCompleted, - base::Unretained(this))), - injection_(injection) {} - ~TimedScriptInjectionCallback() override {} - - void OnCompleted(const std::vector<v8::Local<v8::Value>>& result) { - if (injection_) { - base::TimeTicks timestamp(base::TimeTicks::Now()); - absl::optional<base::TimeDelta> elapsed; - // If the script will never execute (such as if the context is destroyed), - // willExecute() will not be called, but OnCompleted() will. Only log a - // time for execution if the script, in fact, executed. - if (!start_time_.is_null()) - elapsed = timestamp - start_time_; - injection_->OnJsInjectionCompleted(result, elapsed); - } - } - - void WillExecute() override { - start_time_ = base::TimeTicks::Now(); - } - - private: - base::WeakPtr<ScriptInjection> injection_; - base::TimeTicks start_time_; -}; - } // namespace // Watches for the deletion of a RenderFrame, after which is_valid will return @@ -328,9 +296,6 @@ run_location_, executing_scripts, num_injected_js_scripts); DCHECK(!sources.empty()); - std::unique_ptr<blink::WebScriptExecutionCallback> callback( - new TimedScriptInjectionCallback(weak_ptr_factory_.GetWeakPtr())); - base::ElapsedTimer exec_timer; // For content scripts executing during page load, we run them asynchronously @@ -364,16 +329,26 @@ } render_frame_->GetWebFrame()->RequestExecuteScript( world_id, sources, injector_->IsUserGesture(), execution_option, - blink::mojom::LoadEventBlockingOption::kBlock, callback.release(), + blink::mojom::LoadEventBlockingOption::kBlock, + base::BindOnce(&ScriptInjection::OnJsInjectionCompleted, + weak_ptr_factory_.GetWeakPtr()), blink::BackForwardCacheAware::kPossiblyDisallow, injector_->ShouldWaitForPromise()); } void ScriptInjection::OnJsInjectionCompleted( - const std::vector<v8::Local<v8::Value>>& results, - absl::optional<base::TimeDelta> elapsed) { + const blink::WebVector<v8::Local<v8::Value>>& results, + base::TimeTicks start_time) { DCHECK(!did_inject_js_); + base::TimeTicks timestamp(base::TimeTicks::Now()); + absl::optional<base::TimeDelta> elapsed; + // If the script will never execute (such as if the context is destroyed), + // `start_time` is null. Only log a time for execution if the script, in fact, + // executed. + if (!start_time.is_null()) + elapsed = timestamp - start_time; + if (injection_host_->id().type == mojom::HostID::HostType::kExtensions && elapsed) { UMA_HISTOGRAM_TIMES("Extensions.InjectedScriptExecutionTime", *elapsed);
diff --git a/extensions/renderer/script_injection.h b/extensions/renderer/script_injection.h index 543ae98..caf1f9c 100644 --- a/extensions/renderer/script_injection.h +++ b/extensions/renderer/script_injection.h
@@ -93,8 +93,9 @@ // Called when JS injection for the given frame has been completed or // cancelled. - void OnJsInjectionCompleted(const std::vector<v8::Local<v8::Value>>& results, - absl::optional<base::TimeDelta> elapsed); + void OnJsInjectionCompleted( + const blink::WebVector<v8::Local<v8::Value>>& results, + base::TimeTicks start_time); private: class FrameWatcher;
diff --git a/extensions/renderer/script_injection_callback.cc b/extensions/renderer/script_injection_callback.cc deleted file mode 100644 index ccaaa83..0000000 --- a/extensions/renderer/script_injection_callback.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "extensions/renderer/script_injection_callback.h" - -#include "third_party/blink/public/platform/web_vector.h" - -namespace extensions { - -ScriptInjectionCallback::ScriptInjectionCallback( - CompleteCallback injection_completed_callback) - : injection_completed_callback_(std::move(injection_completed_callback)) {} - -ScriptInjectionCallback::~ScriptInjectionCallback() { -} - -void ScriptInjectionCallback::Completed( - const blink::WebVector<v8::Local<v8::Value>>& result) { - std::vector<v8::Local<v8::Value>> stl_result(result.begin(), result.end()); - std::move(injection_completed_callback_).Run(stl_result); - delete this; -} - -} // namespace extensions
diff --git a/extensions/renderer/script_injection_callback.h b/extensions/renderer/script_injection_callback.h deleted file mode 100644 index f4d7653..0000000 --- a/extensions/renderer/script_injection_callback.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef EXTENSIONS_RENDERER_SCRIPT_INJECTION_CALLBACK_H_ -#define EXTENSIONS_RENDERER_SCRIPT_INJECTION_CALLBACK_H_ - -#include <vector> - -#include "base/callback.h" -#include "third_party/blink/public/web/web_script_execution_callback.h" -#include "v8/include/v8-forward.h" - -namespace extensions { - -// A wrapper around a callback to notify a script injection when injection -// completes. -// This class manages its own lifetime. -class ScriptInjectionCallback : public blink::WebScriptExecutionCallback { - public: - using CompleteCallback = - base::OnceCallback<void(const std::vector<v8::Local<v8::Value>>& result)>; - - explicit ScriptInjectionCallback( - CompleteCallback injection_completed_callback); - - ScriptInjectionCallback(const ScriptInjectionCallback&) = delete; - ScriptInjectionCallback& operator=(const ScriptInjectionCallback&) = delete; - - ~ScriptInjectionCallback() override; - - void Completed(const blink::WebVector<v8::Local<v8::Value>>& result) override; - - private: - CompleteCallback injection_completed_callback_; -}; - -} // namespace extensions - -#endif // EXTENSIONS_RENDERER_SCRIPT_INJECTION_CALLBACK_H_
diff --git a/infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Mac Builder/properties.json b/infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Mac Builder/properties.json index c64af130..a28b328 100644 --- a/infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Mac Builder/properties.json +++ b/infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Mac Builder/properties.json
@@ -12,5 +12,6 @@ ] }, "builder_group": "chromium.webrtc.fyi", - "recipe": "chromium" + "recipe": "chromium", + "xcode_build_version": "14a5294e" } \ No newline at end of file
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 7839f69..95dd159 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -82002,6 +82002,10 @@ ' "recipe": "chromium"' '}' execution_timeout_secs: 7200 + caches { + name: "xcode_ios_14a5294e" + path: "xcode_ios_14a5294e.app" + } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" experiments {
diff --git a/infra/config/subprojects/webrtc/webrtc.fyi.star b/infra/config/subprojects/webrtc/webrtc.fyi.star index 146dadf..fdec3d4 100644 --- a/infra/config/subprojects/webrtc/webrtc.fyi.star +++ b/infra/config/subprojects/webrtc/webrtc.fyi.star
@@ -91,6 +91,7 @@ name = "WebRTC Chromium FYI Mac Builder", goma_backend = goma.backend.RBE_PROD, os = os.MAC_ANY, + xcode = xcode.x14main, ) builder(
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index be91af6..9688624 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -766,10 +766,6 @@ kInterestFeedV2ClickAndViewActionsConditionalUploadDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(feed::kInterestFeedV2ClicksAndViewsConditionalUpload)}, - {"incognito-brand-consistency-for-ios", - flag_descriptions::kIncognitoBrandConsistencyForIOSName, - flag_descriptions::kIncognitoBrandConsistencyForIOSDescription, - flags_ui::kOsIos, FEATURE_VALUE_TYPE(kIncognitoBrandConsistencyForIOS)}, {"incognito-ntp-revamp", flag_descriptions::kIncognitoNtpRevampName, flag_descriptions::kIncognitoNtpRevampDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kIncognitoNtpRevamp)},
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 274852f5..431b3ba1 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -374,12 +374,6 @@ const char kHttpsOnlyModeName[] = "HTTPS-Only Mode Setting"; const char kHttpsOnlyModeDescription[] = "Enables the HTTPS-Only Mode setting"; -const char kIncognitoBrandConsistencyForIOSName[] = - "Enable Incognito brand consistency in iOS."; -const char kIncognitoBrandConsistencyForIOSDescription[] = - "When enabled, keeps Incognito UI consistent regardless of any selected " - "theme."; - const char kIncognitoNtpRevampName[] = "Revamped Incognito New Tab Page"; const char kIncognitoNtpRevampDescription[] = "When enabled, Incognito new tab page will have an updated UI.";
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index ef2995b4..bdb4dcc3 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -335,11 +335,6 @@ extern const char kHttpsOnlyModeName[]; extern const char kHttpsOnlyModeDescription[]; -// Title and description for the flag to enable dark mode colors while in -// Incognito mode. -extern const char kIncognitoBrandConsistencyForIOSName[]; -extern const char kIncognitoBrandConsistencyForIOSDescription[]; - // Title and description for the flag to enable revamped Incognito NTP page. extern const char kIncognitoNtpRevampName[]; extern const char kIncognitoNtpRevampDescription[];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm index dd15a5cb..788f6b3 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm
@@ -283,13 +283,12 @@ } - (void)showActivityIndicator { - [self.activityIndicator startAnimating]; [self.activityIndicator setHidden:NO]; + [self.activityIndicator startAnimating]; [self.iconView setHidden:YES]; } - (void)hideActivityIndicator { - [self.activityIndicator stopAnimating]; [self.activityIndicator setHidden:YES]; [self.iconView setHidden:NO]; }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm index a3831b0f..7d4f9f3 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -355,16 +355,14 @@ // Tests entering and leaving the tab grid. - (void)testEnteringAndLeavingTabGrid { - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()] performAction:grey_tap()]; } // Tests that tapping on the first cell shows that tab. - (void)testTappingOnFirstCell { - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)] performAction:grey_tap()]; [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] @@ -373,8 +371,7 @@ // Tests that closing the cell shows no tabs, and displays the empty state. - (void)testClosingFirstCell { - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [[EarlGrey selectElementWithMatcher:chrome_test_util:: TabGridCloseButtonForCellAtIndex(0)] performAction:grey_tap()]; @@ -389,12 +386,7 @@ // the empty state. Then tests tapping Undo shows Close All button again. // Validates this case when Tab Grid Bulk Actions feature is enabled. - (void)testCloseAllAndUndoCloseAll { - // TODO(crbug.com/1350734): Re-enable when flake fixed. - EARL_GREY_TEST_DISABLED( - @"Test consistently failing on iOS16 iPhone 8 and flaky on others.") - - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; // Close all tabs [[EarlGrey selectElementWithMatcher:VisibleTabGridEditButton()] @@ -433,8 +425,7 @@ // then creating a new tab, then coming back to the tab grid. // Validates this case when Tab Grid Bulk Actions feature is enabled. - (void)testUndoCloseAllNotAvailableAfterNewTabCreation { - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [[EarlGrey selectElementWithMatcher:VisibleTabGridEditButton()] performAction:grey_tap()]; @@ -448,8 +439,10 @@ // Create a new tab then come back to tab grid. [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridNewTabButton()] performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + + [ChromeEarlGrey waitForSufficientlyVisibleElementWithMatcher: + chrome_test_util::ShowTabsButton()]; + [ChromeEarlGreyUI openTabGrid]; // Undo is no longer available. [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridUndoCloseAllButton()] @@ -463,8 +456,7 @@ // Load history [self loadTestURLs]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; // Switch over to Recent Tabs. [[EarlGrey selectElementWithMatcher:TabGridOtherDevicesPanelButton()] @@ -533,8 +525,7 @@ [ChromeEarlGrey loadURL:_URL1]; [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [self longPressTabWithTitle:[NSString stringWithUTF8String:kTitle1]]; @@ -548,8 +539,7 @@ [ChromeEarlGrey loadURL:_URL1]; [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [self longPressTabWithTitle:[NSString stringWithUTF8String:kTitle1]]; @@ -562,8 +552,7 @@ [ChromeEarlGrey loadURL:_URL1]; [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [self longPressTabWithTitle:[NSString stringWithUTF8String:kTitle1]]; @@ -594,8 +583,7 @@ [ChromeEarlGrey loadURL:_URL1]; [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [self longPressTabWithTitle:[NSString stringWithUTF8String:kTitle1]]; [[EarlGrey selectElementWithMatcher:AddToBookmarksButton()] @@ -614,8 +602,7 @@ [ChromeEarlGrey loadURL:_URL1]; [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [self longPressTabWithTitle:[NSString stringWithUTF8String:kTitle1]]; @@ -636,8 +623,7 @@ [ChromeEarlGrey loadURL:_URL1]; [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [self longPressTabWithTitle:[NSString stringWithUTF8String:kTitle1]]; @@ -684,8 +670,7 @@ [ChromeEarlGrey waitForMainTabCount:2 inWindowWithNumber:0]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; GREYWaitForAppToIdle(@"App failed to idle"); @@ -735,8 +720,7 @@ [ChromeEarlGrey waitForIncognitoTabCount:2 inWindowWithNumber:0]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; GREYWaitForAppToIdle(@"App failed to idle"); @@ -801,12 +785,10 @@ // Open tab grid in both window. [EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; GREYWaitForAppToIdle(@"App failed to idle"); @@ -873,12 +855,10 @@ // Open tab grid in both window. [EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; GREYWaitForAppToIdle(@"App failed to idle"); @@ -952,8 +932,7 @@ // Open tab grid in first window. [EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; GREYWaitForAppToIdle(@"App failed to idle"); @@ -1012,8 +991,7 @@ // Open incognito tab grid in first window. [EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [[EarlGrey selectElementWithMatcher:chrome_test_util:: TabGridIncognitoTabsPanelButton()] performAction:grey_tap()]; @@ -1076,8 +1054,7 @@ // Open incognito tab grid in first window. [EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; GREYWaitForAppToIdle(@"App failed to idle"); @@ -1117,8 +1094,7 @@ [ChromeEarlGrey loadURL:_URL1]; [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [[EarlGrey selectElementWithMatcher:VisibleTabGridEditButton()] performAction:grey_tap()]; @@ -1172,8 +1148,7 @@ [ChromeEarlGrey loadURL:_URL3]; [ChromeEarlGrey waitForWebStateContainingText:kResponse3]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [[EarlGrey selectElementWithMatcher:VisibleTabGridEditButton()] performAction:grey_tap()]; @@ -1219,8 +1194,7 @@ [ChromeEarlGrey loadURL:_URL3]; [ChromeEarlGrey waitForWebStateContainingText:kResponse3]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [[EarlGrey selectElementWithMatcher:VisibleTabGridEditButton()] performAction:grey_tap()]; @@ -1277,8 +1251,7 @@ [ChromeEarlGrey loadURL:_URL3]; [ChromeEarlGrey waitForWebStateContainingText:kResponse3]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [[EarlGrey selectElementWithMatcher:VisibleTabGridEditButton()] performAction:grey_tap()]; @@ -1332,8 +1305,7 @@ [ChromeEarlGrey loadURL:_URL3]; [ChromeEarlGrey waitForWebStateContainingText:kResponse3]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [[EarlGrey selectElementWithMatcher:VisibleTabGridEditButton()] performAction:grey_tap()]; @@ -1377,8 +1349,7 @@ [ChromeEarlGrey loadURL:_URL3]; [ChromeEarlGrey waitForWebStateContainingText:kResponse3]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGreyUI openTabGrid]; [[EarlGrey selectElementWithMatcher:VisibleTabGridEditButton()] performAction:grey_tap()]; @@ -2483,8 +2454,9 @@ tabIndex)] performAction:grey_tap()]; [ChromeEarlGrey waitForWebStateContainingText:text inWindowWithNumber:windowNumber]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] - performAction:grey_tap()]; + [ChromeEarlGrey waitForSufficientlyVisibleElementWithMatcher: + chrome_test_util::ShowTabsButton()]; + [ChromeEarlGreyUI openTabGrid]; } - (void)waitForSnackBarMessage:(int)messageIdentifier
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc index ddbec789..73543d0 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.cc +++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -24,9 +24,6 @@ const base::Feature kModernTabStrip{"ModernTabStrip", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kIncognitoBrandConsistencyForIOS{ - "IncognitoBrandConsistencyForIOS", base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kIncognitoNtpRevamp{"IncognitoNtpRevamp", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/ui_feature_flags.h b/ios/chrome/browser/ui/ui_feature_flags.h index c64847b0..a55461b 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.h +++ b/ios/chrome/browser/ui/ui_feature_flags.h
@@ -31,9 +31,6 @@ // finished. Flag to modernize the tabstrip without disturbing the existing one. extern const base::Feature kModernTabStrip; -// Enables the usage of dark mode color while in Incognito mode. -extern const base::Feature kIncognitoBrandConsistencyForIOS; - // Feature flag to enable revamped Incognito NTP page. extern const base::Feature kIncognitoNtpRevamp;
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index e6281a52..20aaceb5 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -674f986aeb5f3167bda38521ab4b5b85e9126f8a \ No newline at end of file +8b02bcc56401152fcd75b1fdeb34e013cf8de563 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index 129c038..8ef5cc00 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -16e12b734378f80306ac5d0a34911308e67b166d \ No newline at end of file +9b7a4f94836740082ad0f7421ef4363ae9062aa9 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index c57c1303..73e7fde 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -801677c8222c456108336dee7e99725aeb462fcb \ No newline at end of file +2538519dfe0686bd3e0b6057aa16fabc872afa06 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index adc71a7..b4f3045 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -8d10c36bcd057470fb3081af0be31d629992ee73 \ No newline at end of file +3143c9b105a5658bf0bc23fae63dfa7c757019f6 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 index fb2de97..8bc5b0d 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -226f3c180a41af2f27835c7580e7e28385500be7 \ No newline at end of file +158d9c8b2b3e1104c52049156bc51a95d1045c5d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 index a0aabfe..261f4d5 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -f6de4eac18c171a12d3a43037802adfc9a7bd4fa \ No newline at end of file +63b8105abaa6a7c3d2d1eb8b07f431a4a2ad393a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index 955d2eb..5b4b60bd 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -1562f88ea478a04891f0b3578524c44ef7361b6c \ No newline at end of file +7e6bddd56c4570b7681b84e71085d1a02a554372 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index 0f749e99..aa8b712 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -4ddc2ee0f3723982956f2f017c866727cb837da7 \ No newline at end of file +b76508965342233f99aac9a895f8b513afd11af2 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index 3ad1986e..5df28d8 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -21671e748669e30a3bed4365a259903e8cc09cab \ No newline at end of file +0f1770187795d1abf5cfb183d987098b7127edcf \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index 7cde37e..3d5d161 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -b599268754090bd41d0e1fa9064acb26d9dcf962 \ No newline at end of file +7a67d96b2d4fbd043b3a575f0292e4aca5c96ee2 \ No newline at end of file
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc index 88bf5e2..02664f1 100644 --- a/services/network/cors/cors_url_loader.cc +++ b/services/network/cors/cors_url_loader.cc
@@ -495,7 +495,7 @@ request_.is_revalidating && response_head->headers && response_head->headers->response_code() == 304; if (fetch_cors_flag_ && !is_304_for_revalidation) { - const auto error_status = CheckAccessAndReportMetrics( + const auto result = CheckAccessAndReportMetrics( request_.url, GetHeaderString(*response_head, header_names::kAccessControlAllowOrigin), @@ -503,8 +503,8 @@ header_names::kAccessControlAllowCredentials), request_.credentials_mode, tainted_ ? url::Origin() : *request_.request_initiator); - if (error_status) { - HandleComplete(URLLoaderCompletionStatus(*error_status)); + if (!result.has_value()) { + HandleComplete(URLLoaderCompletionStatus(result.error())); return; } } @@ -539,7 +539,7 @@ // If `CORS flag` is set and a CORS check for `request` and `response` returns // failure, then return a network error. if (fetch_cors_flag_ && IsCorsEnabledRequestMode(request_.mode)) { - const auto error_status = CheckAccessAndReportMetrics( + const auto result = CheckAccessAndReportMetrics( request_.url, GetHeaderString(*response_head, header_names::kAccessControlAllowOrigin), @@ -547,8 +547,8 @@ header_names::kAccessControlAllowCredentials), request_.credentials_mode, tainted_ ? url::Origin() : *request_.request_initiator); - if (error_status) { - HandleComplete(URLLoaderCompletionStatus(*error_status)); + if (!result.has_value()) { + HandleComplete(URLLoaderCompletionStatus(result.error())); return; } }
diff --git a/services/network/cors/preflight_controller.cc b/services/network/cors/preflight_controller.cc index 2d680ac..19f8d727 100644 --- a/services/network/cors/preflight_controller.cc +++ b/services/network/cors/preflight_controller.cc
@@ -214,7 +214,7 @@ // According to the note at https://fetch.spec.whatwg.org/#cors-preflight-fetch // step 6, even for a preflight check, `credentials_mode` should be checked on // the actual request rather than preflight one. -absl::optional<CorsErrorStatus> CheckPreflightAccess( +base::expected<void, CorsErrorStatus> CheckPreflightAccess( const GURL& response_url, const int response_status_code, const absl::optional<std::string>& allow_origin_header, @@ -222,12 +222,12 @@ mojom::CredentialsMode actual_credentials_mode, const url::Origin& origin) { // Step 7 of https://fetch.spec.whatwg.org/#cors-preflight-fetch - auto error_status = + auto cors_result = CheckAccess(response_url, allow_origin_header, allow_credentials_header, actual_credentials_mode, origin); const bool has_ok_status = IsOkStatus(response_status_code); - AccessCheckResult result = (error_status || !has_ok_status) + AccessCheckResult result = (!cors_result.has_value() || !has_ok_status) ? AccessCheckResult::kNotPermittedInPreflight : AccessCheckResult::kPermittedInPreflight; UMA_HISTOGRAM_ENUMERATION("Net.Cors.AccessCheckResult", result); @@ -237,30 +237,30 @@ } // Prefer using a preflight specific error code. - if (error_status) { - switch (error_status->cors_error) { + if (!cors_result.has_value()) { + switch (cors_result.error().cors_error) { case mojom::CorsError::kWildcardOriginNotAllowed: - error_status->cors_error = + cors_result.error().cors_error = mojom::CorsError::kPreflightWildcardOriginNotAllowed; break; case mojom::CorsError::kMissingAllowOriginHeader: - error_status->cors_error = + cors_result.error().cors_error = mojom::CorsError::kPreflightMissingAllowOriginHeader; break; case mojom::CorsError::kMultipleAllowOriginValues: - error_status->cors_error = + cors_result.error().cors_error = mojom::CorsError::kPreflightMultipleAllowOriginValues; break; case mojom::CorsError::kInvalidAllowOriginValue: - error_status->cors_error = + cors_result.error().cors_error = mojom::CorsError::kPreflightInvalidAllowOriginValue; break; case mojom::CorsError::kAllowOriginMismatch: - error_status->cors_error = + cors_result.error().cors_error = mojom::CorsError::kPreflightAllowOriginMismatch; break; case mojom::CorsError::kInvalidAllowCredentials: - error_status->cors_error = + cors_result.error().cors_error = mojom::CorsError::kPreflightInvalidAllowCredentials; break; default: @@ -268,13 +268,13 @@ break; } } else if (!has_ok_status) { - error_status = absl::make_optional<CorsErrorStatus>( + cors_result = base::unexpected<CorsErrorStatus>( mojom::CorsError::kPreflightInvalidStatus); } else { - return absl::nullopt; + base::expected<void, CorsErrorStatus>(); } - return error_status; + return cors_result; } // Checks errors for the "Access-Control-Allow-Private-Network" header. @@ -321,15 +321,18 @@ absl::optional<CorsErrorStatus>* detected_error_status) { DCHECK(detected_error_status); - *detected_error_status = CheckPreflightAccess( + auto check_result = CheckPreflightAccess( final_url, head.headers ? head.headers->response_code() : 0, GetHeaderString(head.headers, header_names::kAccessControlAllowOrigin), GetHeaderString(head.headers, header_names::kAccessControlAllowCredentials), original_request.credentials_mode, tainted ? url::Origin() : *original_request.request_initiator); - if (*detected_error_status) + if (!check_result.has_value()) { + *detected_error_status = std::move(check_result.error()); return nullptr; + } + *detected_error_status = absl::nullopt; absl::optional<CorsErrorStatus> status = CheckAllowPrivateNetworkHeader(head, original_request); @@ -607,7 +610,7 @@ } // static -absl::optional<CorsErrorStatus> +base::expected<void, CorsErrorStatus> PreflightController::CheckPreflightAccessForTesting( const GURL& response_url, const int response_status_code,
diff --git a/services/network/cors/preflight_controller.h b/services/network/cors/preflight_controller.h index 7b247ac..0aab87c 100644 --- a/services/network/cors/preflight_controller.h +++ b/services/network/cors/preflight_controller.h
@@ -11,6 +11,7 @@ #include "base/component_export.h" #include "base/containers/unique_ptr_adapters.h" #include "base/memory/raw_ptr.h" +#include "base/types/expected.h" #include "base/types/strong_alias.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "services/network/cors/preflight_cache.h" @@ -84,7 +85,7 @@ absl::optional<CorsErrorStatus>* detected_error_status); // Checks CORS aceess on the CORS-preflight response parameters for testing. - static absl::optional<CorsErrorStatus> CheckPreflightAccessForTesting( + static base::expected<void, CorsErrorStatus> CheckPreflightAccessForTesting( const GURL& response_url, const int response_status_code, const absl::optional<std::string>& allow_origin_header,
diff --git a/services/network/cors/preflight_controller_unittest.cc b/services/network/cors/preflight_controller_unittest.cc index e091450..be61182 100644 --- a/services/network/cors/preflight_controller_unittest.cc +++ b/services/network/cors/preflight_controller_unittest.cc
@@ -977,33 +977,34 @@ const std::string allow_all_header("*"); // Status 200-299 should pass. - EXPECT_FALSE(PreflightController::CheckPreflightAccessForTesting( - response_url, 200, allow_all_header, - /*allow_credentials_header=*/absl::nullopt, - network::mojom::CredentialsMode::kOmit, origin)); - EXPECT_FALSE(PreflightController::CheckPreflightAccessForTesting( - response_url, 299, allow_all_header, - /*allow_credentials_header=*/absl::nullopt, - network::mojom::CredentialsMode::kOmit, origin)); + EXPECT_TRUE(PreflightController::CheckPreflightAccessForTesting( + response_url, 200, allow_all_header, + /*allow_credentials_header=*/absl::nullopt, + network::mojom::CredentialsMode::kOmit, origin) + .has_value()); + EXPECT_TRUE(PreflightController::CheckPreflightAccessForTesting( + response_url, 299, allow_all_header, + /*allow_credentials_header=*/absl::nullopt, + network::mojom::CredentialsMode::kOmit, origin) + .has_value()); // Status 300 should fail. - absl::optional<CorsErrorStatus> invalid_status_error = - PreflightController::CheckPreflightAccessForTesting( - response_url, 300, allow_all_header, - /*allow_credentials_header=*/absl::nullopt, - network::mojom::CredentialsMode::kOmit, origin); - ASSERT_TRUE(invalid_status_error); + const auto result300 = PreflightController::CheckPreflightAccessForTesting( + response_url, 300, allow_all_header, + /*allow_credentials_header=*/absl::nullopt, + network::mojom::CredentialsMode::kOmit, origin); + ASSERT_FALSE(result300.has_value()); EXPECT_EQ(mojom::CorsError::kPreflightInvalidStatus, - invalid_status_error->cors_error); + result300.error().cors_error); // Status 0 should fail too. - invalid_status_error = PreflightController::CheckPreflightAccessForTesting( + const auto result0 = PreflightController::CheckPreflightAccessForTesting( response_url, 0, allow_all_header, /*allow_credentials_header=*/absl::nullopt, network::mojom::CredentialsMode::kOmit, origin); - ASSERT_TRUE(invalid_status_error); + ASSERT_FALSE(result0.has_value()); EXPECT_EQ(mojom::CorsError::kPreflightInvalidStatus, - invalid_status_error->cors_error); + result0.error().cors_error); } } // namespace
diff --git a/services/network/http_server_properties_pref_delegate.cc b/services/network/http_server_properties_pref_delegate.cc index 1bac16b..ae31a4ba 100644 --- a/services/network/http_server_properties_pref_delegate.cc +++ b/services/network/http_server_properties_pref_delegate.cc
@@ -29,7 +29,7 @@ const base::Value* HttpServerPropertiesPrefDelegate::GetServerProperties() const { - return pref_service_->Get(kPrefPath); + return &pref_service_->GetValue(kPrefPath); } void HttpServerPropertiesPrefDelegate::SetServerProperties(
diff --git a/services/network/network_qualities_pref_delegate.cc b/services/network/network_qualities_pref_delegate.cc index 1a490c1..41f4163 100644 --- a/services/network/network_qualities_pref_delegate.cc +++ b/services/network/network_qualities_pref_delegate.cc
@@ -46,7 +46,7 @@ base::Value::Dict GetDictionaryValue() override { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); UMA_HISTOGRAM_EXACT_LINEAR("NQE.Prefs.ReadCount", 1, 2); - return pref_service_->GetDictionary(path_)->GetDict().Clone(); + return pref_service_->GetValueDict(path_).Clone(); } private:
diff --git a/services/network/public/cpp/cors/cors.cc b/services/network/public/cpp/cors/cors.cc index e349353..0174477 100644 --- a/services/network/public/cpp/cors/cors.cc +++ b/services/network/public/cpp/cors/cors.cc
@@ -145,7 +145,7 @@ } // namespace header_names // See https://fetch.spec.whatwg.org/#cors-check. -absl::optional<CorsErrorStatus> CheckAccess( +base::expected<void, CorsErrorStatus> CheckAccess( const GURL& response_url, const absl::optional<std::string>& allow_origin_header, const absl::optional<std::string>& allow_credentials_header, @@ -156,7 +156,7 @@ // to be sent, even with Access-Control-Allow-Credentials set to true. // See https://fetch.spec.whatwg.org/#cors-protocol-and-credentials. if (credentials_mode != mojom::CredentialsMode::kInclude) - return absl::nullopt; + return base::expected<void, CorsErrorStatus>(); // Since the credential is a concept for network schemes, we perform the // wildcard check only for HTTP and HTTPS. This is a quick hack to allow @@ -164,10 +164,13 @@ // TODO(https://crbug.com/736308): Once the callers exist only in the // browser process or network service, this check won't be needed any more // because it is always for network requests there. - if (response_url.SchemeIsHTTPOrHTTPS()) - return CorsErrorStatus(mojom::CorsError::kWildcardOriginNotAllowed); + if (response_url.SchemeIsHTTPOrHTTPS()) { + return base::unexpected<CorsErrorStatus>( + CorsErrorStatus(mojom::CorsError::kWildcardOriginNotAllowed)); + } } else if (!allow_origin_header) { - return CorsErrorStatus(mojom::CorsError::kMissingAllowOriginHeader); + return base::unexpected<CorsErrorStatus>( + CorsErrorStatus(mojom::CorsError::kMissingAllowOriginHeader)); } else if (*allow_origin_header != origin.Serialize()) { // We do not use url::Origin::IsSameOriginWith() here for two reasons below. // 1. Allow "null" to match here. The latest spec does not have a clear @@ -186,26 +189,26 @@ // Does not allow to have multiple origins in the allow origin header. // See https://fetch.spec.whatwg.org/#http-access-control-allow-origin. if (allow_origin_header->find_first_of(" ,") != std::string::npos) { - return CorsErrorStatus(mojom::CorsError::kMultipleAllowOriginValues, - *allow_origin_header); + return base::unexpected<CorsErrorStatus>(CorsErrorStatus( + mojom::CorsError::kMultipleAllowOriginValues, *allow_origin_header)); } // Check valid "null" first since GURL assumes it as invalid. if (*allow_origin_header == "null") { - return CorsErrorStatus(mojom::CorsError::kAllowOriginMismatch, - *allow_origin_header); + return base::unexpected<CorsErrorStatus>(CorsErrorStatus( + mojom::CorsError::kAllowOriginMismatch, *allow_origin_header)); } // As commented above, this validation is not strict as an origin // validation, but should be ok for providing error details to developers. GURL header_origin(*allow_origin_header); if (!header_origin.is_valid()) { - return CorsErrorStatus(mojom::CorsError::kInvalidAllowOriginValue, - *allow_origin_header); + return base::unexpected<CorsErrorStatus>(CorsErrorStatus( + mojom::CorsError::kInvalidAllowOriginValue, *allow_origin_header)); } - return CorsErrorStatus(mojom::CorsError::kAllowOriginMismatch, - *allow_origin_header); + return base::unexpected<CorsErrorStatus>(CorsErrorStatus( + mojom::CorsError::kAllowOriginMismatch, *allow_origin_header)); } if (credentials_mode == mojom::CredentialsMode::kInclude) { @@ -213,31 +216,33 @@ // This check should be case sensitive. // See also https://fetch.spec.whatwg.org/#http-new-header-syntax. if (allow_credentials_header != kLowerCaseTrue) { - return CorsErrorStatus(mojom::CorsError::kInvalidAllowCredentials, - allow_credentials_header.value_or(std::string())); + return base::unexpected<CorsErrorStatus>( + CorsErrorStatus(mojom::CorsError::kInvalidAllowCredentials, + allow_credentials_header.value_or(std::string()))); } } - return absl::nullopt; + return base::expected<void, CorsErrorStatus>(); } -absl::optional<CorsErrorStatus> CheckAccessAndReportMetrics( +base::expected<void, CorsErrorStatus> CheckAccessAndReportMetrics( const GURL& response_url, const absl::optional<std::string>& allow_origin_header, const absl::optional<std::string>& allow_credentials_header, mojom::CredentialsMode credentials_mode, const url::Origin& origin) { - absl::optional<CorsErrorStatus> error_status = + auto check_result = CheckAccess(response_url, allow_origin_header, allow_credentials_header, credentials_mode, origin); - cors::AccessCheckResult result = error_status - ? cors::AccessCheckResult::kNotPermitted - : cors::AccessCheckResult::kPermitted; + cors::AccessCheckResult result = check_result.has_value() + ? cors::AccessCheckResult::kPermitted + : cors::AccessCheckResult::kNotPermitted; + base::UmaHistogramEnumeration("Net.Cors.AccessCheckResult", result); if (!IsOriginPotentiallyTrustworthy(origin)) { base::UmaHistogramEnumeration( "Net.Cors.AccessCheckResult.NotSecureRequestor", result); } - return error_status; + return check_result; } bool ShouldCheckCors(const GURL& request_url,
diff --git a/services/network/public/cpp/cors/cors.h b/services/network/public/cpp/cors/cors.h index ce1b4a95..b2b1a4f 100644 --- a/services/network/public/cpp/cors/cors.h +++ b/services/network/public/cpp/cors/cors.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/component_export.h" +#include "base/types/expected.h" #include "net/http/http_request_headers.h" #include "services/network/public/cpp/cors/cors_error_status.h" #include "services/network/public/mojom/cors.mojom-shared.h" @@ -68,7 +69,7 @@ // Performs a CORS access check on the response parameters. // This implements https://fetch.spec.whatwg.org/#concept-cors-check COMPONENT_EXPORT(NETWORK_CPP) -absl::optional<CorsErrorStatus> CheckAccess( +base::expected<void, CorsErrorStatus> CheckAccess( const GURL& response_url, const absl::optional<std::string>& allow_origin_header, const absl::optional<std::string>& allow_credentials_header, @@ -77,7 +78,7 @@ // Performs a CORS access check and reports result and error. COMPONENT_EXPORT(NETWORK_CPP) -absl::optional<CorsErrorStatus> CheckAccessAndReportMetrics( +base::expected<void, CorsErrorStatus> CheckAccessAndReportMetrics( const GURL& response_url, const absl::optional<std::string>& allow_origin_header, const absl::optional<std::string>& allow_credentials_header,
diff --git a/services/network/public/cpp/cors/cors_unittest.cc b/services/network/public/cpp/cors/cors_unittest.cc index 4a201c8b..4b03c3b8 100644 --- a/services/network/public/cpp/cors/cors_unittest.cc +++ b/services/network/public/cpp/cors/cors_unittest.cc
@@ -25,20 +25,21 @@ const std::string allow_all_header("*"); // Access-Control-Allow-Origin '*' works. - absl::optional<CorsErrorStatus> error1 = + const auto result = CheckAccess(response_url, allow_all_header /* allow_origin_header */, absl::nullopt /* allow_credentials_header */, network::mojom::CredentialsMode::kOmit, origin); - EXPECT_FALSE(error1); + EXPECT_TRUE(result.has_value()); // Access-Control-Allow-Origin '*' should not be allowed if credentials mode // is kInclude. - absl::optional<CorsErrorStatus> error2 = + const auto result2 = CheckAccess(response_url, allow_all_header /* allow_origin_header */, absl::nullopt /* allow_credentials_header */, network::mojom::CredentialsMode::kInclude, origin); - ASSERT_TRUE(error2); - EXPECT_EQ(mojom::CorsError::kWildcardOriginNotAllowed, error2->cors_error); + ASSERT_FALSE(result2.has_value()); + EXPECT_EQ(mojom::CorsError::kWildcardOriginNotAllowed, + result2.error().cors_error); } // Tests if CheckAccess detects kMissingAllowOriginHeader error correctly. @@ -47,12 +48,13 @@ const url::Origin origin = url::Origin::Create(GURL("http://google.com")); // Access-Control-Allow-Origin is missed. - absl::optional<CorsErrorStatus> error = + const auto result = CheckAccess(response_url, absl::nullopt /* allow_origin_header */, absl::nullopt /* allow_credentials_header */, network::mojom::CredentialsMode::kOmit, origin); - ASSERT_TRUE(error); - EXPECT_EQ(mojom::CorsError::kMissingAllowOriginHeader, error->cors_error); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(mojom::CorsError::kMissingAllowOriginHeader, + result.error().cors_error); } // Tests if CheckAccess detects kMultipleAllowOriginValues error @@ -63,21 +65,23 @@ const std::string space_separated_multiple_origins( "http://example.com http://another.example.com"); - absl::optional<CorsErrorStatus> error1 = CheckAccess( + const auto result1 = CheckAccess( response_url, space_separated_multiple_origins /* allow_origin_header */, absl::nullopt /* allow_credentials_header */, network::mojom::CredentialsMode::kOmit, origin); - ASSERT_TRUE(error1); - EXPECT_EQ(mojom::CorsError::kMultipleAllowOriginValues, error1->cors_error); + ASSERT_FALSE(result1.has_value()); + EXPECT_EQ(mojom::CorsError::kMultipleAllowOriginValues, + result1.error().cors_error); const std::string comma_separated_multiple_origins( "http://example.com,http://another.example.com"); - absl::optional<CorsErrorStatus> error2 = CheckAccess( + const auto result2 = CheckAccess( response_url, comma_separated_multiple_origins /* allow_origin_header */, absl::nullopt /* allow_credentials_header */, network::mojom::CredentialsMode::kOmit, origin); - ASSERT_TRUE(error2); - EXPECT_EQ(mojom::CorsError::kMultipleAllowOriginValues, error2->cors_error); + ASSERT_FALSE(result2.has_value()); + EXPECT_EQ(mojom::CorsError::kMultipleAllowOriginValues, + result2.error().cors_error); } // Tests if CheckAccess detects kInvalidAllowOriginValue error correctly. @@ -85,13 +89,14 @@ const GURL response_url("http://example.com/data"); const url::Origin origin = url::Origin::Create(GURL("http://google.com")); - absl::optional<CorsErrorStatus> error = CheckAccess( + const auto result = CheckAccess( response_url, std::string("invalid.origin") /* allow_origin_header */, absl::nullopt /* allow_credentials_header */, network::mojom::CredentialsMode::kOmit, origin); - ASSERT_TRUE(error); - EXPECT_EQ(mojom::CorsError::kInvalidAllowOriginValue, error->cors_error); - EXPECT_EQ("invalid.origin", error->failed_parameter); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(mojom::CorsError::kInvalidAllowOriginValue, + result.error().cors_error); + EXPECT_EQ("invalid.origin", result.error().failed_parameter); } // Tests if CheckAccess detects kAllowOriginMismatch error correctly. @@ -99,31 +104,31 @@ const GURL response_url("http://example.com/data"); const url::Origin origin = url::Origin::Create(GURL("http://google.com")); - absl::optional<CorsErrorStatus> error1 = + const auto result1 = CheckAccess(response_url, origin.Serialize() /* allow_origin_header */, absl::nullopt /* allow_credentials_header */, network::mojom::CredentialsMode::kOmit, origin); - ASSERT_FALSE(error1); + ASSERT_TRUE(result1.has_value()); - absl::optional<CorsErrorStatus> error2 = CheckAccess( + const auto result2 = CheckAccess( response_url, std::string("http://not.google.com") /* allow_origin_header */, absl::nullopt /* allow_credentials_header */, network::mojom::CredentialsMode::kOmit, origin); - ASSERT_TRUE(error2); - EXPECT_EQ(mojom::CorsError::kAllowOriginMismatch, error2->cors_error); - EXPECT_EQ("http://not.google.com", error2->failed_parameter); + ASSERT_FALSE(result2.has_value()); + EXPECT_EQ(mojom::CorsError::kAllowOriginMismatch, result2.error().cors_error); + EXPECT_EQ("http://not.google.com", result2.error().failed_parameter); // Allow "null" value to match serialized unique origins. const std::string null_string("null"); const url::Origin null_origin; EXPECT_EQ(null_string, null_origin.Serialize()); - absl::optional<CorsErrorStatus> error3 = + const auto result3 = CheckAccess(response_url, null_string /* allow_origin_header */, absl::nullopt /* allow_credentials_header */, network::mojom::CredentialsMode::kOmit, null_origin); - EXPECT_FALSE(error3); + EXPECT_TRUE(result3.has_value()); } // Tests if CheckAccess detects kInvalidAllowCredentials error correctly. @@ -131,19 +136,20 @@ const GURL response_url("http://example.com/data"); const url::Origin origin = url::Origin::Create(GURL("http://google.com")); - absl::optional<CorsErrorStatus> error1 = + const auto result1 = CheckAccess(response_url, origin.Serialize() /* allow_origin_header */, std::string("true") /* allow_credentials_header */, network::mojom::CredentialsMode::kInclude, origin); - ASSERT_FALSE(error1); + ASSERT_TRUE(result1.has_value()); - absl::optional<CorsErrorStatus> error2 = + const auto restul2 = CheckAccess(response_url, origin.Serialize() /* allow_origin_header */, std::string("fuga") /* allow_credentials_header */, network::mojom::CredentialsMode::kInclude, origin); - ASSERT_TRUE(error2); - EXPECT_EQ(mojom::CorsError::kInvalidAllowCredentials, error2->cors_error); - EXPECT_EQ("fuga", error2->failed_parameter); + ASSERT_FALSE(restul2.has_value()); + EXPECT_EQ(mojom::CorsError::kInvalidAllowCredentials, + restul2.error().cors_error); + EXPECT_EQ("fuga", restul2.error().failed_parameter); } // Should match unexposed enum in cors.cc
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index a134574..ff17918f 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5689,38 +5689,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "isolate_profile_data": true, @@ -5753,21 +5721,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5234.0", + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -5780,7 +5748,39 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "isolate_profile_data": true, @@ -5856,37 +5856,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "lacros_chrome_browsertests", - "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "isolate_profile_data": true, @@ -5918,21 +5887,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5234.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -5944,7 +5913,38 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "lacros_chrome_browsertests", + "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "args": [ @@ -6002,37 +6002,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "lacros_chrome_browsertests_run_in_series", - "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "isolate_profile_data": true, @@ -6064,21 +6033,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5234.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -6090,7 +6059,38 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "lacros_chrome_browsertests_run_in_series", + "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "isolate_profile_data": true,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index db2f912b..5ee0266 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -99239,33 +99239,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "isolate_profile_data": true, @@ -99293,21 +99266,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5234.0", + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -99315,7 +99288,34 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "isolate_profile_data": true, @@ -99376,32 +99376,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "lacros_chrome_browsertests", - "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "isolate_profile_data": true, @@ -99428,28 +99402,54 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5234.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "lacros_chrome_browsertests", + "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "args": [ @@ -99497,32 +99497,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "lacros_chrome_browsertests_run_in_series", - "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "isolate_profile_data": true, @@ -99549,28 +99523,54 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5234.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "lacros_chrome_browsertests_run_in_series", + "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "isolate_profile_data": true, @@ -100844,38 +100844,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04", - "ssd": "0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "merge": { @@ -100908,20 +100876,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5234.0", + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -100935,7 +100903,39 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "merge": { @@ -101011,37 +101011,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04", - "ssd": "0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "lacros_chrome_browsertests", - "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "merge": { @@ -101073,20 +101042,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5234.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -101099,7 +101068,38 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "lacros_chrome_browsertests", + "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "args": [ @@ -101157,37 +101157,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04", - "ssd": "0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "lacros_chrome_browsertests_run_in_series", - "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "merge": { @@ -101219,20 +101188,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5234.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -101245,7 +101214,38 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "lacros_chrome_browsertests_run_in_series", + "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "merge": { @@ -102677,38 +102677,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04", - "ssd": "0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "merge": { @@ -102741,20 +102709,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5234.0", + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -102768,7 +102736,39 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "merge": { @@ -102844,37 +102844,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04", - "ssd": "0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "lacros_chrome_browsertests", - "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "merge": { @@ -102906,20 +102875,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5234.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -102932,7 +102901,38 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "lacros_chrome_browsertests", + "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "args": [ @@ -102990,37 +102990,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04", - "ssd": "0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "lacros_chrome_browsertests_run_in_series", - "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "merge": { @@ -103052,20 +103021,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5234.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -103078,7 +103047,38 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04", + "ssd": "0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "lacros_chrome_browsertests_run_in_series", + "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "merge": { @@ -103751,37 +103751,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "merge": { @@ -103813,20 +103782,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5234.0", + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -103839,7 +103808,38 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" } ] },
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index a94139d..94aa109c 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -20807,38 +20807,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "isolate_profile_data": true, @@ -20871,21 +20839,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5234.0", + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -20898,7 +20866,39 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "interactive_ui_tests", + "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "isolate_profile_data": true, @@ -20974,37 +20974,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "lacros_chrome_browsertests", - "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "isolate_profile_data": true, @@ -21036,21 +21005,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5234.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -21062,7 +21031,38 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "lacros_chrome_browsertests", + "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "args": [ @@ -21120,37 +21120,6 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome" - ], - "isolate_profile_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5187.0", - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v105.0.5187.0", - "revision": "version:105.0.5187.0" - } - ], - "dimension_sets": [ - { - "os": "Ubuntu-18.04" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "lacros_chrome_browsertests_run_in_series", - "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 105.0.5187.0" - }, - { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5195.24/test_ash_chrome" ], "isolate_profile_data": true, @@ -21182,21 +21151,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5234.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5226.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v106.0.5234.0", - "revision": "version:106.0.5234.0" + "location": "lacros_version_skew_tests_v106.0.5226.0", + "revision": "version:106.0.5226.0" } ], "dimension_sets": [ @@ -21208,7 +21177,38 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 106.0.5234.0" + "variant_id": "Lacros version skew testing ash 106.0.5226.0" + }, + { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5235.0", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", + "location": "lacros_version_skew_tests_v106.0.5235.0", + "revision": "version:106.0.5235.0" + } + ], + "dimension_sets": [ + { + "os": "Ubuntu-18.04" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "lacros_chrome_browsertests_run_in_series", + "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", + "variant_id": "Lacros version skew testing ash 106.0.5235.0" }, { "isolate_profile_data": true,
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 8743ae7f..26f4789 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -22,30 +22,30 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5234.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5235.0/test_ash_chrome', ], - 'identifier': 'Lacros version skew testing ash 106.0.5234.0', + 'identifier': 'Lacros version skew testing ash 106.0.5235.0', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v106.0.5234.0', - 'revision': 'version:106.0.5234.0', + 'location': 'lacros_version_skew_tests_v106.0.5235.0', + 'revision': 'version:106.0.5235.0', }, ], }, }, 'LACROS_VERSION_SKEW_DEV': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5187.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5226.0/test_ash_chrome', ], - 'identifier': 'Lacros version skew testing ash 105.0.5187.0', + 'identifier': 'Lacros version skew testing ash 106.0.5226.0', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v105.0.5187.0', - 'revision': 'version:105.0.5187.0', + 'location': 'lacros_version_skew_tests_v106.0.5226.0', + 'revision': 'version:106.0.5226.0', }, ], },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index c1ccd562..6bd8171 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -7902,6 +7902,31 @@ ] } ], + "ReduceUserAgentPlatformOsCpu": [ + { + "platforms": [ + "android", + "android_weblayer", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "all_except_legacy_windows_platform": "true", + "legacy_windows_platform": "true" + }, + "enable_features": [ + "ReduceUserAgentPlatformOsCpu" + ] + } + ] + } + ], "RelatedSearches": [ { "platforms": [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 3d76b57..86ec16c 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -1510,6 +1510,9 @@ DelayAsyncScriptDelayType::kFinishedParsing, &delay_async_script_execution_delay_types}; +const base::FeatureParam<bool> kDelayAsyncScriptExecutionCrossSiteOnlyParam{ + &kDelayAsyncScriptExecution, "cross_site_only", false}; + const base::Feature kForceDeferScriptIntervention{ "ForceDeferScriptIntervention", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 7a3c9c1..91e4bcd 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -750,6 +750,8 @@ }; BLINK_COMMON_EXPORT extern const base::FeatureParam<DelayAsyncScriptDelayType> kDelayAsyncScriptExecutionDelayParam; +BLINK_COMMON_EXPORT extern const base::FeatureParam<bool> + kDelayAsyncScriptExecutionCrossSiteOnlyParam; // If enabled, parser-blocking scripts are force-deferred. // https://crbug.com/1339112
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h index fb11ec3..ba043cf6 100644 --- a/third_party/blink/public/web/web_local_frame.h +++ b/third_party/blink/public/web/web_local_frame.h
@@ -49,6 +49,7 @@ #include "third_party/blink/public/web/web_frame.h" #include "third_party/blink/public/web/web_frame_load_type.h" #include "third_party/blink/public/web/web_history_item.h" +#include "third_party/blink/public/web/web_script_execution_callback.h" #include "ui/accessibility/ax_tree_id.h" #include "ui/base/ime/ime_text_span.h" #include "ui/gfx/range/range.h" @@ -89,7 +90,6 @@ class WebPlugin; class WebPrintClient; class WebRange; -class WebScriptExecutionCallback; class WebSpellCheckPanelHostClient; class WebString; class WebTextCheckClient; @@ -413,7 +413,7 @@ v8::Local<v8::Value> receiver, int argc, v8::Local<v8::Value> argv[], - WebScriptExecutionCallback*) = 0; + WebScriptExecutionCallback) = 0; // Executes the script in the main world of the page. // Use kMainDOMWorldId to execute in the main world; otherwise, @@ -423,7 +423,7 @@ mojom::UserActivationOption, mojom::EvaluationTiming, mojom::LoadEventBlockingOption, - WebScriptExecutionCallback*, + WebScriptExecutionCallback, BackForwardCacheAware, mojom::PromiseResultOption) = 0;
diff --git a/third_party/blink/public/web/web_script_execution_callback.h b/third_party/blink/public/web/web_script_execution_callback.h index ab81474..c37e7ef 100644 --- a/third_party/blink/public/web/web_script_execution_callback.h +++ b/third_party/blink/public/web/web_script_execution_callback.h
@@ -5,28 +5,26 @@ #ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SCRIPT_EXECUTION_CALLBACK_H_ #define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SCRIPT_EXECUTION_CALLBACK_H_ +#include "base/callback.h" + namespace v8 { class Value; template <class T> class Local; } +namespace base { +class TimeTicks; +} + namespace blink { template <typename T> class WebVector; -class WebScriptExecutionCallback { - public: - virtual ~WebScriptExecutionCallback() = default; - - // Method to be invoked when the asynchronous script is about to execute. - virtual void WillExecute() {} - - // Method to be invoked when the asynchronous script execution is complete. - // After function call all objects in vector will be collected - virtual void Completed(const WebVector<v8::Local<v8::Value>>&) {} -}; +using WebScriptExecutionCallback = + base::OnceCallback<void(const WebVector<v8::Local<v8::Value>>&, + base::TimeTicks)>; } // namespace blink
diff --git a/third_party/blink/renderer/bindings/generated_in_extensions_chromeos.gni b/third_party/blink/renderer/bindings/generated_in_extensions_chromeos.gni index ea6a801..3b4d0b6 100644 --- a/third_party/blink/renderer/bindings/generated_in_extensions_chromeos.gni +++ b/third_party/blink/renderer/bindings/generated_in_extensions_chromeos.gni
@@ -7,6 +7,8 @@ generated_dictionary_sources_in_extensions_chromeos = [ "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_accelerator_event_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_accelerator_event_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_event_init.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_event_init.h", ] generated_enumeration_sources_in_extensions_chromeos = [ @@ -27,6 +29,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_screen.h", "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window.cc", "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window.h", + "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_event.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_event.h", "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_management.cc", "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_management.h", ]
diff --git a/third_party/blink/renderer/bindings/idl_in_extensions_chromeos.gni b/third_party/blink/renderer/bindings/idl_in_extensions_chromeos.gni index b8394d4..58be9e0 100644 --- a/third_party/blink/renderer/bindings/idl_in_extensions_chromeos.gni +++ b/third_party/blink/renderer/bindings/idl_in_extensions_chromeos.gni
@@ -14,6 +14,8 @@ "//third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event.idl", "//third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_accelerator_event_init.idl", "//third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_screen.idl", + "//third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event.idl", + "//third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event_init.idl", "//third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window.idl", "//third_party/blink/renderer/extensions/chromeos/system_extensions/hid/cros_hid.idl", ],
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index 6d15fc1..ca818d3 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -2586,7 +2586,7 @@ } DocumentLoader* loader = local_frame->Loader().GetDocumentLoader(); if (loader) { - loader->GetTiming().MarkBackForwardCacheRestoreNavigationStart( + loader->GetTiming().SetBackForwardCacheRestoreNavigationStart( navigation_start); } }
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc index 2ad89c64..3891afe 100644 --- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
@@ -225,8 +225,7 @@ // A wrapper class used as the callback for JavaScript executed // in an isolated world. -class JavaScriptIsolatedWorldRequest : public PausableScriptExecutor::Executor, - public WebScriptExecutionCallback { +class JavaScriptIsolatedWorldRequest : public PausableScriptExecutor::Executor { using JavaScriptExecuteRequestInIsolatedWorldCallback = mojom::blink::LocalFrame::JavaScriptExecuteRequestInIsolatedWorldCallback; @@ -249,10 +248,12 @@ void Trace(Visitor* visitor) const override; - // WebScriptExecutionCallback overrides. - void Completed(const WebVector<v8::Local<v8::Value>>& result) override; + WebScriptExecutionCallback Callback(); private: + void Completed(const WebVector<v8::Local<v8::Value>>& result, + base::TimeTicks); + Member<LocalFrame> local_frame_; int32_t world_id_; String script_; @@ -294,7 +295,8 @@ } void JavaScriptIsolatedWorldRequest::Completed( - const WebVector<v8::Local<v8::Value>>& result) { + const WebVector<v8::Local<v8::Value>>& result, + base::TimeTicks start_time) { base::Value value; if (!result.empty() && !result.begin()->IsEmpty() && wants_result_) { // It's safe to always use the main world context when converting @@ -315,6 +317,11 @@ std::move(callback_).Run(std::move(value)); } +WebScriptExecutionCallback JavaScriptIsolatedWorldRequest::Callback() { + return WTF::Bind(&JavaScriptIsolatedWorldRequest::Completed, + WrapWeakPersistent(this)); +} + HitTestResult HitTestResultForRootFramePos( LocalFrame* frame, const PhysicalOffset& pos_in_root_frame) { @@ -1125,7 +1132,7 @@ auto* executor = MakeGarbageCollected<PausableScriptExecutor>( DomWindow(), ToScriptState(frame_, *isolated_world), - /*callback=*/execution_request, + execution_request->Callback(), /*executor=*/execution_request); executor->Run();
diff --git a/third_party/blink/renderer/core/frame/pausable_script_executor.cc b/third_party/blink/renderer/core/frame/pausable_script_executor.cc index 34ba150b..4b2b8fc 100644 --- a/third_party/blink/renderer/core/frame/pausable_script_executor.cc +++ b/third_party/blink/renderer/core/frame/pausable_script_executor.cc
@@ -247,23 +247,22 @@ } // namespace -void PausableScriptExecutor::CreateAndRun( - LocalDOMWindow* window, - v8::Local<v8::Context> context, - v8::Local<v8::Function> function, - v8::Local<v8::Value> receiver, - int argc, - v8::Local<v8::Value> argv[], - WebScriptExecutionCallback* callback) { +void PausableScriptExecutor::CreateAndRun(LocalDOMWindow* window, + v8::Local<v8::Context> context, + v8::Local<v8::Function> function, + v8::Local<v8::Value> receiver, + int argc, + v8::Local<v8::Value> argv[], + WebScriptExecutionCallback callback) { ScriptState* script_state = ScriptState::From(context); if (!script_state->ContextIsValid()) { if (callback) - callback->Completed(Vector<v8::Local<v8::Value>>()); + std::move(callback).Run(Vector<v8::Local<v8::Value>>(), {}); return; } PausableScriptExecutor* executor = MakeGarbageCollected<PausableScriptExecutor>( - window, script_state, callback, + window, script_state, std::move(callback), MakeGarbageCollected<V8FunctionExecutor>( window->GetIsolate(), function, receiver, argc, argv)); executor->Run(); @@ -276,7 +275,7 @@ // is permitted. Ensure a valid scope is present for the callback. // See https://crbug.com/840719. ScriptState::Scope script_scope(script_state_); - callback_->Completed(Vector<v8::Local<v8::Value>>()); + std::move(callback_).Run(Vector<v8::Local<v8::Value>>(), {}); } Dispose(); } @@ -286,11 +285,11 @@ scoped_refptr<DOMWrapperWorld> world, Vector<WebScriptSource> sources, mojom::blink::UserActivationOption user_gesture, - WebScriptExecutionCallback* callback) + WebScriptExecutionCallback callback) : PausableScriptExecutor( window, ToScriptState(window, *world), - callback, + std::move(callback), MakeGarbageCollected<WebScriptExecutor>(std::move(sources), world->GetWorldId(), user_gesture)) {} @@ -298,11 +297,11 @@ PausableScriptExecutor::PausableScriptExecutor( LocalDOMWindow* window, ScriptState* script_state, - WebScriptExecutionCallback* callback, + WebScriptExecutionCallback callback, Executor* executor) : ExecutionContextLifecycleObserver(window), script_state_(script_state), - callback_(callback), + callback_(std::move(callback)), blocking_option_(mojom::blink::LoadEventBlockingOption::kDoNotBlock), executor_(executor) { CHECK(script_state_); @@ -343,8 +342,7 @@ void PausableScriptExecutor::ExecuteAndDestroySelf() { CHECK(script_state_->ContextIsValid()); - if (callback_) - callback_->WillExecute(); + start_time_ = base::TimeTicks::Now(); auto* window = To<LocalDOMWindow>(GetExecutionContext()); ScriptState::Scope script_scope(script_state_); @@ -388,7 +386,7 @@ window->document()->DecrementLoadEventDelayCount(); if (callback_) - callback_->Completed(results); + std::move(callback_).Run(results, start_time_); Dispose(); }
diff --git a/third_party/blink/renderer/core/frame/pausable_script_executor.h b/third_party/blink/renderer/core/frame/pausable_script_executor.h index 3c9b611..12a42ef 100644 --- a/third_party/blink/renderer/core/frame/pausable_script_executor.h +++ b/third_party/blink/renderer/core/frame/pausable_script_executor.h
@@ -7,6 +7,7 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/public/mojom/script/script_evaluation_params.mojom-blink.h" +#include "third_party/blink/public/web/web_script_execution_callback.h" #include "third_party/blink/public/web/web_script_source.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" @@ -21,7 +22,6 @@ class LocalDOMWindow; class ScriptState; -class WebScriptExecutionCallback; class CORE_EXPORT PausableScriptExecutor final : public GarbageCollected<PausableScriptExecutor>, @@ -33,7 +33,7 @@ v8::Local<v8::Value> receiver, int argc, v8::Local<v8::Value> argv[], - WebScriptExecutionCallback*); + WebScriptExecutionCallback); class Executor : public GarbageCollected<Executor> { public: @@ -48,10 +48,10 @@ scoped_refptr<DOMWrapperWorld>, Vector<WebScriptSource>, mojom::blink::UserActivationOption, - WebScriptExecutionCallback*); + WebScriptExecutionCallback); PausableScriptExecutor(LocalDOMWindow*, ScriptState*, - WebScriptExecutionCallback*, + WebScriptExecutionCallback, Executor*); ~PausableScriptExecutor() override; @@ -74,7 +74,8 @@ void HandleResults(const Vector<v8::Local<v8::Value>>& results); Member<ScriptState> script_state_; - WebScriptExecutionCallback* callback_; + WebScriptExecutionCallback callback_; + base::TimeTicks start_time_; mojom::blink::LoadEventBlockingOption blocking_option_; TaskHandle task_handle_;
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc index 731d6c5c..4a95e6f3 100644 --- a/third_party/blink/renderer/core/frame/web_frame_test.cc +++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -262,7 +262,7 @@ void ExecuteScriptsInMainWorld( WebLocalFrame* frame, base::span<const String> scripts, - WebScriptExecutionCallback* callback, + WebScriptExecutionCallback callback, mojom::blink::PromiseResultOption wait_for_promise = mojom::blink::PromiseResultOption::kAwait, mojom::blink::UserActivationOption user_gesture = @@ -273,7 +273,7 @@ frame->RequestExecuteScript( DOMWrapperWorld::kMainWorldId, sources, user_gesture, mojom::blink::EvaluationTiming::kSynchronous, - mojom::blink::LoadEventBlockingOption::kDoNotBlock, callback, + mojom::blink::LoadEventBlockingOption::kDoNotBlock, std::move(callback), BackForwardCacheAware::kAllow, wait_for_promise); } @@ -281,13 +281,14 @@ void ExecuteScriptInMainWorld( WebLocalFrame* frame, String script_string, - WebScriptExecutionCallback* callback, + WebScriptExecutionCallback callback, mojom::blink::PromiseResultOption wait_for_promise = mojom::blink::PromiseResultOption::kAwait, mojom::blink::UserActivationOption user_gesture = mojom::blink::UserActivationOption::kDoNotActivate) { - ExecuteScriptsInMainWorld(frame, base::make_span(&script_string, 1), callback, - wait_for_promise, user_gesture); + ExecuteScriptsInMainWorld(frame, base::make_span(&script_string, 1), + std::move(callback), wait_for_promise, + user_gesture); } } // namespace @@ -535,15 +536,16 @@ ->MainWorldScriptContext())); } -class ScriptExecutionCallbackHelper : public WebScriptExecutionCallback { +class ScriptExecutionCallbackHelper final { public: - explicit ScriptExecutionCallbackHelper(v8::Local<v8::Context> context) - : context_(context) {} - ~ScriptExecutionCallbackHelper() override = default; - // Returns true if the callback helper was ever invoked. bool DidComplete() const { return did_complete_; } + WebScriptExecutionCallback Callback() { + return base::BindOnce(&ScriptExecutionCallbackHelper::Completed, + base::Unretained(this)); + } + // Returns true if any results (even if they were empty) were passed to the // callback helper. This is generally false if the execution context was // invalidated while running the script. @@ -569,8 +571,8 @@ } private: - // WebScriptExecutionCallback: - void Completed(const WebVector<v8::Local<v8::Value>>& values) override { + void Completed(const WebVector<v8::Local<v8::Value>>& values, + base::TimeTicks start_time) { did_complete_ = true; string_values_.Grow(static_cast<wtf_size_t>(values.size())); for (wtf_size_t i = 0u; i < values.size(); ++i) { @@ -593,10 +595,9 @@ web_view_helper.InitializeAndLoad(base_url_ + "foo.html"); v8::HandleScope scope(v8::Isolate::GetCurrent()); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - "'hello';", &callback_helper); + "'hello';", callback_helper.Callback()); RunPendingTasks(); EXPECT_TRUE(callback_helper.DidComplete()); EXPECT_EQ("hello", callback_helper.SingleStringValue()); @@ -609,13 +610,12 @@ web_view_helper.InitializeAndLoad(base_url_ + "foo.html"); v8::HandleScope scope(v8::Isolate::GetCurrent()); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper callback_helper; // Suspend scheduled tasks so the script doesn't run. web_view_helper.GetWebView()->GetPage()->SetPaused(true); ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - "'hello';", &callback_helper); + "'hello';", callback_helper.Callback()); RunPendingTasks(); EXPECT_FALSE(callback_helper.DidComplete()); @@ -632,13 +632,11 @@ v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::HandleScope scope(isolate); - v8::Local<v8::Context> context = - web_view_helper.LocalMainFrame()->MainWorldScriptContext(); - ScriptExecutionCallbackHelper callback_helper(context); v8::TryCatch try_catch(isolate); try_catch.SetVerbose(true); + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - "foo = bar; 'hello';", &callback_helper); + "foo = bar; 'hello';", callback_helper.Callback()); RunPendingTasks(); EXPECT_TRUE(callback_helper.DidComplete()); // Even though an error is thrown here, it's swallowed by one of the @@ -657,10 +655,9 @@ constexpr char kScript[] = R"(Promise.resolve('hello');)"; v8::HandleScope scope(v8::Isolate::GetCurrent()); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - kScript, &callback_helper, + kScript, callback_helper.Callback(), mojom::blink::PromiseResultOption::kDoNotWait); RunPendingTasks(); // Since the caller specified the script shouldn't wait for the promise to @@ -679,10 +676,9 @@ constexpr char kScript[] = R"(Promise.resolve('hello');)"; v8::HandleScope scope(v8::Isolate::GetCurrent()); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - kScript, &callback_helper); + kScript, callback_helper.Callback()); RunPendingTasks(); EXPECT_TRUE(callback_helper.DidComplete()); EXPECT_EQ("hello", callback_helper.SingleStringValue()); @@ -697,10 +693,9 @@ constexpr char kScript[] = R"(Promise.reject('hello');)"; v8::HandleScope scope(v8::Isolate::GetCurrent()); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - kScript, &callback_helper); + kScript, callback_helper.Callback()); RunPendingTasks(); EXPECT_TRUE(callback_helper.DidComplete()); // Promise rejection, similar to errors, are represented by empty V8Values @@ -721,9 +716,8 @@ WebLocalFrame* iframe = web_view_helper.LocalMainFrame()->FirstChild()->ToWebLocalFrame(); - ScriptExecutionCallbackHelper callback_helper( - iframe->MainWorldScriptContext()); - ExecuteScriptInMainWorld(iframe, kScript, &callback_helper); + ScriptExecutionCallbackHelper callback_helper; + ExecuteScriptInMainWorld(iframe, kScript, callback_helper.Callback()); RunPendingTasks(); EXPECT_FALSE(callback_helper.DidComplete()); @@ -750,10 +744,9 @@ }; v8::HandleScope scope(v8::Isolate::GetCurrent()); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptsInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - scripts, &callback_helper); + scripts, callback_helper.Callback()); RunPendingTasks(); EXPECT_TRUE(callback_helper.DidComplete()); EXPECT_EQ("hello", callback_helper.StringValueAt(0)); @@ -772,19 +765,17 @@ }; v8::HandleScope scope(v8::Isolate::GetCurrent()); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptsInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - scripts, &callback_helper); + scripts, callback_helper.Callback()); RunPendingTasks(); EXPECT_FALSE(callback_helper.DidComplete()); { - ScriptExecutionCallbackHelper second_callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper second_callback_helper; ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), String("window.resolveSecond('world');"), - &second_callback_helper); + second_callback_helper.Callback()); RunPendingTasks(); EXPECT_TRUE(second_callback_helper.DidComplete()); EXPECT_EQ("undefined", second_callback_helper.SingleStringValue()); @@ -807,10 +798,9 @@ }; v8::HandleScope scope(v8::Isolate::GetCurrent()); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptsInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - scripts, &callback_helper); + scripts, callback_helper.Callback()); RunPendingTasks(); EXPECT_TRUE(callback_helper.DidComplete()); @@ -830,10 +820,9 @@ }; v8::HandleScope scope(v8::Isolate::GetCurrent()); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptsInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - scripts, &callback_helper); + scripts, callback_helper.Callback()); RunPendingTasks(); EXPECT_TRUE(callback_helper.DidComplete()); EXPECT_EQ("hello", callback_helper.StringValueAt(0)); @@ -856,7 +845,7 @@ v8::HandleScope scope(isolate); v8::Local<v8::Context> context = web_view_helper.LocalMainFrame()->MainWorldScriptContext(); - ScriptExecutionCallbackHelper callback_helper(context); + ScriptExecutionCallbackHelper callback_helper; v8::Local<v8::Function> function = v8::Function::New(context, callback).ToLocalChecked(); v8::Local<v8::Value> args[] = {v8::Undefined(isolate), @@ -865,7 +854,8 @@ ->MainFrame() ->ToWebLocalFrame() ->RequestExecuteV8Function(context, function, v8::Undefined(isolate), - std::size(args), args, &callback_helper); + std::size(args), args, + callback_helper.Callback()); RunPendingTasks(); EXPECT_TRUE(callback_helper.DidComplete()); EXPECT_EQ("hello", callback_helper.SingleStringValue()); @@ -890,12 +880,12 @@ WebLocalFrameImpl* main_frame = web_view_helper.LocalMainFrame(); web_view_helper.GetWebView()->GetPage()->SetPaused(true); - ScriptExecutionCallbackHelper callback_helper(context); + ScriptExecutionCallbackHelper callback_helper; v8::Local<v8::Function> function = v8::Function::New(context, callback).ToLocalChecked(); main_frame->RequestExecuteV8Function(context, function, v8::Undefined(context->GetIsolate()), 0, - nullptr, &callback_helper); + nullptr, callback_helper.Callback()); RunPendingTasks(); EXPECT_FALSE(callback_helper.DidComplete()); @@ -919,11 +909,10 @@ LocalFrame::NotifyUserActivation( web_view_helper.LocalMainFrame()->GetFrame(), mojom::UserActivationNotificationType::kTest); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), "navigator.userActivation.isActive;", - &callback_helper); + callback_helper.Callback()); RunPendingTasks(); EXPECT_FALSE(callback_helper.DidComplete()); @@ -941,8 +930,7 @@ web_view_helper.InitializeAndLoad(base_url_ + "single_iframe.html"); v8::HandleScope scope(v8::Isolate::GetCurrent()); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptInMainWorld( web_view_helper.GetWebView() ->MainFrame() @@ -950,7 +938,7 @@ ->ToWebLocalFrame(), "var iframe = window.top.document.getElementsByTagName('iframe')[0]; " "window.top.document.body.removeChild(iframe); 'hello';", - &callback_helper); + callback_helper.Callback()); RunPendingTasks(); EXPECT_TRUE(callback_helper.DidComplete()); EXPECT_FALSE(callback_helper.HasAnyResults()); @@ -1001,8 +989,6 @@ event_type_names::kMessage, message_event_listener); v8::HandleScope scope(v8::Isolate::GetCurrent()); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper.LocalMainFrame()->MainWorldScriptContext()); { String post_message_wo_request( @@ -1013,39 +999,55 @@ // The delegation info is not passed through a postMessage that is sent // without either user activation or the delegation option. - ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - post_message_wo_request, &callback_helper); - RunPendingTasks(); - EXPECT_TRUE(callback_helper.DidComplete()); - EXPECT_FALSE(message_event_listener->DelegateCapability()); + { + ScriptExecutionCallbackHelper callback_helper; + ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), + post_message_wo_request, + callback_helper.Callback()); + RunPendingTasks(); + EXPECT_TRUE(callback_helper.DidComplete()); + EXPECT_FALSE(message_event_listener->DelegateCapability()); + } // The delegation info is not passed through a postMessage that is sent // without user activation but with the delegation option. - ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - post_message_w_payment_request, &callback_helper); - RunPendingTasks(); - EXPECT_TRUE(callback_helper.DidComplete()); - EXPECT_FALSE(message_event_listener->DelegateCapability()); + { + ScriptExecutionCallbackHelper callback_helper; + ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), + post_message_w_payment_request, + callback_helper.Callback()); + RunPendingTasks(); + EXPECT_TRUE(callback_helper.DidComplete()); + EXPECT_FALSE(message_event_listener->DelegateCapability()); + } // The delegation info is not passed through a postMessage that is sent with // user activation but without the delegation option. - ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - post_message_wo_request, &callback_helper, - blink::mojom::PromiseResultOption::kAwait, - blink::mojom::UserActivationOption::kActivate); - RunPendingTasks(); - EXPECT_TRUE(callback_helper.DidComplete()); - EXPECT_FALSE(message_event_listener->DelegateCapability()); + { + ScriptExecutionCallbackHelper callback_helper; + ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), + post_message_wo_request, + callback_helper.Callback(), + blink::mojom::PromiseResultOption::kAwait, + blink::mojom::UserActivationOption::kActivate); + RunPendingTasks(); + EXPECT_TRUE(callback_helper.DidComplete()); + EXPECT_FALSE(message_event_listener->DelegateCapability()); + } // The delegation info is passed through a postMessage that is sent with // both user activation and the delegation option. - ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - post_message_w_payment_request, &callback_helper, - blink::mojom::PromiseResultOption::kAwait, - blink::mojom::UserActivationOption::kActivate); - RunPendingTasks(); - EXPECT_TRUE(callback_helper.DidComplete()); - EXPECT_TRUE(message_event_listener->DelegateCapability()); + { + ScriptExecutionCallbackHelper callback_helper; + ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), + post_message_w_payment_request, + callback_helper.Callback(), + blink::mojom::PromiseResultOption::kAwait, + blink::mojom::UserActivationOption::kActivate); + RunPendingTasks(); + EXPECT_TRUE(callback_helper.DidComplete()); + EXPECT_TRUE(message_event_listener->DelegateCapability()); + } } { @@ -1056,9 +1058,10 @@ // The delegation info is passed through a postMessage that is sent with // both user activation and the delegation option for another known // capability. + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), post_message_w_fullscreen_request, - &callback_helper, + callback_helper.Callback(), blink::mojom::PromiseResultOption::kAwait, blink::mojom::UserActivationOption::kActivate); RunPendingTasks(); @@ -1073,8 +1076,10 @@ // The delegation info is not passed through a postMessage that is sent with // user activation and the delegation option for an unknown capability. + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptInMainWorld(web_view_helper.GetWebView()->MainFrameImpl(), - post_message_w_unknown_request, &callback_helper, + post_message_w_unknown_request, + callback_helper.Callback(), blink::mojom::PromiseResultOption::kAwait, blink::mojom::UserActivationOption::kActivate); RunPendingTasks(); @@ -10197,10 +10202,9 @@ String DumpSize(const String& id) { String code = "dumpSize('" + id + "')"; v8::HandleScope scope(v8::Isolate::GetCurrent()); - ScriptExecutionCallbackHelper callback_helper( - web_view_helper_.LocalMainFrame()->MainWorldScriptContext()); + ScriptExecutionCallbackHelper callback_helper; ExecuteScriptInMainWorld(web_view_helper_.GetWebView()->MainFrameImpl(), - code, &callback_helper); + code, callback_helper.Callback()); RunPendingTasks(); EXPECT_TRUE(callback_helper.DidComplete()); return callback_helper.SingleStringValue();
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index d2a7456..fc095fe 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -1071,11 +1071,11 @@ v8::Local<v8::Value> receiver, int argc, v8::Local<v8::Value> argv[], - WebScriptExecutionCallback* callback) { + WebScriptExecutionCallback callback) { DCHECK(GetFrame()); PausableScriptExecutor::CreateAndRun(GetFrame()->DomWindow(), context, function, receiver, argc, argv, - callback); + std::move(callback)); } void WebLocalFrameImpl::RequestExecuteScript( @@ -1084,7 +1084,7 @@ mojom::blink::UserActivationOption user_gesture, mojom::blink::EvaluationTiming evaluation_timing, mojom::blink::LoadEventBlockingOption blocking_option, - WebScriptExecutionCallback* callback, + WebScriptExecutionCallback callback, BackForwardCacheAware back_forward_cache_aware, mojom::blink::PromiseResultOption promise_behavior) { DCHECK(GetFrame()); @@ -1108,7 +1108,7 @@ base::checked_cast<wtf_size_t>(sources.size())); auto* executor = MakeGarbageCollected<PausableScriptExecutor>( GetFrame()->DomWindow(), std::move(world), std::move(script_sources), - user_gesture, callback); + user_gesture, std::move(callback)); executor->set_wait_for_promise(promise_behavior); switch (evaluation_timing) { case mojom::blink::EvaluationTiming::kAsynchronous:
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index 3c12154d..1544772 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -90,7 +90,6 @@ class WebNode; class WebPerformance; class WebRemoteFrameImpl; -class WebScriptExecutionCallback; class WebSpellCheckPanelHostClient; class WebView; class WebViewImpl; @@ -182,13 +181,13 @@ v8::Local<v8::Value> receiver, int argc, v8::Local<v8::Value> argv[], - WebScriptExecutionCallback*) override; + WebScriptExecutionCallback) override; void RequestExecuteScript(int32_t world_id, base::span<const WebScriptSource> sources, mojom::blink::UserActivationOption, mojom::blink::EvaluationTiming, mojom::blink::LoadEventBlockingOption, - WebScriptExecutionCallback*, + WebScriptExecutionCallback, BackForwardCacheAware back_forward_cache_aware, mojom::blink::PromiseResultOption) override; void Alert(const WebString& message) override;
diff --git a/third_party/blink/renderer/core/loader/document_load_timing.cc b/third_party/blink/renderer/core/loader/document_load_timing.cc index 3ecdb7c..f69f1cc 100644 --- a/third_party/blink/renderer/core/loader/document_load_timing.cc +++ b/third_party/blink/renderer/core/loader/document_load_timing.cc
@@ -154,7 +154,7 @@ NotifyDocumentTimingChanged(); } -void DocumentLoadTiming::MarkBackForwardCacheRestoreNavigationStart( +void DocumentLoadTiming::SetBackForwardCacheRestoreNavigationStart( base::TimeTicks navigation_start) { bfcache_restore_navigation_starts_.push_back(navigation_start); NotifyDocumentTimingChanged(); @@ -214,7 +214,7 @@ NotifyDocumentTimingChanged(); } -void DocumentLoadTiming::MarkUnloadEventStart(base::TimeTicks start_time) { +void DocumentLoadTiming::SetUnloadEventStart(base::TimeTicks start_time) { unload_event_start_ = start_time; TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "unloadEventStart", start_time, "frame", @@ -222,7 +222,7 @@ NotifyDocumentTimingChanged(); } -void DocumentLoadTiming::MarkUnloadEventEnd(base::TimeTicks end_time) { +void DocumentLoadTiming::SetUnloadEventEnd(base::TimeTicks end_time) { unload_event_end_ = end_time; TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "unloadEventEnd", end_time, "frame", ToTraceValue(GetFrame())); @@ -281,7 +281,7 @@ NotifyDocumentTimingChanged(); } -void DocumentLoadTiming::MarkActivationStart(base::TimeTicks activation_start) { +void DocumentLoadTiming::SetActivationStart(base::TimeTicks activation_start) { activation_start_ = activation_start; TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "activationtart", activation_start, "frame",
diff --git a/third_party/blink/renderer/core/loader/document_load_timing.h b/third_party/blink/renderer/core/loader/document_load_timing.h index fd1d899..614891d 100644 --- a/third_party/blink/renderer/core/loader/document_load_timing.h +++ b/third_party/blink/renderer/core/loader/document_load_timing.h
@@ -57,7 +57,7 @@ void MarkNavigationStart(); void SetNavigationStart(base::TimeTicks); - void MarkBackForwardCacheRestoreNavigationStart(base::TimeTicks); + void SetBackForwardCacheRestoreNavigationStart(base::TimeTicks); void MarkCommitNavigationEnd(); void SetInputStart(base::TimeTicks); @@ -74,8 +74,8 @@ has_cross_origin_redirect_ = value; } - void MarkUnloadEventStart(base::TimeTicks); - void MarkUnloadEventEnd(base::TimeTicks); + void SetUnloadEventStart(base::TimeTicks); + void SetUnloadEventEnd(base::TimeTicks); void MarkFetchStart(); void SetFetchStart(base::TimeTicks); @@ -85,7 +85,7 @@ void MarkLoadEventStart(); void MarkLoadEventEnd(); - void MarkActivationStart(base::TimeTicks); + void SetActivationStart(base::TimeTicks); void SetCanRequestFromPreviousDocument(bool value) { can_request_from_previous_document_ = value;
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 0c91a50..719a83a5 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -2887,7 +2887,7 @@ // process already knows it. } - GetTiming().MarkActivationStart(params.activation_start); + GetTiming().SetActivationStart(params.activation_start); } HashMap<KURL, EarlyHintsPreloadEntry>
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 061c423..b0a24ea2b 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -1350,10 +1350,10 @@ if (old_document_info->unload_timing_info.unload_timing.has_value()) { document_loader_->GetTiming().SetCanRequestFromPreviousDocument( old_document_info->unload_timing_info.unload_timing->can_request); - document_loader_->GetTiming().MarkUnloadEventStart( + document_loader_->GetTiming().SetUnloadEventStart( old_document_info->unload_timing_info.unload_timing ->unload_event_start); - document_loader_->GetTiming().MarkUnloadEventEnd( + document_loader_->GetTiming().SetUnloadEventEnd( old_document_info->unload_timing_info.unload_timing ->unload_event_end); document_loader_->GetTiming().MarkCommitNavigationEnd();
diff --git a/third_party/blink/renderer/core/scheduler_integration_tests/virtual_time_test.cc b/third_party/blink/renderer/core/scheduler_integration_tests/virtual_time_test.cc index 693bd0c..85d68c7 100644 --- a/third_party/blink/renderer/core/scheduler_integration_tests/virtual_time_test.cc +++ b/third_party/blink/renderer/core/scheduler_integration_tests/virtual_time_test.cc
@@ -20,17 +20,16 @@ namespace blink { namespace virtual_time_test { -class ScriptExecutionCallbackHelper : public WebScriptExecutionCallback { +class ScriptExecutionCallbackHelper final { public: const String Result() const { return result_; } - - private: - void Completed(const WebVector<v8::Local<v8::Value>>& values) override { + void Completed(const WebVector<v8::Local<v8::Value>>& values, + base::TimeTicks start_time) { if (!values.empty() && !values[0].IsEmpty() && values[0]->IsString()) { result_ = ToCoreString(v8::Local<v8::String>::Cast(values[0])); } } - + private: String result_; }; @@ -51,7 +50,9 @@ DOMWrapperWorld::kMainWorldId, base::make_span(&source, 1), mojom::blink::UserActivationOption::kDoNotActivate, mojom::blink::EvaluationTiming::kSynchronous, - mojom::blink::LoadEventBlockingOption::kDoNotBlock, &callback_helper, + mojom::blink::LoadEventBlockingOption::kDoNotBlock, + base::BindOnce(&ScriptExecutionCallbackHelper::Completed, + base::Unretained(&callback_helper)), BackForwardCacheAware::kAllow, mojom::blink::PromiseResultOption::kDoNotWait);
diff --git a/third_party/blink/renderer/core/script/classic_pending_script.cc b/third_party/blink/renderer/core/script/classic_pending_script.cc index 78b5f53..14f0558 100644 --- a/third_party/blink/renderer/core/script/classic_pending_script.cc +++ b/third_party/blink/renderer/core/script/classic_pending_script.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/script/classic_pending_script.h" #include "base/feature_list.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/script/script_type.mojom-blink-forward.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h" @@ -60,6 +61,27 @@ KURL BaseUrl(const ScriptResource& resource) { return resource.GetResponse().ResponseUrl(); } + +bool CheckIfEligibleForDelay(const KURL& url, + const Document& element_document, + const ScriptElementBase& element) { + if (!base::FeatureList::IsEnabled(features::kDelayAsyncScriptExecution)) + return false; + + if (element.IsPotentiallyRenderBlocking()) + return false; + + if (features::kDelayAsyncScriptExecutionCrossSiteOnlyParam.Get()) { + ExecutionContext* context = element_document.GetExecutionContext(); + scoped_refptr<const SecurityOrigin> src_security_origin = + SecurityOrigin::Create(url); + if (src_security_origin->IsSameSiteWith(context->GetSecurityOrigin())) + return false; + } + + return true; +} + } // namespace // <specdef href="https://html.spec.whatwg.org/C/#fetch-a-classic-script"> @@ -80,7 +102,8 @@ MakeGarbageCollected<ClassicPendingScript>( element, TextPosition::MinimumPosition(), KURL(), KURL(), String(), ScriptSourceLocationType::kExternalFile, options, - true /* is_external */); + true /* is_external */, + CheckIfEligibleForDelay(url, element_document, *element)); // [Intervention] // For users on slow connections, we want to avoid blocking the parser in @@ -114,7 +137,8 @@ ClassicPendingScript* pending_script = MakeGarbageCollected<ClassicPendingScript>( element, starting_position, source_url, base_url, source_text, - source_location_type, options, false /* is_external */); + source_location_type, options, false /* is_external */, + false /* is_eligible_for_delay */); pending_script->CheckState(); return pending_script; } @@ -127,7 +151,8 @@ const String& source_text_for_inline_script, ScriptSourceLocationType source_location_type, const ScriptFetchOptions& options, - bool is_external) + bool is_external, + bool is_eligible_for_delay) : PendingScript(element, starting_position), options_(options), source_url_for_inline_script_(source_url_for_inline_script), @@ -136,7 +161,8 @@ source_location_type_(source_location_type), is_external_(is_external), ready_state_(is_external ? kWaitingForResource : kReady), - integrity_failure_(false) { + integrity_failure_(false), + is_eligible_for_delay_(is_eligible_for_delay) { CHECK(GetElement()); if (is_external_) { @@ -219,8 +245,10 @@ // We don't delay async scripts that have matched a resource in the preload // cache, because we're using <link rel=preload> as a signal that the script // is higher-than-usual priority, and therefore should be executed earlier - // rather than later. - return !GetResource()->IsLinkPreload(); + // rather than later. IsLinkPreload() can't be checked in + // CheckIfEligibleForDelay() since ClassicPendingScript::Fetch() initialize + // the state. + return is_eligible_for_delay_ && !GetResource()->IsLinkPreload(); } void ClassicPendingScript::NotifyFinished(Resource* resource) {
diff --git a/third_party/blink/renderer/core/script/classic_pending_script.h b/third_party/blink/renderer/core/script/classic_pending_script.h index c17a5d55..01bc595 100644 --- a/third_party/blink/renderer/core/script/classic_pending_script.h +++ b/third_party/blink/renderer/core/script/classic_pending_script.h
@@ -60,7 +60,8 @@ const String& source_text_for_inline_script, ScriptSourceLocationType, const ScriptFetchOptions&, - bool is_external); + bool is_external, + bool is_eligible_for_delay); ~ClassicPendingScript() override; void Trace(Visitor*) const override; @@ -137,6 +138,7 @@ const bool is_external_; ReadyState ready_state_; bool integrity_failure_; + const bool is_eligible_for_delay_; // The request is intervened by document.write() intervention. bool intervened_ = false;
diff --git a/third_party/blink/renderer/core/script/script_runner.cc b/third_party/blink/renderer/core/script/script_runner.cc index 5dd753b..83d9d1ba 100644 --- a/third_party/blink/renderer/core/script/script_runner.cc +++ b/third_party/blink/renderer/core/script/script_runner.cc
@@ -56,13 +56,10 @@ PendingScript* pending_script) { DelayReasons reasons = static_cast<DelayReasons>(DelayReason::kLoad); - if (base::FeatureList::IsEnabled(features::kDelayAsyncScriptExecution)) { - if (pending_script->IsEligibleForDelay() && - !pending_script->GetElement()->IsPotentiallyRenderBlocking() && - (active_delay_reasons_ & - static_cast<DelayReasons>(DelayReason::kMilestone))) { - reasons |= static_cast<DelayReasons>(DelayReason::kMilestone); - } + if (pending_script->IsEligibleForDelay() && + (active_delay_reasons_ & + static_cast<DelayReasons>(DelayReason::kMilestone))) { + reasons |= static_cast<DelayReasons>(DelayReason::kMilestone); } if (base::FeatureList::IsEnabled(features::kForceDeferScriptIntervention)) {
diff --git a/third_party/blink/renderer/extensions/chromeos/event_type_chromeos_names.json5 b/third_party/blink/renderer/extensions/chromeos/event_type_chromeos_names.json5 index 1fc566d5..ca7370a 100644 --- a/third_party/blink/renderer/extensions/chromeos/event_type_chromeos_names.json5 +++ b/third_party/blink/renderer/extensions/chromeos/event_type_chromeos_names.json5
@@ -7,5 +7,6 @@ data: [ "acceleratordown", "acceleratorup", + "windowclosed", ] }
diff --git a/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/BUILD.gn b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/BUILD.gn index 76541e0f..be47655 100644 --- a/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/BUILD.gn +++ b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/BUILD.gn
@@ -12,6 +12,8 @@ "cros_screen.h", "cros_window.cc", "cros_window.h", + "cros_window_event.cc", + "cros_window_event.h", "cros_window_management.cc", "cros_window_management.h", ]
diff --git a/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event.cc b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event.cc new file mode 100644 index 0000000..c72d3d7 --- /dev/null +++ b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event.cc
@@ -0,0 +1,31 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event.h" + +#include "third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_event_init.h" +#include "third_party/blink/renderer/extensions/chromeos/event_interface_chromeos_names.h" +#include "third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window.h" + +namespace blink { + +CrosWindowEvent* CrosWindowEvent::Create( + const AtomicString& type, + const CrosWindowEventInit* event_init) { + return MakeGarbageCollected<CrosWindowEvent>(type, event_init); +} + +CrosWindowEvent::CrosWindowEvent(const AtomicString& type, + const CrosWindowEventInit* event_init) + : Event(type, Bubbles::kYes, Cancelable::kNo), + window_(event_init->window()) {} + +CrosWindowEvent::~CrosWindowEvent() = default; + +void CrosWindowEvent::Trace(Visitor* visitor) const { + visitor->Trace(window_); + Event::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event.h b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event.h new file mode 100644 index 0000000..9c15f2f2 --- /dev/null +++ b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event.h
@@ -0,0 +1,36 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_EXTENSIONS_CHROMEOS_SYSTEM_EXTENSIONS_WINDOW_MANAGEMENT_CROS_WINDOW_EVENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_EXTENSIONS_CHROMEOS_SYSTEM_EXTENSIONS_WINDOW_MANAGEMENT_CROS_WINDOW_EVENT_H_ + +#include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window.h" + +namespace blink { + +class CrosWindowEventInit; + +class CrosWindowEvent final : public Event { + DEFINE_WRAPPERTYPEINFO(); + + public: + static CrosWindowEvent* Create(const AtomicString& type, + const CrosWindowEventInit* event_init); + + CrosWindowEvent(const AtomicString& type, + const CrosWindowEventInit* event_init); + ~CrosWindowEvent() override; + + CrosWindow* window() { return window_; } + + void Trace(Visitor*) const override; + + private: + Member<CrosWindow> window_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_EXTENSIONS_CHROMEOS_SYSTEM_EXTENSIONS_WINDOW_MANAGEMENT_CROS_WINDOW_MANAGEMENT_WINDOW_EVENT_H_
diff --git a/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event.idl b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event.idl new file mode 100644 index 0000000..eed3861 --- /dev/null +++ b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event.idl
@@ -0,0 +1,13 @@ +// Copyright 2022 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. + +// Fired on window event (open/close/focus). +[ + RuntimeEnabled=BlinkExtensionChromeOSWindowManagement, + Exposed=ChromeOSExtensions +] interface CrosWindowEvent : Event { + constructor(DOMString type, CrosWindowEventInit eventInitDict); + // The CrosWindow associated with this event. + readonly attribute CrosWindow window; +};
diff --git a/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event_init.idl b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event_init.idl new file mode 100644 index 0000000..96d0652 --- /dev/null +++ b/third_party/blink/renderer/extensions/chromeos/system_extensions/window_management/cros_window_event_init.idl
@@ -0,0 +1,7 @@ +// Copyright 2022 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. + +dictionary CrosWindowEventInit : EventInit { + required CrosWindow window; +};
diff --git a/third_party/blink/renderer/modules/breakout_box/OWNERS b/third_party/blink/renderer/modules/breakout_box/OWNERS index 7c203f44..7cffee4 100644 --- a/third_party/blink/renderer/modules/breakout_box/OWNERS +++ b/third_party/blink/renderer/modules/breakout_box/OWNERS
@@ -2,3 +2,4 @@ guidou@chromium.org hta@chromium.org tguilbert@chromium.org +toprice@chromium.org
diff --git a/third_party/blink/renderer/platform/graphics/color.cc b/third_party/blink/renderer/platform/graphics/color.cc index 91629344..afaa9c0c1 100644 --- a/third_party/blink/renderer/platform/graphics/color.cc +++ b/third_party/blink/renderer/platform/graphics/color.cc
@@ -60,46 +60,6 @@ return static_cast<int>(c / alpha); } -double CalcHue(double temp1, double temp2, double hue_val) { - if (hue_val < 0.0) - hue_val += 6.0; - else if (hue_val >= 6.0) - hue_val -= 6.0; - if (hue_val < 1.0) - return temp1 + (temp2 - temp1) * hue_val; - if (hue_val < 3.0) - return temp2; - if (hue_val < 4.0) - return temp1 + (temp2 - temp1) * (4.0 - hue_val); - return temp1; -} - -// Explanation of this algorithm can be found in the CSS Color 4 Module -// specification at https://drafts.csswg.org/css-color-4/#hsl-to-rgb with -// further explanation available at http://en.wikipedia.org/wiki/HSL_color_space - -// Hue is in the range of 0.0 to 6.0, the remainder are in the range 0.0 to 1.0. -// Out parameters r, g, and b are also returned in range 0.0 to 1.0. -void HSLToRGB(double hue, - double saturation, - double lightness, - double& r, - double& g, - double& b) { - if (!saturation) { - r = g = b = lightness; - } else { - double temp2 = lightness <= 0.5 - ? lightness * (1.0 + saturation) - : lightness + saturation - lightness * saturation; - double temp1 = 2.0 * lightness - temp2; - - r = CalcHue(temp1, temp2, hue + 2.0); - g = CalcHue(temp1, temp2, hue); - b = CalcHue(temp1, temp2, hue - 2.0); - } -} - int ColorFloatToRGBAByte(float f) { return ClampTo(static_cast<int>(lroundf(255.0f * f)), 0, 255); } @@ -162,16 +122,6 @@ } // namespace -RGBA32 MakeRGB(int r, int g, int b) { - return 0xFF000000 | ClampTo(r, 0, 255) << 16 | ClampTo(g, 0, 255) << 8 | - ClampTo(b, 0, 255); -} - -RGBA32 MakeRGBA(int r, int g, int b, int a) { - return ClampTo(a, 0, 255) << 24 | ClampTo(r, 0, 255) << 16 | - ClampTo(g, 0, 255) << 8 | ClampTo(b, 0, 255); -} - RGBA32 MakeRGBA32FromFloats(float r, float g, float b, float a) { return ColorFloatToRGBAByte(a) << 24 | ColorFloatToRGBAByte(r) << 16 | ColorFloatToRGBAByte(g) << 8 | ColorFloatToRGBAByte(b); @@ -183,45 +133,6 @@ return SkColor4f{r, g, b, a}; } -// Hue is in the range of 0 to 6.0, the remainder are in the range 0 to 1.0 -RGBA32 MakeRGBAFromHSLA(double hue, - double saturation, - double lightness, - double alpha) { - const double scale_factor = 255.0; - double r, g, b; - HSLToRGB(hue, saturation, lightness, r, g, b); - - return MakeRGBA(static_cast<int>(round(r * scale_factor)), - static_cast<int>(round(g * scale_factor)), - static_cast<int>(round(b * scale_factor)), - static_cast<int>(round(alpha * scale_factor))); -} - -// Hue is in the range of 0 to 6.0, the remainder are in the range 0 to 1.0 -RGBA32 MakeRGBAFromHWBA(double hue, double white, double black, double alpha) { - const double scale_factor = 255.0; - - if (white + black >= 1.0) { - int gray = static_cast<int>(round(white / (white + black) * scale_factor)); - return MakeRGBA(gray, gray, gray, - static_cast<int>(round(alpha * scale_factor))); - } - - // Leverage HSL to RGB conversion to find HWB to RGB, see - // https://drafts.csswg.org/css-color-4/#hwb-to-rgb - double r, g, b; - HSLToRGB(hue, 1.0, 0.5, r, g, b); - r += white - (white + black) * r; - g += white - (white + black) * g; - b += white - (white + black) * b; - - return MakeRGBA(static_cast<int>(round(r * scale_factor)), - static_cast<int>(round(g * scale_factor)), - static_cast<int>(round(b * scale_factor)), - static_cast<int>(round(alpha * scale_factor))); -} - RGBA32 MakeRGBAFromCMYKA(float c, float m, float y, float k, float a) { double colors = 1 - k; int r = static_cast<int>(nextafter(256, 0) * (colors * (1 - c)));
diff --git a/third_party/blink/renderer/platform/graphics/color.h b/third_party/blink/renderer/platform/graphics/color.h index f601a3a..0b877c3 100644 --- a/third_party/blink/renderer/platform/graphics/color.h +++ b/third_party/blink/renderer/platform/graphics/color.h
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/forward.h" +#include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_uchar.h" #include "third_party/skia/include/core/SkColor.h" @@ -41,12 +42,100 @@ typedef unsigned RGBA32; // RGBA quadruplet // TODO(crbug.com/1351544): Remove these functions. -PLATFORM_EXPORT RGBA32 MakeRGB(int r, int g, int b); -PLATFORM_EXPORT RGBA32 MakeRGBA(int r, int g, int b, int a); +constexpr RGBA32 MakeRGB(int r, int g, int b) { + return 0xFF000000 | ClampTo(r, 0, 255) << 16 | ClampTo(g, 0, 255) << 8 | + ClampTo(b, 0, 255); +} + +constexpr RGBA32 MakeRGBA(int r, int g, int b, int a) { + return ClampTo(a, 0, 255) << 24 | ClampTo(r, 0, 255) << 16 | + ClampTo(g, 0, 255) << 8 | ClampTo(b, 0, 255); +} PLATFORM_EXPORT RGBA32 MakeRGBA32FromFloats(float r, float g, float b, float a); -PLATFORM_EXPORT RGBA32 MakeRGBAFromHSLA(double h, double s, double l, double a); -PLATFORM_EXPORT RGBA32 MakeRGBAFromHWBA(double h, double w, double b, double a); + +constexpr double CalcHue(double temp1, double temp2, double hue_val) { + if (hue_val < 0.0) + hue_val += 6.0; + else if (hue_val >= 6.0) + hue_val -= 6.0; + if (hue_val < 1.0) + return temp1 + (temp2 - temp1) * hue_val; + if (hue_val < 3.0) + return temp2; + if (hue_val < 4.0) + return temp1 + (temp2 - temp1) * (4.0 - hue_val); + return temp1; +} + +// Explanation of this algorithm can be found in the CSS Color 4 Module +// specification at https://drafts.csswg.org/css-color-4/#hsl-to-rgb with +// further explanation available at http://en.wikipedia.org/wiki/HSL_color_space + +// Hue is in the range of 0.0 to 6.0, the remainder are in the range 0.0 to 1.0. +// Out parameters r, g, and b are also returned in range 0.0 to 1.0. +constexpr void HSLToRGB(double hue, + double saturation, + double lightness, + double& r, + double& g, + double& b) { + if (!saturation) { + r = g = b = lightness; + } else { + double temp2 = lightness <= 0.5 + ? lightness * (1.0 + saturation) + : lightness + saturation - lightness * saturation; + double temp1 = 2.0 * lightness - temp2; + + r = CalcHue(temp1, temp2, hue + 2.0); + g = CalcHue(temp1, temp2, hue); + b = CalcHue(temp1, temp2, hue - 2.0); + } +} + +// Hue is in the range of 0 to 6.0, the remainder are in the range 0 to 1.0 +constexpr RGBA32 MakeRGBAFromHSLA(double hue, + double saturation, + double lightness, + double alpha) { + const double scale_factor = 255.0; + double r = 0, g = 0, b = 0; + HSLToRGB(hue, saturation, lightness, r, g, b); + + return MakeRGBA(static_cast<int>(round(r * scale_factor)), + static_cast<int>(round(g * scale_factor)), + static_cast<int>(round(b * scale_factor)), + static_cast<int>(round(alpha * scale_factor))); +} + +// Hue is in the range of 0 to 6.0, the remainder are in the range 0 to 1.0 +constexpr RGBA32 MakeRGBAFromHWBA(double hue, + double white, + double black, + double alpha) { + const double scale_factor = 255.0; + + if (white + black >= 1.0) { + int gray = static_cast<int>(round(white / (white + black) * scale_factor)); + return MakeRGBA(gray, gray, gray, + static_cast<int>(round(alpha * scale_factor))); + } + + // Leverage HSL to RGB conversion to find HWB to RGB, see + // https://drafts.csswg.org/css-color-4/#hwb-to-rgb + double r = 0, g = 0, b = 0; + HSLToRGB(hue, 1.0, 0.5, r, g, b); + r += white - (white + black) * r; + g += white - (white + black) * g; + b += white - (white + black) * b; + + return MakeRGBA(static_cast<int>(round(r * scale_factor)), + static_cast<int>(round(g * scale_factor)), + static_cast<int>(round(b * scale_factor)), + static_cast<int>(round(alpha * scale_factor))); +} + PLATFORM_EXPORT RGBA32 MakeRGBAFromCMYKA(float c, float m, float y, float k, float a);
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index f30a8dad..2732779 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1724,6 +1724,7 @@ name: "PendingBeaconAPI", origin_trial_feature_name: "PendingBeaconAPI", origin_trial_allows_third_party: true, + status: "experimental", }, { name: "PercentBasedScrolling",
diff --git a/third_party/blink/renderer/platform/wtf/math_extras.h b/third_party/blink/renderer/platform/wtf/math_extras.h index 1121dff..2876f9ec 100644 --- a/third_party/blink/renderer/platform/wtf/math_extras.h +++ b/third_party/blink/renderer/platform/wtf/math_extras.h
@@ -309,9 +309,10 @@ // And, finally, the actual function for people to call. template <typename LimitType, typename ValueType> -inline LimitType ClampTo(ValueType value, - LimitType min = DefaultMinimumForClamp<LimitType>(), - LimitType max = DefaultMaximumForClamp<LimitType>()) { +constexpr LimitType ClampTo( + ValueType value, + LimitType min = DefaultMinimumForClamp<LimitType>(), + LimitType max = DefaultMaximumForClamp<LimitType>()) { DCHECK(!std::isnan(static_cast<double>(value))); DCHECK_LE(min, max); // This also ensures |min| and |max| aren't NaN. return ClampToHelper<LimitType, ValueType>::ClampTo(value, min, max);
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-features=PendingBeaconAPI b/third_party/blink/web_tests/FlagExpectations/enable-features=PendingBeaconAPI deleted file mode 100644 index 06c9016..0000000 --- a/third_party/blink/web_tests/FlagExpectations/enable-features=PendingBeaconAPI +++ /dev/null
@@ -1,8 +0,0 @@ -# Pending Beacon API: Tests should all pass with -# --enable-blink-features=PendingBeaconAPI -# -# results: [ Timeout Crash Pass Failure Slow Skip ] - -crbug.com/1293679 pending_beacon/pending_beacon-basic.html [ Pass ] -crbug.com/1293679 pending_beacon/pending_beacon-deactivate.html [ Pass ] -crbug.com/1293679 wpt_internal/pending_beacon/* [ Pass ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 75da4ba..b4664d1 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -1984,3 +1984,6 @@ crbug.com/1260483 http/tests/inspector-protocol/fenced-frame/* [ Skip ] crbug.com/1260483 virtual/fenced-frame-mparch/http/tests/inspector-protocol/fenced-frame/* [ Pass ] +# Feature is not yet launched, so skip the base. +crbug.com/1293679 external/wpt/pending_beacon/* [ Skip ] +crbug.com/1293679 virtual/pending-beacon/external/wpt/pending_beacon/* [ Pass ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index cb38a9c..aa976247 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1386,8 +1386,6 @@ crbug.com/880802 external/wpt/css/css-contain/contain-layout-017.html [ Failure ] crbug.com/880802 external/wpt/css/css-contain/contain-paint-021.html [ Failure ] -crbug.com/882367 external/wpt/css/css-contain/contain-paint-clip-015.html [ Failure ] -crbug.com/882367 external/wpt/css/css-contain/contain-paint-clip-016.html [ Failure ] crbug.com/882385 external/wpt/css/css-contain/quote-scoping-001.html [ Failure ] crbug.com/882385 external/wpt/css/css-contain/quote-scoping-002.html [ Failure ] crbug.com/882385 external/wpt/css/css-contain/quote-scoping-003.html [ Failure ] @@ -3371,6 +3369,7 @@ crbug.com/626703 [ Win ] virtual/partitioned-cookies/http/tests/inspector-protocol/network/disabled-cache-navigation.js [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Mac11-arm64 ] wpt_internal/navigation-api/ordering-and-transition/navigate-cross-document-double.html [ Timeout ] crbug.com/626703 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/dynamic-import.https.html [ Failure ] crbug.com/626703 external/wpt/custom-elements/form-associated/ElementInternals-target-element-is-held-strongly.html [ Timeout ] crbug.com/626703 [ Mac11-arm64 ] external/wpt/html/browsers/browsing-the-web/remote-context-helper-tests/navigation-same-document.window.html [ Failure Timeout ] @@ -6893,11 +6892,6 @@ # Sheriff 2022-05-16 crbug.com/1325858 virtual/wasm-code-caching/http/tests/wasm/caching/code-cache.html [ Skip ] -# Pending Beacon API: Not enabled by default so skip these tests. -crbug.com/1293679 pending_beacon/pending_beacon-basic.html [ Skip ] -crbug.com/1293679 pending_beacon/pending_beacon-deactivate.html [ Skip ] -crbug.com/1293679 wpt_internal/pending_beacon/* [ Skip ] - # introduce blink_wpt_tests crbug.com/1299834 [ Win ] wpt_internal/html/interaction/focus/the-autofocus-attribute/object-fallback.html [ Timeout ] crbug.com/1299834 external/wpt/css/css-pseudo/first-letter-with-quote.html [ Failure ] @@ -7095,10 +7089,18 @@ # Sheriff 2022-08-11 # Most likely a forced style/layout update from accessibiity while we are # render blocking, which should not happen. -crbug.com/1351811 external/wpt/css/css-transitions/no-transition-from-ua-to-blocking-stylesheet.html [ Pass Failure ] +crbug.com/1351811 external/wpt/css/css-transitions/no-transition-from-ua-to-blocking-stylesheet.html [ Failure Pass ] # Flakes on all platforms. -crbug.com/1352209 wpt_internal/navigation-api/ordering-and-transition/navigate-cross-document-double.html [ Failure Pass ] +crbug.com/1352209 [ Fuchsia ] wpt_internal/navigation-api/ordering-and-transition/navigate-cross-document-double.html [ Failure Pass ] +crbug.com/1352209 [ Linux ] wpt_internal/navigation-api/ordering-and-transition/navigate-cross-document-double.html [ Failure Pass ] +crbug.com/1352209 [ Mac10.13 ] wpt_internal/navigation-api/ordering-and-transition/navigate-cross-document-double.html [ Failure Pass ] +crbug.com/1352209 [ Mac10.14 ] wpt_internal/navigation-api/ordering-and-transition/navigate-cross-document-double.html [ Failure Pass ] +crbug.com/1352209 [ Mac10.15 ] wpt_internal/navigation-api/ordering-and-transition/navigate-cross-document-double.html [ Failure Pass ] +crbug.com/1352209 [ Mac11 ] wpt_internal/navigation-api/ordering-and-transition/navigate-cross-document-double.html [ Failure Pass ] +crbug.com/1352209 [ Mac12 ] wpt_internal/navigation-api/ordering-and-transition/navigate-cross-document-double.html [ Failure Pass ] +crbug.com/1352209 [ Mac12-arm64 ] wpt_internal/navigation-api/ordering-and-transition/navigate-cross-document-double.html [ Failure Pass ] +crbug.com/1352209 [ Win ] wpt_internal/navigation-api/ordering-and-transition/navigate-cross-document-double.html [ Failure Pass ] # Sheriff 2022-08-12 crbug.com/1350611 [ Mac10.15 ] external/wpt/html/browsers/browsing-the-web/remote-context-helper-tests/navigation-same-document.window.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 1c3efd4..5026ee28 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1094,6 +1094,12 @@ "args": ["--disable-features=DelayAsyncScriptExecution"] }, { + "prefix": "async-script-scheduling-apply-to-cross-site-only", + "platforms": ["Linux", "Mac", "Win"], + "bases": ["wpt_internal/async-script-scheduling"], + "args": ["--enable-features=DelayAsyncScriptExecution:cross_site_only/true"] + }, + { "prefix": "async-script-scheduling-finished-parsing", "platforms": ["Linux", "Mac", "Win"], "bases": ["wpt_internal/async-script-scheduling"], @@ -1332,5 +1338,11 @@ "platforms": ["Linux", "Mac", "Win"], "bases": [ "http/tests/inspector-protocol/issues/cookie-domain-non-ascii.js" ], "args": ["--enable-features=CookieDomainRejectNonASCII"] + }, + { + "prefix": "pending-beacon", + "platforms": ["Linux", "Mac", "Win"], + "bases": ["external/wpt/pending_beacon"], + "args": ["--enable-features=PendingBeaconAPI"] } ]
diff --git a/third_party/blink/web_tests/android/WebviewWPTExpectations b/third_party/blink/web_tests/android/WebviewWPTExpectations index 3d6f265..c9a5243 100644 --- a/third_party/blink/web_tests/android/WebviewWPTExpectations +++ b/third_party/blink/web_tests/android/WebviewWPTExpectations
@@ -2861,7 +2861,6 @@ crbug.com/1050754 external/wpt/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html [ Failure Pass ] crbug.com/1050754 external/wpt/html/semantics/forms/constraints/form-validation-validity-valueMissing.html [ Failure Pass ] crbug.com/1050754 external/wpt/html/semantics/forms/form-submission-0/form-double-submit-3.html [ Failure ] -crbug.com/1050754 external/wpt/html/semantics/forms/form-submission-0/form-double-submit-to-different-origin-frame.html [ Failure ] crbug.com/1050754 external/wpt/html/semantics/forms/form-submission-0/form-double-submit.html [ Failure ] crbug.com/1050754 external/wpt/html/semantics/forms/form-submission-0/getactionurl.html [ Failure Pass ] crbug.com/1050754 external/wpt/html/semantics/forms/form-submission-target/rel-base-target.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version index 8a82631..2fcb556 100644 --- a/third_party/blink/web_tests/external/Version +++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@ -Version: 1d7b12e92199a765ff83c89c8c4f8345fb5137c3 +Version: f1ef84ca14e9e7f18d82544dfa2191ccab027757
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 35dc05f4..0a7bcc3d 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
@@ -95234,7 +95234,7 @@ ] ], "contain-layout-017.html": [ - "c8118ad974844cd807e0dfbcc07a9a06469a308c", + "fd74c5a5f4aa81b14da7aaa3e6da927e30a2e9cb", [ null, [ @@ -96027,7 +96027,7 @@ ] ], "contain-paint-021.html": [ - "a8ea1c8bfc2d9686d5fa1659a77e187ea8bbc28e", + "c1f145245d29702914c5e35d7a4a8053f452c156", [ null, [ @@ -309104,7 +309104,7 @@ [] ], "fill-and-stroke-styles.yaml": [ - "88a36119d4127907a3f4dc494e9b28349b1a1929", + "1650ec4909b2adf1bd582f88a02f25e33e98975e", [] ], "line-styles.yaml": [ @@ -309201,7 +309201,7 @@ [] ], "drawing-images-to-the-canvas.yaml": [ - "8569ed044f8d6f973a30f4fc2cc7a6d9db1811f2", + "8c6de99e0c54d02e32c45f4ed284d34518868ee0", [] ], "drawing-rectangles-to-the-canvas.yaml": [ @@ -320170,7 +320170,7 @@ [] ], "broken.png": [ - "f2581017b43d44664e7137a78c0803554b50f3b1", + "2ff648a04905f9090df637f2140c1c092cc3a247", [] ], "clear-100x50.png": [ @@ -320319,6 +320319,10 @@ "55f8e69325bc61ff83f769a6524f7f9c3310be1f", [] ], + "undecodable.png": [ + "f2581017b43d44664e7137a78c0803554b50f3b1", + [] + ], "webp-animated.webp": [ "35a8dfcf34d58060ec70f0a2a04e0d58e357e084", [] @@ -322487,7 +322491,7 @@ ] }, "lint.ignore": [ - "1f6f823f704c809133a31d321f67ea82b2cf9fb4", + "d923bbf673dd6bbdb156b077091776c370e23f33", [] ], "loading": { @@ -325440,6 +325444,30 @@ [] ] }, + "pending_beacon": { + "resources": { + "get_beacon.py": [ + "32cb9a9ba30638bf0e5c7e54655ae87e7085978d", + [] + ], + "iframe_create_beacon_no_send.html": [ + "dfe047aac8c3d6b58b4c3771946835537c21e20a", + [] + ], + "iframe_create_beacon_then_send.html": [ + "0fa2ca01dc784bc1543b22615cedd1d9d36009f4", + [] + ], + "pending_beacon-helper.js": [ + "ca34e98f43809fb6863761acee1fedc07f8533df", + [] + ], + "set_beacon.py": [ + "41618adc54ed5e7ddf1a1bfaf81f76b11febf8fc", + [] + ] + } + }, "performance-timeline": { "DIR_METADATA": [ "17e24c0942c8113028f9267cb32724f45d651c53", @@ -395282,7 +395310,7 @@ ] ], "preserve-3d-flat-grouping-properties.html": [ - "100726ab1ba0244e930bb281ec25324f5d9a0fef", + "7fbd61d85421dbed1cf37be339302af837ea2155", [ null, {} @@ -446921,7 +446949,7 @@ ] ], "2d.drawImage.broken.html": [ - "017048cf732bc30ff236f941a0ecc6d921e7b2a3", + "4b22ffc8ba6a1795f11dba87fd592d107ec2c33a", [ null, {} @@ -449020,7 +449048,7 @@ ] ], "2d.pattern.image.broken.html": [ - "8eafcada5f57d0549f91946ceb6b40e92aa995b2", + "9f1bb2d036fbb025ef852e2ea90aa133affb8a79", [ null, {} @@ -449904,7 +449932,7 @@ ] ], "createImageBitmap-invalid-args.html": [ - "74ca9a853e66591b5f043b3e9ea74346f985f7b5", + "3cae3523eff54994fdc8b8c68faaaf2b066acf7e", [ null, {} @@ -477079,7 +477107,7 @@ ], "environment-changes": { "viewport-change.html": [ - "f6ae65708c661c5ff1a957c3a8606d75a44827fb", + "bf65172bde27016130e753bdfdb6760bcc36126a", [ null, {} @@ -477947,7 +477975,7 @@ ] ], "form-double-submit-to-different-origin-frame.html": [ - "aee1d41e3a1512638a1f4e3ab5bfeb4ee9781eec", + "00a46bfd4326fc2d35d50bfc4a2f68890a5594bb", [ null, {} @@ -480423,6 +480451,13 @@ {} ] ], + "anchor-without-link.html": [ + "edaf786b2565a779d249730358d0563d6dbf7b8f", + [ + null, + {} + ] + ], "click-behavior-optional.tentative.html": [ "4418413fefe1363d1648fa1088dbc84dd8511649", [ @@ -506220,6 +506255,148 @@ ] ] }, + "pending_beacon": { + "pending_beacon-basic.tentative.window.js": [ + "82ec58a6bf3b978231358c597aff7c343a1fe0e8", + [ + "pending_beacon/pending_beacon-basic.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testharness.js" + ], + [ + "script", + "/resources/testharnessreport.js" + ] + ] + } + ] + ], + "pending_beacon-deactivate.tentative.window.js": [ + "4d8fb6be5aa4ea081f78e03f8de8aa0acb12efa2", + [ + "pending_beacon/pending_beacon-deactivate.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testharness.js" + ], + [ + "script", + "/resources/testharnessreport.js" + ] + ] + } + ] + ], + "pending_beacon-sendnow.tentative.window.js": [ + "cd3360aeecf29e4080228c2b6854b4c4c31cd3c9", + [ + "pending_beacon/pending_beacon-sendnow.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testharness.js" + ], + [ + "script", + "/resources/testharnessreport.js" + ], + [ + "script", + "/common/utils.js" + ], + [ + "script", + "./resources/pending_beacon-helper.js" + ] + ] + } + ] + ], + "pending_beacon-sendondiscard.tentative.window.js": [ + "80d577004b7017cf64903fac1c8da399125becb0", + [ + "pending_beacon/pending_beacon-sendondiscard.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testharness.js" + ], + [ + "script", + "/resources/testharnessreport.js" + ], + [ + "script", + "/common/utils.js" + ], + [ + "script", + "./resources/pending_beacon-helper.js" + ] + ] + } + ] + ], + "pending_get_beacon-send.tentative.window.js": [ + "7f52c082800cea4a4cac2dc57c0c99f727bbe98e", + [ + "pending_beacon/pending_get_beacon-send.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testharness.js" + ], + [ + "script", + "/resources/testharnessreport.js" + ], + [ + "script", + "/common/utils.js" + ], + [ + "script", + "./resources/pending_beacon-helper.js" + ] + ] + } + ] + ], + "pending_post_beacon-sendwithdata.tentative.window.js": [ + "1c7c6cab50ba7133418045cf764e22a91beffe4c", + [ + "pending_beacon/pending_post_beacon-sendwithdata.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testharness.js" + ], + [ + "script", + "/resources/testharnessreport.js" + ], + [ + "script", + "/common/utils.js" + ], + [ + "script", + "./resources/pending_beacon-helper.js" + ] + ] + } + ] + ] + }, "performance-timeline": { "buffered-flag-after-timeout.any.js": [ "08b3e3231465857cf248e4ace8ef574469a14864", @@ -526892,6 +527069,47 @@ } ] ], + "serialPort_readable_byob.https.any.js": [ + "8672cf7124f388309e3ab001b489f692a77bc5a9", + [ + "serial/serialPort_readable_byob.https.any.html", + { + "script_metadata": [ + [ + "script", + "/resources/test-only-api.js" + ], + [ + "script", + "/serial/resources/common.js" + ], + [ + "script", + "resources/automation.js" + ] + ] + } + ], + [ + "serial/serialPort_readable_byob.https.any.worker.html", + { + "script_metadata": [ + [ + "script", + "/resources/test-only-api.js" + ], + [ + "script", + "/serial/resources/common.js" + ], + [ + "script", + "resources/automation.js" + ] + ] + } + ] + ], "serialPort_readable_cancel.https.any.js": [ "fd1b08f6e7f34a3b7e693cc419f6ea84edfaff01", [ @@ -527221,7 +527439,7 @@ ] ], "serialPort_readable_smallRead.https.any.js": [ - "b53ea71443d44f23aa80326b65b1f7501d7846dc", + "b926aa608f38a18db536f0278e755ac7d14e93d0", [ "serial/serialPort_readable_smallRead.https.any.html", { @@ -530464,7 +530682,7 @@ ] ], "imperative-slot-api.html": [ - "b176add4091978e25f2d847d13f279eec1171ce7", + "bcf052bbab37b4060a3c1f54ed3edf0cb9c2bc45", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-layout-017.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-layout-017.html index c8118ad..fd74c5a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-layout-017.html +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-layout-017.html
@@ -6,10 +6,11 @@ <link rel="match" href="../reference/nothing.html"> <meta name=assert content="Elements in which layout containment doesn't apply, do not create a stacking context."> <style> -div { +rt { display: ruby-text; contain: layout; background: white; + overflow: hidden; } span { position: relative; @@ -18,4 +19,4 @@ </style> <p>There should be nothing below.</p> -<div><span>FAIL</span></div> +<ruby><rt><span>FAIL</span></rt></ruby>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-paint-021.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-paint-021.html index a8ea1c8b..c1f1452 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-paint-021.html +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-paint-021.html
@@ -6,10 +6,11 @@ <link rel="match" href="../reference/nothing.html"> <meta name=assert content="Elements in which paint containment doesn't apply, do not create a stacking context."> <style> -div { +rt { display: ruby-text; contain: paint; background: white; + overflow: hidden; } span { position: relative; @@ -18,4 +19,4 @@ </style> <p>There should be nothing below.</p> -<div><span>FAIL</span></div> +<ruby><rt><span>FAIL</span></rt></ruby>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties.html index 100726a..7fbd61d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties.html
@@ -40,7 +40,7 @@ <div id=filter class=child></div> </div> - <div class=parent style="backdrop-filter: invert(0)"> + <div class=parent style="-webkit-backdrop-filter: invert(0); backdrop-filter: invert(0)"> <div id=backdropFilter class=child></div> </div>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/form-submission-0/form-double-submit-to-different-origin-frame.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/form-submission-0/form-double-submit-to-different-origin-frame.html index aee1d41..00a46bf 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/form-submission-0/form-double-submit-to-different-origin-frame.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/form-submission-0/form-double-submit-to-different-origin-frame.html
@@ -4,6 +4,7 @@ <link rel="help" href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-algorithm"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> <!-- The onclick submit() should get superseded by the default action submit(), which isn't preventDefaulted by onclick here. @@ -35,8 +36,7 @@ const frame1LoadPromise = getLoadPromise(frame1); let frame2LoadPromise = getLoadPromise(frame2); - const subframeScheme = window.location.protocol === 'https:' ? 'http://' : 'https://'; - const subframeUrl = subframeScheme + window.location.host; + const subframeUrl = get_host_info().REMOTE_ORIGIN; frame1.src = subframeUrl; frame2.src = subframeUrl; await frame1LoadPromise;
diff --git a/third_party/blink/web_tests/external/wpt/lint.ignore b/third_party/blink/web_tests/external/wpt/lint.ignore index 1f6f823..d923bbf 100644 --- a/third_party/blink/web_tests/external/wpt/lint.ignore +++ b/third_party/blink/web_tests/external/wpt/lint.ignore
@@ -200,6 +200,7 @@ SET TIMEOUT: navigation-timing/* SET TIMEOUT: old-tests/submission/Microsoft/history/history_000.htm SET TIMEOUT: paint-timing/resources/subframe-painting.html +SET TIMEOUT: pending_beacon/resources/pending_beacon-helper.js SET TIMEOUT: performance-timeline/resources/navigation-id-detached-frame-page.html SET TIMEOUT: portals/resources/portals-adopt-predecessor-portal.html SET TIMEOUT: preload/single-download-preload.html
diff --git a/third_party/blink/web_tests/external/wpt/pending_beacon/pending_beacon-basic.tentative.window.js b/third_party/blink/web_tests/external/wpt/pending_beacon/pending_beacon-basic.tentative.window.js new file mode 100644 index 0000000..82ec58a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pending_beacon/pending_beacon-basic.tentative.window.js
@@ -0,0 +1,61 @@ +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.js + +'use strict'; + +test(() => { + assert_throws_js(TypeError, () => new PendingBeacon('/')); +}, `PendingBeacon cannot be constructed directly.`); + +const BeaconTypes = [ + {type: PendingPostBeacon, name: 'PendingPostBeacon', expectedMethod: 'POST'}, + {type: PendingGetBeacon, name: 'PendingGetBeacon', expectedMethod: 'GET'}, +]; + +for (const beaconType of BeaconTypes) { + test(() => { + assert_throws_js(TypeError, () => new beaconType.type()); + }, `${beaconType.name}: constructor throws TypeError if url is missing`); + + test(() => { + const beacon = new beaconType.type('/'); + assert_equals(beacon.url, '/'); + assert_equals(beacon.method, beaconType.expectedMethod); + assert_equals(beacon.backgroundTimeout, -1); + assert_equals(beacon.timeout, -1); + assert_true(beacon.pending); + }, `${beaconType.name}: constructor sets default properties if missing.`); + + test(() => { + const beacon = new beaconType.type( + 'https://www.google.com', {backgroundTimeout: 200, timeout: 100}); + assert_equals(beacon.url, 'https://www.google.com'); + assert_equals(beacon.method, beaconType.expectedMethod); + assert_equals(beacon.backgroundTimeout, 200); + assert_equals(beacon.timeout, 100); + assert_true(beacon.pending); + }, `${beaconType.name}: constructor can set properties.`); + + test(() => { + let beacon = new beaconType.type( + 'https://www.google.com', + {method: 'GET', backgroundTimeout: 200, timeout: 100}); + + beacon.backgroundTimeout = 400; + assert_equals(beacon.backgroundTimeout, 400); + + beacon.timeout = 600; + assert_equals(beacon.timeout, 600); + }, `${beaconType.name}: 'backgroundTimeout' & 'timeout' can be mutated.`); + + test( + () => { + let beacon = new beaconType.type('https://www.google.com'); + + assert_throws_js(TypeError, () => beacon.url = '/'); + assert_throws_js(TypeError, () => beacon.method = 'FOO'); + assert_throws_js(TypeError, () => beacon.pending = false); + }, + `${beaconType.name}: throws TypeError when mutating ` + + `'url', 'method', 'pending'.`); +}
diff --git a/third_party/blink/web_tests/external/wpt/pending_beacon/pending_beacon-deactivate.tentative.window.js b/third_party/blink/web_tests/external/wpt/pending_beacon/pending_beacon-deactivate.tentative.window.js new file mode 100644 index 0000000..4d8fb6be --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pending_beacon/pending_beacon-deactivate.tentative.window.js
@@ -0,0 +1,18 @@ +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.js + +'use strict'; + +const BeaconTypes = [ + {type: PendingPostBeacon, name: 'PendingPostBeacon', expectedMethod: 'POST'}, + {type: PendingGetBeacon, name: 'PendingGetBeacon', expectedMethod: 'GET'}, +]; + +for (const beaconType of BeaconTypes) { + test(() => { + const beacon = new beaconType.type('https://www.google.com'); + assert_true(beacon.pending); + beacon.deactivate(); + assert_false(beacon.pending); + }, `${beaconType.name}: deactivate() changes 'pending' state.`); +}
diff --git a/third_party/blink/web_tests/external/wpt/pending_beacon/pending_beacon-sendnow.tentative.window.js b/third_party/blink/web_tests/external/wpt/pending_beacon/pending_beacon-sendnow.tentative.window.js new file mode 100644 index 0000000..cd3360a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pending_beacon/pending_beacon-sendnow.tentative.window.js
@@ -0,0 +1,46 @@ +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.js +// META: script=/common/utils.js +// META: script=./resources/pending_beacon-helper.js + +'use strict'; + +promise_test(async t => { + const uuid = token(); + const url = generateSetBeaconURL(uuid); + + // Create and send a beacon. + const beacon = new PendingGetBeacon(url); + beacon.sendNow(); + + await expectBeacon(uuid, {count: 1}); +}, 'sendNow() sends a beacon immediately.'); + +promise_test(async t => { + const uuid = token(); + const url = generateSetBeaconURL(uuid); + + // Create and send a beacon. + const beacon = new PendingGetBeacon(url); + beacon.sendNow(); + await expectBeacon(uuid, {count: 1}); + + // Try to send the beacon again, and verify no beacon arrives. + beacon.sendNow(); + await expectBeacon(uuid, {count: 1}); +}, 'sendNow() doesn\'t send the same beacon twice.'); + +promise_test(async t => { + const uuid = token(); + const url = generateSetBeaconURL(uuid); + + // Create and send 1st beacon. + const beacon1 = new PendingGetBeacon(url); + beacon1.sendNow(); + + // Create and send 2st beacon. + const beacon2 = new PendingGetBeacon(url); + beacon2.sendNow(); + + await expectBeacon(uuid, {count: 2}); +}, 'sendNow() sends multiple beacons.');
diff --git a/third_party/blink/web_tests/external/wpt/pending_beacon/pending_beacon-sendondiscard.tentative.window.js b/third_party/blink/web_tests/external/wpt/pending_beacon/pending_beacon-sendondiscard.tentative.window.js new file mode 100644 index 0000000..80d5770 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pending_beacon/pending_beacon-sendondiscard.tentative.window.js
@@ -0,0 +1,50 @@ +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.js +// META: script=/common/utils.js +// META: script=./resources/pending_beacon-helper.js + +'use strict'; + +promise_test(async t => { + const uuid = token(); + + // Create an iframe that contains a document that creates two beacons. + const iframe = document.createElement('iframe'); + iframe.src = + `/pending_beacon/resources/iframe_create_beacon_no_send.html?uuid=${ + uuid}`; + + const iframe_load_promise = + new Promise(resolve => iframe.onload = () => resolve()); + document.body.appendChild(iframe); + await iframe_load_promise; + + // Delete the iframe to trigger beacon sending. + document.body.removeChild(iframe); + + // The iframe should have sent two beacons. + await expectBeacon(uuid, {count: 2}); +}, 'Verify that a discarded document sends its beacons.'); + +promise_test(async t => { + const uuid = token(); + + // Create an iframe that contains a document that creates a beacon, + // then sends it with `sendNow()` + const iframe = document.createElement('iframe'); + iframe.src = + `/pending_beacon/resources/iframe_create_beacon_then_send.html?uuid=${ + uuid}`; + + const iframe_load_promise = + new Promise(resolve => iframe.onload = () => resolve()); + document.body.appendChild(iframe); + await iframe_load_promise; + + // The iframe should have sent one beacon. + await expectBeacon(uuid, {count: 1}); + + // Delete the document and verify no more beacons are sent. + document.body.removeChild(iframe); + await expectBeacon(uuid, {count: 1}); +}, 'Verify that a discarded document does not send an already sent beacon.');
diff --git a/third_party/blink/web_tests/external/wpt/pending_beacon/pending_get_beacon-send.tentative.window.js b/third_party/blink/web_tests/external/wpt/pending_beacon/pending_get_beacon-send.tentative.window.js new file mode 100644 index 0000000..7f52c08 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pending_beacon/pending_get_beacon-send.tentative.window.js
@@ -0,0 +1,40 @@ +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.js +// META: script=/common/utils.js +// META: script=./resources/pending_beacon-helper.js + +'use strict'; + +const baseUrl = `${location.protocol}//${location.host}`; + +parallelPromiseTest(async t => { + const uuid = token(); + const url = generateSetBeaconURL(uuid); + + let beacon = new PendingGetBeacon('/'); + + beacon.setURL(url); + assert_equals(beacon.url, url); + beacon.sendNow(); + + await expectBeacon(uuid, {count: 1}); +}, 'PendingGetBeacon is sent to the updated URL'); + +parallelPromiseTest(async t => { + const uuid = token(); + const url = generateSetBeaconURL(uuid); + + let beacon = new PendingGetBeacon('/0'); + + for (let i = 0; i < 10; i++) { + const transientUrl = `/${i}`; + beacon.setURL(transientUrl); + assert_equals(beacon.url, transientUrl); + } + beacon.setURL(url); + assert_equals(beacon.url, url); + + beacon.sendNow(); + + await expectBeacon(uuid, {count: 1}); +}, 'PendingGetBeacon is sent to the last updated URL');
diff --git a/third_party/blink/web_tests/external/wpt/pending_beacon/pending_post_beacon-sendwithdata.tentative.window.js b/third_party/blink/web_tests/external/wpt/pending_beacon/pending_post_beacon-sendwithdata.tentative.window.js new file mode 100644 index 0000000..1c7c6ca --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pending_beacon/pending_post_beacon-sendwithdata.tentative.window.js
@@ -0,0 +1,24 @@ +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.js +// META: script=/common/utils.js +// META: script=./resources/pending_beacon-helper.js + +'use strict'; + +// Test empty data. +for (const dataType in BeaconDataType) { + postBeaconSendDataTest( + dataType, '', `Sent empty ${dataType}, and server got no data.`, { + expectNoData: true, + }); +} + +// Test small payload. +for (const [dataType, skipCharset] of Object.entries( + BeaconDataTypeToSkipCharset)) { + postBeaconSendDataTest( + dataType, generateSequentialData(0, 1024, skipCharset), + 'Encoded and sent in POST request.'); +} + +// TODO(crbug.com/1293679): Test large payload.
diff --git a/third_party/blink/web_tests/external/wpt/pending_beacon/resources/get_beacon.py b/third_party/blink/web_tests/external/wpt/pending_beacon/resources/get_beacon.py new file mode 100644 index 0000000..32cb9a9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pending_beacon/resources/get_beacon.py
@@ -0,0 +1,30 @@ +"""An HTTP request handler for WPT that handles /get_beacon.py requests.""" + +import json + +_BEACON_ID_KEY = b"uuid" +_BEACON_DATA_PATH = "beacon_data" + + +def main(request, response): + """Retrieves the beacon data keyed by the given uuid from server storage. + + The response content is a JSON string in one of the following formats: + - "{'data': ['abc', null, '123',...]}" + - "{'data': []}" indicates that no data has been set for this uuid. + """ + if _BEACON_ID_KEY not in request.GET: + response.status = 400 + return "Must provide a UUID to store beacon data" + uuid = request.GET.first(_BEACON_ID_KEY) + + with request.server.stash.lock: + body = {'data': []} + data = request.server.stash.take(key=uuid, path=_BEACON_DATA_PATH) + if data: + body['data'] = data + # The stash is read-once/write-once, so it has to be put back after + # reading if `data` is not None. + request.server.stash.put( + key=uuid, value=data, path=_BEACON_DATA_PATH) + return [(b'Content-Type', b'text/plain')], json.dumps(body)
diff --git a/third_party/blink/web_tests/external/wpt/pending_beacon/resources/iframe_create_beacon_no_send.html b/third_party/blink/web_tests/external/wpt/pending_beacon/resources/iframe_create_beacon_no_send.html new file mode 100644 index 0000000..dfe047a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pending_beacon/resources/iframe_create_beacon_no_send.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<body> + <script> + const uuid = window.location.search.split("=")[1] + const url = `/pending_beacon/resources/set_beacon.py?uuid=${uuid}`; + let beacon1 = new PendingGetBeacon(url); + let beacon2 = new PendingGetBeacon(url); + </script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/pending_beacon/resources/iframe_create_beacon_then_send.html b/third_party/blink/web_tests/external/wpt/pending_beacon/resources/iframe_create_beacon_then_send.html new file mode 100644 index 0000000..0fa2ca0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pending_beacon/resources/iframe_create_beacon_then_send.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<body> + <script> + const uuid = window.location.search.split("=")[1] + const url = `/pending_beacon/resources/set_beacon.py?uuid=${uuid}`; + let beacon = new PendingGetBeacon(url); + beacon.sendNow(); + </script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/pending_beacon/resources/pending_beacon-helper.js b/third_party/blink/web_tests/external/wpt/pending_beacon/resources/pending_beacon-helper.js new file mode 100644 index 0000000..ca34e98f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pending_beacon/resources/pending_beacon-helper.js
@@ -0,0 +1,138 @@ +'use strict'; + +function parallelPromiseTest(func, description) { + async_test((t) => { + Promise.resolve(func(t)).then(() => t.done()).catch(t.step_func((e) => { + throw e; + })); + }, description); +} + +/** @enum {string} */ +const BeaconDataType = { + String: 'String', + ArrayBuffer: 'ArrayBuffer', + FormData: 'FormData', + URLSearchParams: 'URLSearchParams', +}; + +/** @enum {string} */ +const BeaconDataTypeToSkipCharset = { + String: '', + ArrayBuffer: '', + FormData: '\n\r', // CRLF characters will be normalized by FormData + URLSearchParams: ';,/?:@&=+$', // reserved URI characters +}; + +const BEACON_PAYLOAD_KEY = 'payload'; + +// Creates beacon data of the given `dataType` from `data`. +// @param {string} data - A string representation of the beacon data. Note that +// it cannot contain UTF-16 surrogates for all `BeaconDataType` except BLOB. +// @param {BeaconDataType} dataType - must be one of `BeaconDataType`. +function makeBeaconData(data, dataType) { + switch (dataType) { + case BeaconDataType.String: + return data; + case BeaconDataType.ArrayBuffer: + return new TextEncoder().encode(data).buffer; + case BeaconDataType.FormData: + const formData = new FormData(); + if (data.length > 0) { + formData.append(BEACON_PAYLOAD_KEY, data); + } + return formData; + case BeaconDataType.URLSearchParams: + if (data.length > 0) { + return new URLSearchParams(`${BEACON_PAYLOAD_KEY}=${data}`); + } + return new URLSearchParams(); + default: + throw Error(`Unsupported beacon dataType: ${dataType}`); + } +} + +// Create a string of `end`-`begin` characters, with characters starting from +// UTF-16 code unit `begin` to `end`-1. +function generateSequentialData(begin, end, skip) { + const codeUnits = Array(end - begin).fill().map((el, i) => i + begin); + if (skip) { + return String.fromCharCode( + ...codeUnits.filter(c => !skip.includes(String.fromCharCode(c)))); + } + return String.fromCharCode(...codeUnits); +} + +function generateSetBeaconURL(uuid) { + return `/pending_beacon/resources/set_beacon.py?uuid=${uuid}`; +} + +async function poll(f, expected) { + const interval = 400; // milliseconds. + while (true) { + const result = await f(); + if (expected(result)) { + return result; + } + await new Promise(resolve => setTimeout(resolve, interval)); + } +} + +// Waits until the `options.count` number of beacon data available from the +// server. Defaults to 1. +// If `options.data` is set, it will be used to compare with the data from the +// response. +async function expectBeacon(uuid, options) { + const expectedCount = options && options.count ? options.count : 1; + + const res = await poll( + async () => { + const res = await fetch( + `/pending_beacon/resources/get_beacon.py?uuid=${uuid}`, + {cache: 'no-store'}); + return await res.json(); + }, + (res) => { + return res.data.length == expectedCount; + }); + if (!options || !options.data) { + return; + } + + const decoder = options && options.percentDecoded ? (s) => { + // application/x-www-form-urlencoded serializer encodes space as '+' + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent + s = s.replace(/\+/g, '%20'); + return decodeURIComponent(s); + } : (s) => s; + + assert_equals( + res.data.length, options.data.length, + `The size of beacon data ${ + res.data.length} from server does not match expected value ${ + options.data.length}.`); + for (let i = 0; i < options.data.length; i++) { + assert_equals( + decoder(res.data[i]), options.data[i], + 'The beacon data does not match expected value.'); + } +} + +function postBeaconSendDataTest(dataType, testData, description, options) { + parallelPromiseTest(async t => { + const expectNoData = options && options.expectNoData; + const uuid = token(); + const url = generateSetBeaconURL(uuid); + const beacon = new PendingPostBeacon(url); + assert_equals(beacon.method, 'POST', 'must be POST to call setData().'); + + beacon.setData(makeBeaconData(testData, dataType)); + beacon.sendNow(); + + const expectedData = expectNoData ? null : testData; + const percentDecoded = + !expectNoData && dataType === BeaconDataType.URLSearchParams; + await expectBeacon( + uuid, {count: 1, data: [expectedData], percentDecoded: percentDecoded}); + }, `PendingPostBeacon(${dataType}): ${description}`); +}
diff --git a/third_party/blink/web_tests/external/wpt/pending_beacon/resources/set_beacon.py b/third_party/blink/web_tests/external/wpt/pending_beacon/resources/set_beacon.py new file mode 100644 index 0000000..41618ad --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pending_beacon/resources/set_beacon.py
@@ -0,0 +1,45 @@ +"""An HTTP request handler for WPT that handles /set_beacon.py requests.""" + +_BEACON_ID_KEY = b"uuid" +_BEACON_DATA_PATH = "beacon_data" +_BEACON_FORM_PAYLOAD_KEY = b"payload" +_BEACON_BODY_PAYLOAD_KEY = "payload=" + + +def main(request, response): + """Stores the given beacon's data keyed by uuid in the server. + + For GET request, this handler assumes no data. + For POST request, this handler extracts data from request body: + - Content-Type=multipart/form-data: data keyed by 'payload'. + - the entire request body. + + Multiple data can be added for the same uuid. + + The data is stored as UTF-8 format. + """ + if _BEACON_ID_KEY not in request.GET: + response.status = 400 + return "Must provide a UUID to store beacon data" + uuid = request.GET.first(_BEACON_ID_KEY) + + data = None + if request.method == u"POST": + if b"multipart/form-data" in request.headers.get(b"Content-Type", b""): + if _BEACON_FORM_PAYLOAD_KEY in request.POST: + data = request.POST.first(_BEACON_FORM_PAYLOAD_KEY).decode( + 'utf-8') + elif request.body: + data = request.body.decode('utf-8') + if data.startswith(_BEACON_BODY_PAYLOAD_KEY): + data = data.split(_BEACON_BODY_PAYLOAD_KEY)[1] + + with request.server.stash.lock: + saved_data = request.server.stash.take(key=uuid, path=_BEACON_DATA_PATH) + if not saved_data: + saved_data = [data] + else: + saved_data.append(data) + request.server.stash.put( + key=uuid, value=saved_data, path=_BEACON_DATA_PATH) + return ((200, "OK"), [], "")
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/imperative-slot-api.html b/third_party/blink/web_tests/external/wpt/shadow-dom/imperative-slot-api.html index b176add..bcf052b 100644 --- a/third_party/blink/web_tests/external/wpt/shadow-dom/imperative-slot-api.html +++ b/third_party/blink/web_tests/external/wpt/shadow-dom/imperative-slot-api.html
@@ -285,4 +285,19 @@ assert_equals(tTree.c2.assignedSlot, tTree.s1); }, 'Removing a node from the document does not break manually assigned slot linkage.'); +test(() => { + const inputValues = [ + ['Attr', document.createAttribute('bar')], + ['Comment', document.createComment('bar')], + ['DocumentFragment', document.createDocumentFragment()], + ['DocumentType', document.implementation.createDocumentType('html', '', '')] + ]; + for (const [label, input] of inputValues) { + assert_throws_js(TypeError, () => { + const slot = document.createElement('slot'); + slot.assign(input); + }, label); + } +}, 'throw TypeError if the passed values are neither Element nor Text'); + </script>
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/styles-3/styles-cancel-editing.js b/third_party/blink/web_tests/http/tests/devtools/elements/styles-3/styles-cancel-editing.js deleted file mode 100644 index a76df61..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/elements/styles-3/styles-cancel-editing.js +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(async function() { - TestRunner.addResult(`Tests that editing is canceled properly after incremental editing.\n`); - await TestRunner.loadLegacyModule('elements'); await TestRunner.loadTestModule('elements_test_runner'); - await TestRunner.showPanel('elements'); - await TestRunner.loadHTML(` - <div id="inspected" style="color: red">Text</div> - <div id="other"></div> - `); - - ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step1); - - var treeElement; - var section; - - async function step1() { - await ElementsTestRunner.dumpSelectedElementStyles(true); - treeElement = ElementsTestRunner.getElementStylePropertyTreeItem('color'); - - treeElement.startEditing(); - treeElement.nameElement.textContent = 'color'; - treeElement.nameElement.dispatchEvent(TestRunner.createKeyEvent('Enter')); - - // Update incrementally, do not commit. - treeElement.valueElement.textContent = 'green'; - await treeElement.kickFreeFlowStyleEditForTest(); - - // Cancel editing. - treeElement.valueElement.firstChild.select(); - treeElement.valueElement.dispatchEvent(TestRunner.createKeyEvent('Escape')); - await ElementsTestRunner.waitForStyleAppliedPromise(); - - ElementsTestRunner.selectNodeWithId('other', step2); - } - - function step2() { - ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step3); - } - - async function step3() { - TestRunner.addResult('After append:'); - await ElementsTestRunner.dumpSelectedElementStyles(true); - TestRunner.completeTest(); - } -})();
diff --git a/third_party/blink/web_tests/pending_beacon/pending_beacon-basic.html b/third_party/blink/web_tests/pending_beacon/pending_beacon-basic.html deleted file mode 100644 index 609e60d1..0000000 --- a/third_party/blink/web_tests/pending_beacon/pending_beacon-basic.html +++ /dev/null
@@ -1,71 +0,0 @@ -<!DOCTYPE html> -<head> -<meta charset="utf-8"> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -</head> -<body> -<script> - test(() => { - assert_throws_js(TypeError, () => new PendingBeacon('/')); - }, `PendingBeacon cannot be constructed directly.`); - - const BeaconTypes = [ - {type: PendingPostBeacon, name: "PendingPostBeacon", expectedMethod: "POST"}, - {type: PendingGetBeacon, name: "PendingGetBeacon", expectedMethod: "GET"}, - ]; - - for (const beaconType of BeaconTypes) { - test(() => { - assert_throws_js(TypeError, () => new beaconType.type()); - }, `${beaconType.name}: constructor throws TypeError if no url is provided`); - - test(() => { - const beacon = new beaconType.type("/"); - assert_equals(beacon.url, "/"); - assert_equals(beacon.method, beaconType.expectedMethod); - assert_equals(beacon.backgroundTimeout, -1); - assert_equals(beacon.timeout, -1); - assert_true(beacon.pending); - }, `${beaconType.name}: constructor sets default properties when not provided.`); - - test(() => { - const beacon = new beaconType.type("https://www.google.com", - {backgroundTimeout: 200, timeout: 100}); - assert_equals(beacon.url, "https://www.google.com"); - assert_equals(beacon.method, beaconType.expectedMethod); - assert_equals(beacon.backgroundTimeout, 200); - assert_equals(beacon.timeout, 100); - assert_true(beacon.pending); - }, `${beaconType.name}: constructor can set properties.`); - - test(() => { - let beacon = new beaconType.type("https://www.google.com", - {method: "GET", backgroundTimeout: 200, timeout: 100}); - - beacon.backgroundTimeout = 400; - assert_equals(beacon.backgroundTimeout, 400); - - beacon.timeout = 600; - assert_equals(beacon.timeout, 600); - - }, `${beaconType.name}: backgroundTimeout & timeout can be mutated.`); - - test(() => { - let beacon = new beaconType.type("https://www.google.com"); - - beacon.url = "/"; - assert_equals(beacon.url, "https://www.google.com"); - - beacon.method = "FOO"; - assert_equals(beacon.method, beaconType.expectedMethod); - - assert_true(beacon.pending); - beacon.pending = false; - assert_true(beacon.pending); - }, `${beaconType.name}: url & method & pending cannot be mutated.`); - } - -</script> -</body> -</html>
diff --git a/third_party/blink/web_tests/pending_beacon/pending_beacon-deactivate.html b/third_party/blink/web_tests/pending_beacon/pending_beacon-deactivate.html deleted file mode 100644 index 44c9ce5..0000000 --- a/third_party/blink/web_tests/pending_beacon/pending_beacon-deactivate.html +++ /dev/null
@@ -1,24 +0,0 @@ -<!DOCTYPE html> -<head> -<meta charset="utf-8"> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -</head> -<body> -<script> - const BeaconTypes = [ - {type: PendingPostBeacon, name: "PendingPostBeacon", expectedMethod: "POST"}, - {type: PendingGetBeacon, name: "PendingGetBeacon", expectedMethod: "GET"}, - ]; - - for (const beaconType of BeaconTypes) { - test(() => { - const beacon = new beaconType.type('https://www.google.com'); - assert_true(beacon.pending); - beacon.deactivate(); - assert_false(beacon.pending); - }, `${beaconType.name}: Tests deactivate()`); - } -</script> -</body> -</html>
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/shadow-dom/imperative-slot-api-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/shadow-dom/imperative-slot-api-expected.txt index 32b0dc9..0197ea3 100644 --- a/third_party/blink/web_tests/platform/generic/external/wpt/shadow-dom/imperative-slot-api-expected.txt +++ b/third_party/blink/web_tests/platform/generic/external/wpt/shadow-dom/imperative-slot-api-expected.txt
@@ -14,5 +14,6 @@ PASS Removing a slot from DOM resets its slottable's slot assignment. PASS Nodes can be assigned even if slots or nodes aren't in the same tree. PASS Removing a node from the document does not break manually assigned slot linkage. +PASS throw TypeError if the passed values are neither Element nor Text Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/devtools/elements/styles-3/styles-cancel-editing-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/devtools/elements/styles-3/styles-cancel-editing-expected.txt deleted file mode 100644 index 9ecb2029..0000000 --- a/third_party/blink/web_tests/platform/generic/http/tests/devtools/elements/styles-3/styles-cancel-editing-expected.txt +++ /dev/null
@@ -1,20 +0,0 @@ -Tests that editing is canceled properly after incremental editing. - -[expanded] -element.style { () - color: red; - -[expanded] -div { (user agent stylesheet) - display: block; - -After append: -[expanded] -element.style { () - color: red; - -[expanded] -div { (user agent stylesheet) - display: block; - -
diff --git a/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-apply-to-cross-site-only/wpt_internal/async-script-scheduling/execution-order.sub-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-apply-to-cross-site-only/wpt_internal/async-script-scheduling/execution-order.sub-expected.txt new file mode 100644 index 0000000..6284456 --- /dev/null +++ b/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-apply-to-cross-site-only/wpt_internal/async-script-scheduling/execution-order.sub-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Async Script Execution Order Uncaught Error: assert_equals: expected "async_preload;async_blocking_render;async;async;inline1;external;inline2;defer;DOMContentLoaded" but got "async_preload;async_blocking_render;async;inline1;external;inline2;defer;DOMContentLoaded;async" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-finished-parsing/wpt_internal/async-script-scheduling/execution-order-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-finished-parsing/wpt_internal/async-script-scheduling/execution-order-expected.txt deleted file mode 100644 index 163d065b..0000000 --- a/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-finished-parsing/wpt_internal/async-script-scheduling/execution-order-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Async Script Execution Order Uncaught Error: assert_equals: expected "async_preload;async_blocking_render;async;inline1;external;inline2;defer;DOMContentLoaded" but got "async_preload;async_blocking_render;inline1;external;inline2;defer;DOMContentLoaded;async" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-finished-parsing/wpt_internal/async-script-scheduling/execution-order.sub-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-finished-parsing/wpt_internal/async-script-scheduling/execution-order.sub-expected.txt new file mode 100644 index 0000000..16feb391 --- /dev/null +++ b/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-finished-parsing/wpt_internal/async-script-scheduling/execution-order.sub-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Async Script Execution Order Uncaught Error: assert_equals: expected "async_preload;async_blocking_render;async;async;inline1;external;inline2;defer;DOMContentLoaded" but got "async_preload;async_blocking_render;inline1;external;inline2;defer;DOMContentLoaded;async;async" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-first-paint-or-finished-parsing/wpt_internal/async-script-scheduling/execution-order-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-first-paint-or-finished-parsing/wpt_internal/async-script-scheduling/execution-order-expected.txt deleted file mode 100644 index 163d065b..0000000 --- a/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-first-paint-or-finished-parsing/wpt_internal/async-script-scheduling/execution-order-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Async Script Execution Order Uncaught Error: assert_equals: expected "async_preload;async_blocking_render;async;inline1;external;inline2;defer;DOMContentLoaded" but got "async_preload;async_blocking_render;inline1;external;inline2;defer;DOMContentLoaded;async" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-first-paint-or-finished-parsing/wpt_internal/async-script-scheduling/execution-order.sub-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-first-paint-or-finished-parsing/wpt_internal/async-script-scheduling/execution-order.sub-expected.txt new file mode 100644 index 0000000..16feb391 --- /dev/null +++ b/third_party/blink/web_tests/platform/generic/virtual/async-script-scheduling-first-paint-or-finished-parsing/wpt_internal/async-script-scheduling/execution-order.sub-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Async Script Execution Order Uncaught Error: assert_equals: expected "async_preload;async_blocking_render;async;async;inline1;external;inline2;defer;DOMContentLoaded" but got "async_preload;async_blocking_render;inline1;external;inline2;defer;DOMContentLoaded;async;async" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt index c3bcb2bc..394dac4 100644 --- a/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt
@@ -6409,6 +6409,26 @@ method retry method toJSON setter onpayerdetailchange +interface PendingBeacon + attribute @@toStringTag + getter backgroundTimeout + getter method + getter pending + getter timeout + getter url + method constructor + method deactivate + method sendNow + setter backgroundTimeout + setter timeout +interface PendingGetBeacon : PendingBeacon + attribute @@toStringTag + method constructor + method setURL +interface PendingPostBeacon : PendingBeacon + attribute @@toStringTag + method constructor + method setData interface Performance : EventTarget attribute @@toStringTag getter eventCounts
diff --git a/third_party/blink/web_tests/virtual/async-script-scheduling-apply-to-cross-site-only/README.md b/third_party/blink/web_tests/virtual/async-script-scheduling-apply-to-cross-site-only/README.md new file mode 100644 index 0000000..fe8a325 --- /dev/null +++ b/third_party/blink/web_tests/virtual/async-script-scheduling-apply-to-cross-site-only/README.md
@@ -0,0 +1,5 @@ +# DelayAsyncScriptExecution +This suite runs the tests in wpt_internal/async-script-scheduling/ with +`--enable-features=DelayAsyncScriptExecution:cross_site_only/true`. + +See crbug.com/1340837.
diff --git a/third_party/blink/web_tests/virtual/pending-beacon/README.md b/third_party/blink/web_tests/virtual/pending-beacon/README.md new file mode 100644 index 0000000..4850c08 --- /dev/null +++ b/third_party/blink/web_tests/virtual/pending-beacon/README.md
@@ -0,0 +1,18 @@ +# PendingBeacon Virtual Tests + +This folder contains virtual test suites for the PendingBeacon feature. +The suite runs `web_tests/external/wpt/pending_beacon/` with `--enable-features=PendingBeaconAPI`. + +To manually run the suites, use the following command: + +To run all tests: + +```bash +third_party/blink/tools/run_web_tests.py -t Default virtual/pending-beacon/ +``` + +To run single test: + +```bash +third_party/blink/tools/run_web_tests.py -t Default virtual/pending-beacon/external/wpt/pending_beacon/pending_beacon-basic.tentative.window.html +```
diff --git a/third_party/blink/web_tests/wpt_internal/async-script-scheduling/execution-order.html b/third_party/blink/web_tests/wpt_internal/async-script-scheduling/execution-order.html deleted file mode 100644 index 94be7fb09..0000000 --- a/third_party/blink/web_tests/wpt_internal/async-script-scheduling/execution-order.html +++ /dev/null
@@ -1,46 +0,0 @@ -<!doctype html> -<head> - <title>Async Script Execution Order</title> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - <link rel="preload" as="script" href="resources/script.js?4&preload"> - <script async blocking=render src="resources/script.js?1&pipe=trickle(d1)" - data-label="async_blocking_render"></script> -</head> -<body> - <!-- Note: This test serves mainly to document the current scheduling behavior - of async scripts with respect to other scripts and events in the loading - pipeline. It does not represent the "ideal" or "desired" behavior, so - changing it is probably fine. --> - <script> - setup({single_test: true}) - - const logs = []; - function logScript(msg) { - logs.push(msg); - } - window.onload = e => { - const actualOrder = logs.join(";"); - const expectedOrder = "async_preload;async_blocking_render;async;inline1;external;inline2;defer;DOMContentLoaded"; - assert_equals(actualOrder, expectedOrder); - done(); - }; - document.addEventListener('DOMContentLoaded', e => { logScript('DOMContentLoaded'); }); - </script> - - <script defer src="resources/script.js?2" data-label="defer"></script> - <script async src="resources/script.js?3&pipe=trickle(d2)" data-label="async"></script> - <script async src="resources/script.js?4&preload" data-label="async_preload"></script> - <link rel=stylesheet href=resources/main.css?pipe=trickle(d3)> - <script> - logScript('inline1'); - assert_equals('rgb(255, 255, 0)', getComputedStyle(document.body)['backgroundColor']); - </script> - <script src="resources/script.js?5&pipe=trickle(d1)" data-label="external"></script> - <script> - logScript('inline2'); - </script> - <h1> - This is the first (contentful) paint. - </h1> -</body>
diff --git a/third_party/blink/web_tests/wpt_internal/async-script-scheduling/execution-order.sub.html b/third_party/blink/web_tests/wpt_internal/async-script-scheduling/execution-order.sub.html new file mode 100644 index 0000000..c630de3 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/async-script-scheduling/execution-order.sub.html
@@ -0,0 +1,51 @@ +<!doctype html> +<head> + <title>Async Script Execution Order</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <link rel="preload" as="script" href="resources/script.sub.js?label=async_preload"> + <script async blocking=render src="resources/script.sub.js?pipe=trickle(d1)&label=async_blocking_render"></script> +</head> +<body> + <!-- Note: This test serves mainly to document the current scheduling behavior + of async scripts with respect to other scripts and events in the loading + pipeline. It does not represent the "ideal" or "desired" behavior, so + changing it is probably fine. --> + <script> + setup({single_test: true}) + + const logs = []; + function logScript(msg) { + logs.push(msg); + } + window.onload = e => { + const actualOrder = logs.join(";"); + const expectedOrder = "async_preload;async_blocking_render;async;async;inline1;external;inline2;defer;DOMContentLoaded"; + assert_equals(actualOrder, expectedOrder); + done(); + }; + document.addEventListener('DOMContentLoaded', e => { logScript('DOMContentLoaded'); }); + </script> + + <script defer src="resources/script.sub.js?label=defer"></script> + <!-- Note: The following two async scripts are named as + "label=async". These are intentionally named with the same name + because the ordering of these two scripts are not guaranteed even + if different trickle values are specified. --> + <script async src="resources/script.sub.js?pipe=trickle(d2)&label=async"></script> + <!-- cross site async script --> + <script async src="http://{{hosts[alt][]}}:{{ports[http][0]}}/wpt_internal/async-script-scheduling/resources/script.sub.js?pipe=trickle(d2)&label=async"></script> + <script async src="resources/script.sub.js?label=async_preload"></script> + <link rel=stylesheet href=resources/main.css?pipe=trickle(d3)> + <script> + logScript('inline1'); + assert_equals('rgb(255, 255, 0)', getComputedStyle(document.body)['backgroundColor']); + </script> + <script src="resources/script.sub.js?pipe=trickle(d1)&label=external"></script> + <script> + logScript('inline2'); + </script> + <h1> + This is the first (contentful) paint. + </h1> +</body>
diff --git a/third_party/blink/web_tests/wpt_internal/async-script-scheduling/resources/script.js b/third_party/blink/web_tests/wpt_internal/async-script-scheduling/resources/script.js deleted file mode 100644 index d34c5f52..0000000 --- a/third_party/blink/web_tests/wpt_internal/async-script-scheduling/resources/script.js +++ /dev/null
@@ -1 +0,0 @@ -logScript(document.currentScript.getAttribute("data-label"))
diff --git a/third_party/blink/web_tests/wpt_internal/async-script-scheduling/resources/script.sub.js b/third_party/blink/web_tests/wpt_internal/async-script-scheduling/resources/script.sub.js new file mode 100644 index 0000000..5695993f --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/async-script-scheduling/resources/script.sub.js
@@ -0,0 +1 @@ +logScript("{{GET[label]}}");
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendnow.html b/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendnow.html deleted file mode 100644 index 39cf255..0000000 --- a/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendnow.html +++ /dev/null
@@ -1,53 +0,0 @@ -<!DOCTYPE html> -<head> -<meta charset="utf-8"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/common/utils.js"></script> -<script src="./resources/pending_beacon-helper.js"></script> -</head> -<body> -<script> - const baseUrl = `${location.protocol}//${location.host}`; - promise_test(async t => { - const uuid = token(); - const url = `${baseUrl}/wpt_internal/pending_beacon/resources/set_beacon_count.py?uuid=${uuid}`; - - // Create and send a beacon. - const beacon = new PendingGetBeacon(url); - beacon.sendNow(); - - await expectBeaconCount(uuid, 1); - }, "sendNow() sends a beacon immediately."); - - promise_test(async t => { - const uuid = token(); - const url = `${baseUrl}/wpt_internal/pending_beacon/resources/set_beacon_count.py?uuid=${uuid}`; - - // Create and send a beacon. - const beacon = new PendingGetBeacon(url); - beacon.sendNow(); - await expectBeaconCount(uuid, 1); - - // Try to send the beacon again, and verify no beacon arrives. - beacon.sendNow(); - await expectBeaconCount(uuid, 1); - }, "sendNow() doesn't send the same beacon twice."); - - promise_test(async t => { - const uuid = token(); - const url = `${baseUrl}/wpt_internal/pending_beacon/resources/set_beacon_count.py?uuid=${uuid}`; - - // Create and send 1st beacon. - const beacon1 = new PendingGetBeacon(url); - beacon1.sendNow(); - - // Create and send 2st beacon. - const beacon2 = new PendingGetBeacon(url); - beacon2.sendNow(); - - await expectBeaconCount(uuid, 2); - }, "sendNow() sends multiple beacons."); -</script> -</body> -</html>
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendondiscard.html b/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendondiscard.html deleted file mode 100644 index 198df00..0000000 --- a/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_beacon-sendondiscard.html +++ /dev/null
@@ -1,52 +0,0 @@ -<!DOCTYPE html> -<head> -<meta charset="utf-8"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/common/utils.js"></script> -<script src="./resources/pending_beacon-helper.js"></script> -</head> -<body> -<script> - promise_test(async t => { - const uuid = token(); - - // Create an iframe that contains a document that creates two beacons. - const iframe = document.createElement("iframe"); - iframe.src = `resources/iframe_create_beacon_no_send.html?uuid=${uuid}`; - - const iframe_load_promise = new Promise( - resolve => iframe.onload = () => resolve()); - document.body.appendChild(iframe); - await iframe_load_promise; - - // Delete the iframe to trigger beacon sending. - document.body.removeChild(iframe); - - // The iframe should have sent two beacons. - await expectBeaconCount(uuid, 2); - }, "Verify that a discarded document sends its beacons."); - - promise_test(async t => { - const uuid = token(); - - // Create an iframe that contains a document that creates a beacon, - // then sends it with `sendNow()` - const iframe = document.createElement("iframe"); - iframe.src = `resources/iframe_create_beacon_then_send.html?uuid=${uuid}`; - - const iframe_load_promise = new Promise( - resolve => iframe.onload = () => resolve()); - document.body.appendChild(iframe); - await iframe_load_promise; - - // The iframe should have sent one beacon. - await expectBeaconCount(uuid, 1); - - // Delete the document and verify no more beacons are sent. - document.body.removeChild(iframe); - await expectBeaconCount(uuid, 1); - }, "Verify that a discarded document does not send an already sent beacon."); -</script> -</body> -</html>
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_get_beacon-send.html b/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_get_beacon-send.html deleted file mode 100644 index 552f068..0000000 --- a/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_get_beacon-send.html +++ /dev/null
@@ -1,46 +0,0 @@ -<!DOCTYPE html> -<head> -<meta charset="utf-8"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/common/utils.js"></script> -<script src="./resources/pending_beacon-helper.js"></script> -</head> -<body> -<script> - const baseUrl = `${location.protocol}//${location.host}`; - - parallelPromiseTest(async t => { - const uuid = token(); - const url = `${baseUrl}/wpt_internal/pending_beacon/resources/set_beacon_count.py?uuid=${uuid}`; - - let beacon = new PendingGetBeacon('/'); - - beacon.setURL(url); - assert_equals(beacon.url, url); - beacon.sendNow(); - - await expectBeaconCount(uuid, 1); - }, "PendingGetBeacon is sent to the updated URL"); - - parallelPromiseTest(async t => { - const uuid = token(); - const url = `${baseUrl}/wpt_internal/pending_beacon/resources/set_beacon_count.py?uuid=${uuid}`; - - let beacon = new PendingGetBeacon('/0'); - - for (let i = 0; i < 10; i++) { - const transientUrl = `/${i}`; - beacon.setURL(transientUrl); - assert_equals(beacon.url, transientUrl); - } - beacon.setURL(url); - assert_equals(beacon.url, url); - - beacon.sendNow(); - - await expectBeaconCount(uuid, 1); - }, "PendingGetBeacon is sent to the last updated URL"); -</script> -</body> -</html>
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_post_beacon-sendwithdata.html b/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_post_beacon-sendwithdata.html deleted file mode 100644 index af9bc6d0..0000000 --- a/third_party/blink/web_tests/wpt_internal/pending_beacon/pending_post_beacon-sendwithdata.html +++ /dev/null
@@ -1,37 +0,0 @@ -<!DOCTYPE html> -<head> -<meta charset="utf-8"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/common/utils.js"></script> -<script src="./resources/pending_beacon-helper.js"></script> -</head> -<body> -<script> - // Test empty data. - postBeaconSendDataTest(BeaconDataType.String, "", - /*expectEmpty=*/true, "Empty data is not sent."); - postBeaconSendDataTest(BeaconDataType.ArrayBuffer, "", - /*expectEmpty=*/true, "Empty data is not sent."); - postBeaconSendDataTest(BeaconDataType.FormData, "", - /*expectEmpty=*/false, "Empty form payload is sent."); - postBeaconSendDataTest(BeaconDataType.URLSearchParams, "testkey=", - /*expectEmpty=*/false, "Empty query is sent."); - - // Test small payload. - postBeaconSendDataTest(BeaconDataType.String, generateSequentialData(0, 1024), - /*expectEmpty=*/false, "Encoded and sent in POST request."); - postBeaconSendDataTest(BeaconDataType.ArrayBuffer, generateSequentialData(0, 1024), - /*expectEmpty=*/false, "Encoded and sent in POST request."); - // Skip CRLF chracters which will be normalzied by FormData. - postBeaconSendDataTest(BeaconDataType.FormData, generateSequentialData(0, 1024, "\n\r"), - /*expectEmpty=*/false, "Encoded and sent in POST request."); - // Skip reserved URI characters. - postBeaconSendDataTest(BeaconDataType.URLSearchParams, - "testkey="+generateSequentialData(0, 1024, ";,/?:@&=+$"), - /*expectEmpty=*/false, "Encoded and sent in POST request."); - - // TODO(crbug.com/1293679): Test large payload. -</script> -</body> -</html>
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/get_beacon_count.py b/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/get_beacon_count.py deleted file mode 100644 index d6b3f4a..0000000 --- a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/get_beacon_count.py +++ /dev/null
@@ -1,15 +0,0 @@ -# Gets the count of beacons the server has seen. -def main(request, response): - if b"uuid" in request.GET: - uuid = request.GET.first(b"uuid") - else: - response.status = 400 - return "Must provide a UUID for beacon count handlers" - - count = request.server.stash.take(key=uuid, path="beaconcount") - if count is None: - count = 0 - # The stash is read-once/write-once, so after reading the count, it has to be - # put back. - request.server.stash.put(key=uuid, value=count, path="beaconcount") - return [(b"Content-Type", b"text/plain")], str(count)
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/get_beacon_data.py b/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/get_beacon_data.py deleted file mode 100644 index 6faa28fb..0000000 --- a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/get_beacon_data.py +++ /dev/null
@@ -1,11 +0,0 @@ -def main(request, response): - """Get the beacon data keyed by uuid.""" - if b'uuid' not in request.GET: - response.status = 400 - return 'Must provide a UUID to look up beacon data' - uuid = request.GET.first(b'uuid') - - with request.server.stash.lock: - data = request.server.stash.take(key=uuid, path='beacondata') - # data is already of type string. - return [(b'Content-Type', b'text/plain')], data
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/iframe_create_beacon_no_send.html b/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/iframe_create_beacon_no_send.html deleted file mode 100644 index 5e1617c..0000000 --- a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/iframe_create_beacon_no_send.html +++ /dev/null
@@ -1,10 +0,0 @@ -<!DOCTYPE html> -<body> - <script> - const uuid = window.location.search.split("=")[1] - const baseUrl = `${location.protocol}//${location.host}`; - const beaconUrl = `${baseUrl}/wpt_internal/pending_beacon/resources/set_beacon_count.py?uuid=${uuid}`; - let beacon1 = new PendingGetBeacon(beaconUrl); - let beacon2 = new PendingGetBeacon(beaconUrl); - </script> -</body>
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/iframe_create_beacon_then_send.html b/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/iframe_create_beacon_then_send.html deleted file mode 100644 index aee4325..0000000 --- a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/iframe_create_beacon_then_send.html +++ /dev/null
@@ -1,10 +0,0 @@ -<!DOCTYPE html> -<body> - <script> - const uuid = window.location.search.split("=")[1] - const baseUrl = `${location.protocol}//${location.host}`; - const beaconUrl = `${baseUrl}/wpt_internal/pending_beacon/resources/set_beacon_count.py?uuid=${uuid}`; - let beacon = new PendingGetBeacon(beaconUrl); - beacon.sendNow(); - </script> -</body>
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/pending_beacon-helper.js b/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/pending_beacon-helper.js deleted file mode 100644 index 9958d3f..0000000 --- a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/pending_beacon-helper.js +++ /dev/null
@@ -1,106 +0,0 @@ -'use strict'; - -function parallelPromiseTest(func, description) { - async_test((t) => { - Promise.resolve(func(t)).then(() => t.done()).catch(t.step_func((e) => { - throw e; - })); - }, description); -} - -/** @enum {string} */ -const BeaconDataType = { - String: 'String', - ArrayBuffer: 'ArrayBuffer', - FormData: 'FormData', - URLSearchParams: 'URLSearchParams', -}; - -// Creates beacon data of the given `dataType` from `data`. -// @param {string} data - A string representation of the beacon data. Note that -// it cannot contain UTF-16 surrogates for all `BeaconDataType` except BLOB. -// @param {BeaconDataType} dataType - must be one of `BeaconDataType`. -function makeBeaconData(data, dataType) { - switch (dataType) { - case BeaconDataType.String: - return data; - case BeaconDataType.ArrayBuffer: - return new TextEncoder().encode(data).buffer; - case BeaconDataType.FormData: - const formData = new FormData(); - formData.append('payload', data); - return formData; - case BeaconDataType.URLSearchParams: - return new URLSearchParams(data); - default: - throw Error(`Unsupported beacon dataType: ${dataType}`); - } -} - -// Create a string of `end`-`begin` characters, with characters starting from -// UTF-16 code unit `begin` to `end`-1. -function generateSequentialData(begin, end, skip) { - const codeUnits = Array(end - begin).fill().map((el, i) => i + begin); - if (skip) { - return String.fromCharCode( - ...codeUnits.filter(c => !skip.includes(String.fromCharCode(c)))); - } - return String.fromCharCode(...codeUnits); -} - -function wait(ms) { - return new Promise(resolve => step_timeout(resolve, ms)); -} - -async function poll(f, expected) { - const interval = 400; // milliseconds. - while (true) { - const result = await f(); - if (result === expected) { - return result; - } - await new Promise(resolve => setTimeout(resolve, interval)); - } -} - -async function expectBeaconCount(uuid, expected) { - poll(async () => { - const res = await fetch( - `resources/get_beacon_count.py?uuid=${uuid}`, {cache: 'no-store'}); - return await res.json(); - }, expected); -} - -async function expectBeaconData(uuid, expected, options) { - poll(async () => { - const res = await fetch( - `resources/get_beacon_count.py?uuid=${uuid}`, {cache: 'no-store'}); - let data = await res.text(); - if (options && options.percentDecoded) { - // application/x-www-form-urlencoded serializer encodes space as '+' - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent - data = data.replace(/\+/g, '%20'); - return decodeURIComponent(data); - } - return data; - }, expected); -} - -function postBeaconSendDataTest(dataType, testData, expectEmpty, description) { - parallelPromiseTest(async t => { - const uuid = token(); - const baseUrl = `${location.protocol}//${location.host}`; - const url = `${ - baseUrl}/wpt_internal/pending_beacon/resources/set_beacon_data.py?uuid=${ - uuid}`; - let beacon = new PendingPostBeacon(url); - assert_equals(beacon.method, 'POST'); - - beacon.setData(makeBeaconData(testData, dataType)); - beacon.sendNow(); - - const expected = expectEmpty ? '<NO-DATA>' : testData; - const percentDecoded = dataType === BeaconDataType.URLSearchParams; - await expectBeaconData(uuid, expected, {percentDecoded: percentDecoded}); - }, `Beacon data of type "${dataType}": ${description}`); -}
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/set_beacon_count.py b/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/set_beacon_count.py deleted file mode 100644 index c40bc8c..0000000 --- a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/set_beacon_count.py +++ /dev/null
@@ -1,13 +0,0 @@ -# Increment the count of beacons the server has seen. -def main(request, response): - if b"uuid" in request.GET: - uuid = request.GET.first(b"uuid") - else: - response.status = 400 - return "Must provide a UUID for beacon count handlers" - count = request.server.stash.take(key=uuid, path="beaconcount") - if count is None: - count = 0 - count += 1 - request.server.stash.put(key=uuid, value=count, path="beaconcount") - return ((200, "OK"), [], "")
diff --git a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/set_beacon_data.py b/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/set_beacon_data.py deleted file mode 100644 index 7c5bcbca..0000000 --- a/third_party/blink/web_tests/wpt_internal/pending_beacon/resources/set_beacon_data.py +++ /dev/null
@@ -1,23 +0,0 @@ -import re - - -def main(request, response): - """Store the given beacon's data keyed by uuid in the server. - - For GET request, this handler assumes everything comes after 'data=' is part - of the data query. - """ - if b'uuid' not in request.GET: - response.status = 400 - return 'Must provide a UUID to store beacon data' - uuid = request.GET.first(b'uuid') - if b'multipart/form-data' in request.headers.get(b'Content-Type', b''): - data = request.POST.first(b'payload') - elif request.body: - data = request.body - else: - data = '<NO-DATA>' - - with request.server.stash.lock: - request.server.stash.put(key=uuid, value=data, path='beacondata') - return ((200, "OK"), [], "")
diff --git a/third_party/ipcz/src/BUILD.gn b/third_party/ipcz/src/BUILD.gn index f689d5b..4fa9f4fd 100644 --- a/third_party/ipcz/src/BUILD.gn +++ b/third_party/ipcz/src/BUILD.gn
@@ -381,6 +381,7 @@ "ipcz/route_edge_test.cc", "ipcz/router_link_test.cc", "ipcz/sequenced_queue_test.cc", + "merge_portals_test.cc", "queueing_test.cc", "reference_drivers/sync_reference_driver_test.cc", "remote_portal_test.cc",
diff --git a/third_party/ipcz/src/api.cc b/third_party/ipcz/src/api.cc index ff582aca..56ef2bf 100644 --- a/third_party/ipcz/src/api.cc +++ b/third_party/ipcz/src/api.cc
@@ -109,7 +109,22 @@ IpczHandle portal1, uint32_t flags, const void* options) { - return IPCZ_RESULT_UNIMPLEMENTED; + ipcz::Portal* first = ipcz::Portal::FromHandle(portal0); + ipcz::Portal* second = ipcz::Portal::FromHandle(portal1); + if (!first || !second) { + return IPCZ_RESULT_INVALID_ARGUMENT; + } + + ipcz::Ref<ipcz::Portal> one(ipcz::RefCounted::kAdoptExistingRef, first); + ipcz::Ref<ipcz::Portal> two(ipcz::RefCounted::kAdoptExistingRef, second); + IpczResult result = one->Merge(*two); + if (result != IPCZ_RESULT_OK) { + one.release(); + two.release(); + return result; + } + + return IPCZ_RESULT_OK; } IpczResult QueryPortalStatus(IpczHandle portal_handle,
diff --git a/third_party/ipcz/src/api_test.cc b/third_party/ipcz/src/api_test.cc index ce83991..84955ae6 100644 --- a/third_party/ipcz/src/api_test.cc +++ b/third_party/ipcz/src/api_test.cc
@@ -18,10 +18,6 @@ TEST_F(APITest, Unimplemented) { EXPECT_EQ(IPCZ_RESULT_UNIMPLEMENTED, - ipcz().MergePortals(IPCZ_INVALID_HANDLE, IPCZ_INVALID_HANDLE, - IPCZ_NO_FLAGS, nullptr)); - - EXPECT_EQ(IPCZ_RESULT_UNIMPLEMENTED, ipcz().BeginPut(IPCZ_INVALID_HANDLE, IPCZ_NO_FLAGS, nullptr, nullptr, nullptr)); EXPECT_EQ(IPCZ_RESULT_UNIMPLEMENTED, @@ -188,6 +184,62 @@ CloseAll({a, node}); } +TEST_F(APITest, MergePortalsFailure) { + const IpczHandle node = CreateNode(kDefaultDriver); + auto [a, b] = OpenPortals(node); + + // Invalid portal handles. + EXPECT_EQ( + IPCZ_RESULT_INVALID_ARGUMENT, + ipcz().MergePortals(a, IPCZ_INVALID_HANDLE, IPCZ_NO_FLAGS, nullptr)); + EXPECT_EQ( + IPCZ_RESULT_INVALID_ARGUMENT, + ipcz().MergePortals(IPCZ_INVALID_HANDLE, a, IPCZ_NO_FLAGS, nullptr)); + EXPECT_EQ(IPCZ_RESULT_INVALID_ARGUMENT, + ipcz().MergePortals(IPCZ_INVALID_HANDLE, IPCZ_INVALID_HANDLE, + IPCZ_NO_FLAGS, nullptr)); + + // Can't merge into own peer. + EXPECT_EQ(IPCZ_RESULT_INVALID_ARGUMENT, + ipcz().MergePortals(a, b, IPCZ_NO_FLAGS, nullptr)); + + // Can't merge into self. + EXPECT_EQ(IPCZ_RESULT_INVALID_ARGUMENT, + ipcz().MergePortals(a, a, IPCZ_NO_FLAGS, nullptr)); + + auto [c, d] = OpenPortals(node); + + // Can't merge a portal that's had parcels put into it. + EXPECT_EQ(IPCZ_RESULT_OK, Put(c, "!")); + EXPECT_EQ(IPCZ_RESULT_FAILED_PRECONDITION, + ipcz().MergePortals(a, c, IPCZ_NO_FLAGS, nullptr)); + + // Can't merge a portal that's had parcels retrieved from it. + std::string message; + EXPECT_EQ(IPCZ_RESULT_OK, Get(d, &message)); + EXPECT_EQ(IPCZ_RESULT_FAILED_PRECONDITION, + ipcz().MergePortals(a, d, IPCZ_NO_FLAGS, nullptr)); + + CloseAll({a, b, c, d, node}); +} + +TEST_F(APITest, MergePortals) { + const IpczHandle node = CreateNode(kDefaultDriver); + auto [a, b] = OpenPortals(node); + auto [c, d] = OpenPortals(node); + + EXPECT_EQ(IPCZ_RESULT_OK, Put(a, "!")); + EXPECT_EQ(IPCZ_RESULT_OK, ipcz().MergePortals(b, c, IPCZ_NO_FLAGS, nullptr)); + + // The message from `a` should be routed to `d`, since `b` and `c` have been + // merged. + std::string message; + EXPECT_EQ(IPCZ_RESULT_OK, Get(d, &message)); + EXPECT_EQ("!", message); + + CloseAll({a, d, node}); +} + TEST_F(APITest, PutGet) { const IpczHandle node = CreateNode(kDefaultDriver); auto [a, b] = OpenPortals(node);
diff --git a/third_party/ipcz/src/ipcz/local_router_link.cc b/third_party/ipcz/src/ipcz/local_router_link.cc index d5a794f..e675a57 100644 --- a/third_party/ipcz/src/ipcz/local_router_link.cc +++ b/third_party/ipcz/src/ipcz/local_router_link.cc
@@ -110,7 +110,12 @@ void LocalRouterLink::AcceptParcel(Parcel& parcel) { if (Ref<Router> receiver = state_->GetRouter(side_.opposite())) { - receiver->AcceptInboundParcel(parcel); + if (state_->type() == LinkType::kCentral) { + receiver->AcceptInboundParcel(parcel); + } else { + ABSL_ASSERT(state_->type() == LinkType::kBridge); + receiver->AcceptOutboundParcel(parcel); + } } }
diff --git a/third_party/ipcz/src/ipcz/portal.cc b/third_party/ipcz/src/ipcz/portal.cc index affabb3..cb494aa1 100644 --- a/third_party/ipcz/src/ipcz/portal.cc +++ b/third_party/ipcz/src/ipcz/portal.cc
@@ -68,6 +68,10 @@ return IPCZ_RESULT_OK; } +IpczResult Portal::Merge(Portal& other) { + return router_->MergeRoute(other.router()); +} + IpczResult Portal::Put(absl::Span<const uint8_t> data, absl::Span<const IpczHandle> handles, const IpczPutLimits* limits) {
diff --git a/third_party/ipcz/src/ipcz/portal.h b/third_party/ipcz/src/ipcz/portal.h index 8ca9cfc..df1fad2 100644 --- a/third_party/ipcz/src/ipcz/portal.h +++ b/third_party/ipcz/src/ipcz/portal.h
@@ -41,6 +41,7 @@ // ipcz portal API implementation: IpczResult QueryStatus(IpczPortalStatus& status); + IpczResult Merge(Portal& other); IpczResult Put(absl::Span<const uint8_t> data, absl::Span<const IpczHandle> handles,
diff --git a/third_party/ipcz/src/ipcz/route_edge.cc b/third_party/ipcz/src/ipcz/route_edge.cc index 5c702a5..5b6a371 100644 --- a/third_party/ipcz/src/ipcz/route_edge.cc +++ b/third_party/ipcz/src/ipcz/route_edge.cc
@@ -42,6 +42,14 @@ return std::move(decaying_link_); } +Ref<Router> RouteEdge::GetLocalPeer() { + return primary_link_ ? primary_link_->GetLocalPeer() : nullptr; +} + +Ref<Router> RouteEdge::GetDecayingLocalPeer() { + return decaying_link_ ? decaying_link_->GetLocalPeer() : nullptr; +} + bool RouteEdge::BeginPrimaryLinkDecay() { if (decaying_link_ || is_decay_deferred_) { return false;
diff --git a/third_party/ipcz/src/ipcz/route_edge.h b/third_party/ipcz/src/ipcz/route_edge.h index 01079af..372ad2c 100644 --- a/third_party/ipcz/src/ipcz/route_edge.h +++ b/third_party/ipcz/src/ipcz/route_edge.h
@@ -86,6 +86,14 @@ // Releases this edge's decaying link and returns a reference to it. Ref<RouterLink> ReleaseDecayingLink(); + // If the primary link is present and is a LocalRouterLink, this returns the + // Router on the other side of the link. Otherwise it returns null. + Ref<Router> GetLocalPeer(); + + // If the decaying link is present and is a LocalRouterLink, this returns the + // Router on the other side of the link. Otherwise it returns null. + Ref<Router> GetDecayingLocalPeer(); + // Sets the current primary link to begin decay; or if there is no primary // link yet, marks this edge for deferred decay. In the latter case, the next // primary link adopted by this edge will immediately begin to decay. This may
diff --git a/third_party/ipcz/src/ipcz/router.cc b/third_party/ipcz/src/ipcz/router.cc index c1277a4..551dfee 100644 --- a/third_party/ipcz/src/ipcz/router.cc +++ b/third_party/ipcz/src/ipcz/router.cc
@@ -103,8 +103,7 @@ bool Router::HasLocalPeer(Router& router) { absl::MutexLock lock(&mutex_); - return outward_edge_.primary_link() && - outward_edge_.primary_link()->GetLocalPeer() == &router; + return outward_edge_.GetLocalPeer() == &router; } IpczResult Router::AllocateOutboundParcel(size_t num_bytes, @@ -312,7 +311,7 @@ *inbound_parcels_.final_sequence_length() <= sequence_length; } - if (!inward_edge_) { + if (!inward_edge_ && !bridge_) { status_.flags |= IPCZ_PORTAL_STATUS_PEER_CLOSED; if (inbound_parcels_.IsSequenceFullyConsumed()) { status_.flags |= IPCZ_PORTAL_STATUS_DEAD; @@ -327,6 +326,11 @@ return outbound_parcels_.final_sequence_length().has_value() && *outbound_parcels_.final_sequence_length() <= sequence_length; } + } else if (link_type.is_bridge()) { + if (!outbound_parcels_.SetFinalSequenceLength(sequence_length)) { + return false; + } + bridge_.reset(); } } @@ -356,6 +360,9 @@ if (inward_edge_) { forwarding_links.push_back(inward_edge_->ReleasePrimaryLink()); forwarding_links.push_back(inward_edge_->ReleaseDecayingLink()); + } else if (bridge_) { + forwarding_links.push_back(bridge_->ReleasePrimaryLink()); + forwarding_links.push_back(bridge_->ReleaseDecayingLink()); } else { // Terminal routers may have trap events to fire. status_.flags |= IPCZ_PORTAL_STATUS_PEER_CLOSED; @@ -514,6 +521,41 @@ return IPCZ_RESULT_OK; } +IpczResult Router::MergeRoute(const Ref<Router>& other) { + if (HasLocalPeer(*other) || other == this) { + return IPCZ_RESULT_INVALID_ARGUMENT; + } + + { + MultiMutexLock lock(&mutex_, &other->mutex_); + if (inward_edge_ || other->inward_edge_ || bridge_ || other->bridge_) { + // It's not legal to call this on non-terminal routers. + return IPCZ_RESULT_INVALID_ARGUMENT; + } + + if (inbound_parcels_.current_sequence_number() > SequenceNumber(0) || + outbound_parcels_.GetCurrentSequenceLength() > SequenceNumber(0) || + other->inbound_parcels_.current_sequence_number() > SequenceNumber(0) || + other->outbound_parcels_.GetCurrentSequenceLength() > + SequenceNumber(0)) { + // It's not legal to call this on a router which has transmitted outbound + // parcels to its peer or retrieved inbound parcels from its queue. + return IPCZ_RESULT_FAILED_PRECONDITION; + } + + bridge_ = std::make_unique<RouteEdge>(); + other->bridge_ = std::make_unique<RouteEdge>(); + + RouterLink::Pair links = LocalRouterLink::CreatePair( + LinkType::kBridge, Router::Pair(WrapRefCounted(this), other)); + bridge_->SetPrimaryLink(std::move(links.first)); + other->bridge_->SetPrimaryLink(std::move(links.second)); + } + + Flush(); + return IPCZ_RESULT_OK; +} + // static Ref<Router> Router::Deserialize(const RouterDescriptor& descriptor, NodeLink& from_node_link) { @@ -672,10 +714,9 @@ return true; } - if (outward_link != &requestor || - !outward_link->GetType().is_peripheral_outward()) { - DLOG(ERROR) << "Rejecting RequestProxyBypass received on " - << requestor.Describe() << " with existing " + if (outward_link != &requestor) { + DLOG(ERROR) << "Rejecting BypassPeer received on " << requestor.Describe() + << " with existing " << outward_edge_.primary_link()->Describe(); return false; } @@ -798,10 +839,10 @@ bool Router::StopProxying(SequenceNumber inbound_sequence_length, SequenceNumber outbound_sequence_length) { + Ref<Router> bridge_peer; { absl::MutexLock lock(&mutex_); - if (outward_edge_.is_stable() || !inward_edge_ || - inward_edge_->is_stable()) { + if (outward_edge_.is_stable()) { // Proxies begin decaying their links before requesting to be bypassed, // and they don't adopt new links after that. So if either edge is stable // then someone is doing something wrong. @@ -809,13 +850,50 @@ return false; } - inward_edge_->set_length_to_decaying_link(inbound_sequence_length); - inward_edge_->set_length_from_decaying_link(outbound_sequence_length); + if (bridge_) { + // If we have a bridge link, we also need to update the router on the + // other side of the bridge. + bridge_peer = bridge_->GetDecayingLocalPeer(); + if (!bridge_peer) { + return false; + } + } else if (!inward_edge_ || inward_edge_->is_stable()) { + // Not a proxy, so this request is invalid. + return false; + } else { + inward_edge_->set_length_to_decaying_link(inbound_sequence_length); + inward_edge_->set_length_from_decaying_link(outbound_sequence_length); + outward_edge_.set_length_to_decaying_link(outbound_sequence_length); + outward_edge_.set_length_from_decaying_link(inbound_sequence_length); + } + } + + if (bridge_peer) { + MultiMutexLock lock(&mutex_, &bridge_peer->mutex_); + if (!bridge_ || bridge_->is_stable() || !bridge_peer->bridge_ || + bridge_peer->bridge_->is_stable()) { + // The bridge is being or has already been torn down, so there's nothing + // to do here. + return true; + } + + bridge_->set_length_to_decaying_link(inbound_sequence_length); + bridge_->set_length_from_decaying_link(outbound_sequence_length); outward_edge_.set_length_to_decaying_link(outbound_sequence_length); outward_edge_.set_length_from_decaying_link(inbound_sequence_length); + bridge_peer->bridge_->set_length_to_decaying_link(outbound_sequence_length); + bridge_peer->bridge_->set_length_from_decaying_link( + inbound_sequence_length); + bridge_peer->outward_edge_.set_length_to_decaying_link( + inbound_sequence_length); + bridge_peer->outward_edge_.set_length_from_decaying_link( + outbound_sequence_length); } Flush(); + if (bridge_peer) { + bridge_peer->Flush(); + } return true; } @@ -841,9 +919,12 @@ bool Router::StopProxyingToLocalPeer(SequenceNumber outbound_sequence_length) { Ref<Router> local_peer; + Ref<Router> bridge_peer; { absl::MutexLock lock(&mutex_); - if (outward_edge_.decaying_link()) { + if (bridge_) { + bridge_peer = bridge_->GetDecayingLocalPeer(); + } else if (outward_edge_.decaying_link()) { local_peer = outward_edge_.decaying_link()->GetLocalPeer(); } else { // Ignore this request if we've been unexpectedly disconnected. @@ -851,13 +932,8 @@ } } - if (!local_peer) { - // It's invalid to send call this on a Router with a non-local outward peer. - DLOG(ERROR) << "Rejecting StopProxyingToLocalPeer with no local peer"; - return false; - } - - { + if (local_peer && !bridge_peer) { + // This is the common case, with no bridge link. MultiMutexLock lock(&mutex_, &local_peer->mutex_); const Ref<RouterLink>& our_link = outward_edge_.decaying_link(); const Ref<RouterLink>& peer_link = @@ -884,10 +960,48 @@ outbound_sequence_length); outward_edge_.set_length_to_decaying_link(outbound_sequence_length); inward_edge_->set_length_from_decaying_link(outbound_sequence_length); + } else if (bridge_peer) { + // When a bridge peer is present we actually have three local routers + // involved: this router, its outward peer, and its bridge peer. Both this + // router and the bridge peer serve as "the" proxy being bypassed in this + // case, so we'll be bypassing both of them below. + { + absl::MutexLock lock(&bridge_peer->mutex_); + if (bridge_peer->outward_edge_.is_stable()) { + return false; + } + local_peer = bridge_peer->outward_edge_.GetDecayingLocalPeer(); + if (!local_peer) { + return false; + } + } + + MultiMutexLock lock(&mutex_, &local_peer->mutex_, &bridge_peer->mutex_); + if (outward_edge_.is_stable() || local_peer->outward_edge_.is_stable() || + bridge_peer->outward_edge_.is_stable()) { + return false; + } + + local_peer->outward_edge_.set_length_from_decaying_link( + outbound_sequence_length); + outward_edge_.set_length_from_decaying_link(outbound_sequence_length); + bridge_->set_length_to_decaying_link(outbound_sequence_length); + bridge_peer->outward_edge_.set_length_to_decaying_link( + outbound_sequence_length); + bridge_peer->bridge_->set_length_from_decaying_link( + outbound_sequence_length); + } else { + // It's invalid to send call this on a Router with a non-local outward peer + // or bridge link. + DLOG(ERROR) << "Rejecting StopProxyingToLocalPeer with no local peer"; + return false; } Flush(); local_peer->Flush(); + if (bridge_peer) { + bridge_peer->Flush(); + } return true; } @@ -919,10 +1033,12 @@ void Router::Flush(FlushBehavior behavior) { Ref<RouterLink> outward_link; Ref<RouterLink> inward_link; + Ref<RouterLink> bridge_link; Ref<RouterLink> decaying_outward_link; Ref<RouterLink> decaying_inward_link; Ref<RouterLink> dead_inward_link; Ref<RouterLink> dead_outward_link; + Ref<RouterLink> dead_bridge_link; absl::optional<SequenceNumber> final_inward_sequence_length; absl::optional<SequenceNumber> final_outward_sequence_length; bool on_central_link = false; @@ -941,6 +1057,11 @@ decaying_inward_link = inward_edge_ ? inward_edge_->decaying_link() : nullptr; on_central_link = outward_link && outward_link->GetType().is_central(); + if (bridge_) { + // Bridges have either a primary link or decaying link, but never both. + bridge_link = bridge_->primary_link() ? bridge_->primary_link() + : bridge_->decaying_link(); + } // Collect any parcels which are safe to transmit now. Note that we do not // transmit anything or generally call into any RouterLinks while `mutex_` @@ -978,6 +1099,14 @@ << " received"; inward_link_decayed = true; } + } else if (bridge_link) { + CollectParcelsToFlush(inbound_parcels_, *bridge_, parcels_to_flush); + } + + if (bridge_ && bridge_->MaybeFinishDecay( + inbound_parcels_.current_sequence_number(), + outbound_parcels_.current_sequence_number())) { + bridge_.reset(); } // If we're dropping the last of our decaying links, our outward link may @@ -1021,6 +1150,9 @@ final_inward_sequence_length = inbound_parcels_.final_sequence_length(); if (inward_edge_) { dead_inward_link = inward_edge_->ReleasePrimaryLink(); + } else { + dead_bridge_link = std::move(bridge_link); + bridge_.reset(); } } } @@ -1037,6 +1169,11 @@ decaying_inward_link->Deactivate(); } + if (bridge_link && outward_link && !inward_link && !decaying_inward_link && + !decaying_outward_link) { + MaybeStartBridgeBypass(); + } + if (dead_outward_link) { if (final_outward_sequence_length) { dead_outward_link->AcceptRouteClosure(*final_outward_sequence_length); @@ -1051,6 +1188,12 @@ dead_inward_link->Deactivate(); } + if (dead_bridge_link) { + if (final_inward_sequence_length) { + dead_bridge_link->AcceptRouteClosure(*final_inward_sequence_length); + } + } + if (dead_outward_link || !on_central_link) { // If we're not on a central link, there's no more work to do. return; @@ -1208,6 +1351,241 @@ return true; } +void Router::MaybeStartBridgeBypass() { + Ref<Router> first_bridge = WrapRefCounted(this); + Ref<Router> second_bridge; + { + absl::MutexLock lock(&mutex_); + if (!bridge_ || !bridge_->is_stable()) { + return; + } + + second_bridge = bridge_->GetLocalPeer(); + if (!second_bridge) { + return; + } + } + + Ref<Router> first_local_peer; + Ref<Router> second_local_peer; + Ref<RemoteRouterLink> first_remote_link; + Ref<RemoteRouterLink> second_remote_link; + { + MultiMutexLock lock(&mutex_, &second_bridge->mutex_); + const Ref<RouterLink>& link_to_first_peer = outward_edge_.primary_link(); + const Ref<RouterLink>& link_to_second_peer = + second_bridge->outward_edge_.primary_link(); + if (!link_to_first_peer || !link_to_second_peer) { + return; + } + + NodeName first_peer_node_name; + first_local_peer = link_to_first_peer->GetLocalPeer(); + first_remote_link = + WrapRefCounted(link_to_first_peer->AsRemoteRouterLink()); + if (first_remote_link) { + first_peer_node_name = first_remote_link->node_link()->remote_node_name(); + } + + NodeName second_peer_node_name; + second_local_peer = link_to_second_peer->GetLocalPeer(); + second_remote_link = + WrapRefCounted(link_to_second_peer->AsRemoteRouterLink()); + if (second_remote_link) { + second_peer_node_name = + second_remote_link->node_link()->remote_node_name(); + } + + if (!link_to_first_peer->TryLockForBypass(second_peer_node_name)) { + return; + } + if (!link_to_second_peer->TryLockForBypass(first_peer_node_name)) { + // Cancel the decay on this bridge's side, because we couldn't decay the + // other side of the bridge yet. + link_to_first_peer->Unlock(); + return; + } + } + + // At this point, the outward links from each bridge router have been locked + // for bypass. There are now three distinct cases to handle, based around + // where the outward peer routers are located. + + // Case 1: Neither bridge router's outward peer is local to this node. This is + // roughly equivalent to the normal proxy bypass case where the proxy belongs + // to a different node from its inward and outward peers. We send a message to + // our outward peer with sufficient information for it to bypass both bridge + // routers with a new central link directly to the other bridge router's + // outward peer. + if (!first_local_peer && !second_local_peer) { + { + MultiMutexLock lock(&mutex_, &second_bridge->mutex_); + outward_edge_.BeginPrimaryLinkDecay(); + second_bridge->outward_edge_.BeginPrimaryLinkDecay(); + bridge_->BeginPrimaryLinkDecay(); + second_bridge->bridge_->BeginPrimaryLinkDecay(); + } + second_remote_link->BypassPeer( + first_remote_link->node_link()->remote_node_name(), + first_remote_link->sublink()); + return; + } + + // Case 2: Only one of the bridge routers has a local outward peer. This is + // roughly equivalent to the normal proxy bypass case where the proxy and its + // outward peer belong to the same node. This case is handled separately since + // it's a bit more complex than the cases above and below. + if (!second_local_peer) { + StartBridgeBypassFromLocalPeer( + second_remote_link->node_link()->memory().TryAllocateRouterLinkState()); + return; + } else if (!first_local_peer) { + second_bridge->StartBridgeBypassFromLocalPeer( + first_remote_link->node_link()->memory().TryAllocateRouterLinkState()); + return; + } + + // Case 3: Both bridge routers' outward peers are local to this node. This is + // a unique bypass case, as it's the only scenario where all involved routers + // are local to the same node and bypass can be orchestrated synchronously in + // a single step. + { + MultiMutexLock lock(&mutex_, &second_bridge->mutex_, + &first_local_peer->mutex_, &second_local_peer->mutex_); + const SequenceNumber length_from_first_peer = + first_local_peer->outbound_parcels_.current_sequence_number(); + const SequenceNumber length_from_second_peer = + second_local_peer->outbound_parcels_.current_sequence_number(); + + RouteEdge& first_peer_edge = first_local_peer->outward_edge_; + first_peer_edge.BeginPrimaryLinkDecay(); + first_peer_edge.set_length_to_decaying_link(length_from_first_peer); + first_peer_edge.set_length_from_decaying_link(length_from_second_peer); + + RouteEdge& second_peer_edge = second_local_peer->outward_edge_; + second_peer_edge.BeginPrimaryLinkDecay(); + second_peer_edge.set_length_to_decaying_link(length_from_second_peer); + second_peer_edge.set_length_from_decaying_link(length_from_first_peer); + + outward_edge_.BeginPrimaryLinkDecay(); + outward_edge_.set_length_to_decaying_link(length_from_second_peer); + outward_edge_.set_length_from_decaying_link(length_from_first_peer); + + RouteEdge& peer_bridge_outward_edge = second_bridge->outward_edge_; + peer_bridge_outward_edge.BeginPrimaryLinkDecay(); + peer_bridge_outward_edge.set_length_to_decaying_link( + length_from_first_peer); + peer_bridge_outward_edge.set_length_from_decaying_link( + length_from_second_peer); + + bridge_->BeginPrimaryLinkDecay(); + bridge_->set_length_to_decaying_link(length_from_first_peer); + bridge_->set_length_from_decaying_link(length_from_second_peer); + + RouteEdge& peer_bridge = *second_bridge->bridge_; + peer_bridge.BeginPrimaryLinkDecay(); + peer_bridge.set_length_to_decaying_link(length_from_second_peer); + peer_bridge.set_length_from_decaying_link(length_from_first_peer); + + RouterLink::Pair links = LocalRouterLink::CreatePair( + LinkType::kCentral, Router::Pair(first_local_peer, second_local_peer)); + first_local_peer->outward_edge_.SetPrimaryLink(std::move(links.first)); + second_local_peer->outward_edge_.SetPrimaryLink(std::move(links.second)); + } + + first_bridge->Flush(); + second_bridge->Flush(); + first_local_peer->Flush(); + second_local_peer->Flush(); +} + +void Router::StartBridgeBypassFromLocalPeer( + FragmentRef<RouterLinkState> link_state) { + Ref<Router> local_peer; + Ref<Router> other_bridge; + { + absl::MutexLock lock(&mutex_); + if (!bridge_ || !bridge_->is_stable()) { + return; + } + + local_peer = outward_edge_.GetLocalPeer(); + other_bridge = bridge_->GetLocalPeer(); + if (!local_peer || !other_bridge) { + return; + } + } + + Ref<RemoteRouterLink> remote_link; + { + absl::MutexLock lock(&other_bridge->mutex_); + if (!other_bridge->outward_edge_.primary_link()) { + return; + } + + remote_link = WrapRefCounted( + other_bridge->outward_edge_.primary_link()->AsRemoteRouterLink()); + if (!remote_link) { + return; + } + } + + if (link_state.is_null()) { + // We need a new RouterLinkState on the remote link before we can complete + // this operation. + remote_link->node_link()->memory().AllocateRouterLinkState( + [router = WrapRefCounted(this)](FragmentRef<RouterLinkState> state) { + if (!state.is_null()) { + router->StartBridgeBypassFromLocalPeer(std::move(state)); + } + }); + return; + } + + // At this point, we have a new RouterLinkState for a new link, we have + // references to all three local routers (this bridge router, its local peer, + // and the other bridge router), and we have a remote link to the other bridge + // router's outward peer. This is sufficient to initiate bypass. + + const Ref<NodeLink>& node_link_to_peer = remote_link->node_link(); + SequenceNumber length_from_local_peer; + const SublinkId bypass_sublink = + node_link_to_peer->memory().AllocateSublinkIds(1); + Ref<RemoteRouterLink> new_link = node_link_to_peer->AddRemoteRouterLink( + bypass_sublink, link_state, LinkType::kCentral, LinkSide::kA, local_peer); + { + MultiMutexLock lock(&mutex_, &other_bridge->mutex_, &local_peer->mutex_); + + length_from_local_peer = + local_peer->outbound_parcels_.current_sequence_number(); + + RouteEdge& edge_from_local_peer = local_peer->outward_edge_; + edge_from_local_peer.BeginPrimaryLinkDecay(); + edge_from_local_peer.set_length_to_decaying_link(length_from_local_peer); + + RouteEdge& edge_to_other_peer = other_bridge->outward_edge_; + edge_to_other_peer.BeginPrimaryLinkDecay(); + edge_to_other_peer.set_length_to_decaying_link(length_from_local_peer); + + bridge_->BeginPrimaryLinkDecay(); + bridge_->set_length_to_decaying_link(length_from_local_peer); + + outward_edge_.BeginPrimaryLinkDecay(); + outward_edge_.set_length_from_decaying_link(length_from_local_peer); + + RouteEdge& other_bridge_edge = *other_bridge->bridge_; + other_bridge_edge.BeginPrimaryLinkDecay(); + other_bridge_edge.set_length_from_decaying_link(length_from_local_peer); + } + + remote_link->BypassPeerWithLink(bypass_sublink, std::move(link_state), + length_from_local_peer); + local_peer->SetOutwardLink(std::move(new_link)); + Flush(); + other_bridge->Flush(); + local_peer->Flush(); +} + bool Router::BypassPeerWithNewRemoteLink( RemoteRouterLink& requestor, NodeLink& node_link, @@ -1318,7 +1696,7 @@ // Otherwise immediately begin decay of both links to the proxy. if (!outward_edge_.BeginPrimaryLinkDecay() || !new_local_peer->outward_edge_.BeginPrimaryLinkDecay()) { - DLOG(ERROR) << "Rejecting RequestProxyBypass on failure to decay link"; + DLOG(ERROR) << "Rejecting BypassPeer on failure to decay link"; return false; } outward_edge_.set_length_to_decaying_link(length_to_proxy_from_us);
diff --git a/third_party/ipcz/src/ipcz/router.h b/third_party/ipcz/src/ipcz/router.h index 310b773..cb3eca95 100644 --- a/third_party/ipcz/src/ipcz/router.h +++ b/third_party/ipcz/src/ipcz/router.h
@@ -160,6 +160,12 @@ IpczTrapConditionFlags* satisfied_condition_flags, IpczPortalStatus* status); + // Attempts to merge this Router's route with the route terminated by `other`. + // Both `other` and this Router must be terminal routers on their own separate + // routes, and neither Router must have transmitted or retreived any parcels + // via Put or Get APIs. + IpczResult MergeRoute(const Ref<Router>& other); + // Deserializes a new Router from `descriptor` received over `from_node_link`. static Ref<Router> Deserialize(const RouterDescriptor& descriptor, NodeLink& from_node_link); @@ -320,6 +326,21 @@ RemoteRouterLink& inward_link, FragmentRef<RouterLinkState> new_link_state); + // Attempts to start bypass of this Router, which must be on a bridge link, as + // well bypassing the bridge link itself and the bridge peer router on its + // other side. This method will attempt to lock this Router's outward link as + // well as the outward link of this Router's bridge peer. If either fails, + // both are left unlocked and this operation cannot yet proceed. + void MaybeStartBridgeBypass(); + + // Starts bypass of this Router, which must be on a bridge link and must have + // a local outward peer link. The router on the other side of the bridge must + // have a remote outward peer, and `link_state` if non-null will be used to + // establish a new remote link to that peer to bypass the entire bridge. If + // `link_state` is null, the operation will be deferred until a fragment can + // be allocated. + void StartBridgeBypassFromLocalPeer(FragmentRef<RouterLinkState> link_state); + // Attempts to bypass the link identified by `requestor` in favor of a new // link that runs over `node_link`. If `new_link_state` is non-null, it will // be used for the RouterLinkState of the new RemoteRouterLink; otherwise one @@ -358,6 +379,10 @@ // routers by definition can have no inward edge. absl::optional<RouteEdge> inward_edge_ ABSL_GUARDED_BY(mutex_); + // A special inward edge which when present bridges this route with another + // route. This is used only to implement route merging. + std::unique_ptr<RouteEdge> bridge_ ABSL_GUARDED_BY(mutex_); + // Parcels received from the other end of the route. If this is a terminal // router, these may be retrieved by the application via a controlling portal; // otherwise they will be forwarded along `inward_edge_` as soon as possible.
diff --git a/third_party/ipcz/src/merge_portals_test.cc b/third_party/ipcz/src/merge_portals_test.cc new file mode 100644 index 0000000..a25008a --- /dev/null +++ b/third_party/ipcz/src/merge_portals_test.cc
@@ -0,0 +1,129 @@ +// Copyright 2022 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 <string> +#include <string_view> + +#include "ipcz/ipcz.h" +#include "test/multinode_test.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace ipcz { +namespace { + +using MergePortalsTestNode = test::TestNode; +using MergePortalsTest = test::MultinodeTest<MergePortalsTestNode>; + +constexpr std::string_view kMessage1 = "bork bork"; +constexpr std::string_view kMessage2 = "aw heck"; + +MULTINODE_TEST_NODE(MergePortalsTestNode, MergeWithInitialPortalClient) { + IpczHandle b = ConnectToBroker(); + + std::string message; + EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(b, &message)); + EXPECT_EQ(kMessage1, message); + EXPECT_EQ(IPCZ_RESULT_OK, Put(b, kMessage2)); + WaitForDirectRemoteLink(b); + EXPECT_EQ(IPCZ_RESULT_OK, WaitForConditionFlags(b, IPCZ_TRAP_PEER_CLOSED)); + Close(b); +} + +TEST_P(MergePortalsTest, MergeWithInitialPortal) { + IpczHandle c = SpawnTestNode<MergeWithInitialPortalClient>(); + auto [q, p] = OpenPortals(); + EXPECT_EQ(IPCZ_RESULT_OK, Merge(c, p)); + EXPECT_EQ(IPCZ_RESULT_OK, Put(q, kMessage1)); + + std::string message; + EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(q, &message)); + EXPECT_EQ(kMessage2, message); + WaitForDirectRemoteLink(q); + Close(q); +} + +TEST_P(MergePortalsTest, MergeWithClosedLocalPeer) { + auto [q, p] = OpenPortals(); + auto [d, b] = OpenPortals(); + + Close(d); + EXPECT_EQ(IPCZ_RESULT_OK, Merge(b, p)); + EXPECT_EQ(IPCZ_RESULT_OK, WaitForConditionFlags(q, IPCZ_TRAP_PEER_CLOSED)); + Close(q); +} + +MULTINODE_TEST_NODE(MergePortalsTestNode, MergeWithClosedRemotePeerClient) { + IpczHandle b = ConnectToBroker(); + auto [q, p] = OpenPortals(); + Close(q); + IpczHandle r; + EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(b, nullptr, {&r, 1})); + Merge(p, r); + EXPECT_EQ(IPCZ_RESULT_OK, WaitForConditionFlags(b, IPCZ_TRAP_PEER_CLOSED)); + Close(b); +} + +TEST_P(MergePortalsTest, MergeWithClosedRemotePeer) { + IpczHandle c = SpawnTestNode<MergeWithClosedRemotePeerClient>(); + auto [r, s] = OpenPortals(); + EXPECT_EQ(IPCZ_RESULT_OK, Put(c, "", {&r, 1})); + EXPECT_EQ(IPCZ_RESULT_OK, WaitForConditionFlags(s, IPCZ_TRAP_PEER_CLOSED)); + CloseAll({c, s}); +} + +constexpr size_t kMergeComplexRoutesNumIterations = 1000; + +MULTINODE_TEST_NODE(MergePortalsTestNode, MergeComplexRoutesClient) { + IpczHandle b = ConnectToBroker(); + IpczHandle other_client; + IpczHandle portal; + EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(b, nullptr, {&other_client, 1})); + EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(b, nullptr, {&portal, 1})); + + for (size_t i = 0; i < kMergeComplexRoutesNumIterations; ++i) { + EXPECT_EQ(IPCZ_RESULT_OK, Put(other_client, "", {&portal, 1})); + EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(other_client, nullptr, {&portal, 1})); + EXPECT_EQ(IPCZ_RESULT_OK, Put(b, "", {&portal, 1})); + EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(b, nullptr, {&portal, 1})); + } + + WaitForDirectRemoteLink(portal); + PingPong(portal); + EXPECT_EQ(IPCZ_RESULT_OK, Put(b, "done")); + EXPECT_EQ(IPCZ_RESULT_OK, WaitForConditionFlags(b, IPCZ_TRAP_PEER_CLOSED)); + CloseAll({b, portal, other_client}); +} + +TEST_P(MergePortalsTest, MergeComplexRoutes) { + IpczHandle c1 = SpawnTestNode<MergeComplexRoutesClient>(); + IpczHandle c2 = SpawnTestNode<MergeComplexRoutesClient>(); + + auto [q, p] = OpenPortals(); + EXPECT_EQ(IPCZ_RESULT_OK, Put(c1, "", {&q, 1})); + EXPECT_EQ(IPCZ_RESULT_OK, Put(c2, "", {&p, 1})); + + auto [s, t] = OpenPortals(); + auto [u, v] = OpenPortals(); + EXPECT_EQ(IPCZ_RESULT_OK, Put(c1, "", {&t, 1})); + EXPECT_EQ(IPCZ_RESULT_OK, Put(c2, "", {&v, 1})); + + for (size_t i = 0; i < kMergeComplexRoutesNumIterations; ++i) { + EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(c1, nullptr, {&t, 1})); + EXPECT_EQ(IPCZ_RESULT_OK, Put(c1, "", {&t, 1})); + EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(c2, nullptr, {&v, 1})); + EXPECT_EQ(IPCZ_RESULT_OK, Put(c2, "", {&v, 1})); + } + + Merge(s, u); + + std::string message; + EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(c1, &message)); + EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(c2, &message)); + CloseAll({c1, c2}); +} + +INSTANTIATE_MULTINODE_TEST_SUITE_P(MergePortalsTest); + +} // namespace +} // namespace ipcz
diff --git a/third_party/ipcz/src/test/test_base.cc b/third_party/ipcz/src/test/test_base.cc index 13c85cc..087ed1ac 100644 --- a/third_party/ipcz/src/test/test_base.cc +++ b/third_party/ipcz/src/test/test_base.cc
@@ -55,6 +55,10 @@ } } +IpczResult TestBase::Merge(IpczHandle a, IpczHandle b) { + return ipcz().MergePortals(a, b, IPCZ_NO_FLAGS, nullptr); +} + IpczHandle TestBase::CreateNode(const IpczDriver& driver, IpczCreateNodeFlags flags) { IpczHandle node;
diff --git a/third_party/ipcz/src/test/test_base.h b/third_party/ipcz/src/test/test_base.h index 4786fbf6..3b3df98b 100644 --- a/third_party/ipcz/src/test/test_base.h +++ b/third_party/ipcz/src/test/test_base.h
@@ -35,6 +35,7 @@ // Some trivial shorthand methods to access the ipcz API more conveniently. void Close(IpczHandle handle); void CloseAll(absl::Span<const IpczHandle> handles); + IpczResult Merge(IpczHandle a, IpczHandle b); IpczHandle CreateNode(const IpczDriver& driver, IpczCreateNodeFlags flags = IPCZ_NO_FLAGS); std::pair<IpczHandle, IpczHandle> OpenPortals(IpczHandle node);
diff --git a/third_party/ipcz/src/util/ref_counted.h b/third_party/ipcz/src/util/ref_counted.h index f57c7d3..d991b50 100644 --- a/third_party/ipcz/src/util/ref_counted.h +++ b/third_party/ipcz/src/util/ref_counted.h
@@ -96,6 +96,8 @@ T* release() { return static_cast<T*>(ReleaseImpl()); } + void swap(Ref<T>& other) noexcept { std::swap(ptr_, other.ptr_); } + template <typename H> friend H AbslHashValue(H h, const Ref<T>& ref) { return H::combine(std::move(h), ref.get());
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 6cf9110..a239362 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -59394,6 +59394,7 @@ label="QueryTilesRemoveTrendingAfterInactivity:disabled"/> <int value="193865288" label="EnableSuggestedLocalFiles:enabled"/> <int value="194573877" label="MacViewsNativeDialogs:disabled"/> + <int value="194645300" label="FileTransferEnterpriseConnector:disabled"/> <int value="194895489" label="passive-listeners-default"/> <int value="195112080" label="DeskTemplateSync:enabled"/> <int value="195335115" label="AudioWorkletRealtimeThread:disabled"/> @@ -61038,6 +61039,7 @@ <int value="1230555479" label="AutofillEnableUnmaskCardRequestSetInstrumentId:disabled"/> <int value="1234601252" label="ForceUseAPDownloadProtection:enabled"/> + <int value="1234950775" label="FileTransferEnterpriseConnector:enabled"/> <int value="1235197204" label="AvatarsCloudMigration:enabled"/> <int value="1235800887" label="V8Ignition:enabled"/> <int value="1235940786" label="ChromeHomePersistentIph:enabled"/>
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml index e9e3d82..c988eb3f 100644 --- a/tools/metrics/histograms/metadata/autofill/histograms.xml +++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -2693,18 +2693,6 @@ </summary> </histogram> -<histogram name="Autofill.ProfileImport.UpdateProfileAffectedType" - enum="AutofillSettingsVisibleTypes" expires_after="2022-12-25"> - <owner>koerber@google.com</owner> - <owner>src/components/autofill/OWNERS</owner> - <summary> - Logs that a specific type was changed in a profile update process that was - shown to the user when a profile similar to an already existing profile was - observed in a form submission. This metric is emitted only when the user - accepts the update without further edits. - </summary> -</histogram> - <histogram name="Autofill.ProfileImport.UpdateProfileAffectedType.{Decision}" enum="AutofillSettingsVisibleTypes" expires_after="M108"> <owner>koerber@google.com</owner> @@ -2785,18 +2773,6 @@ </summary> </histogram> -<histogram name="Autofill.ProfileImport.UpdateProfileNumberOfAffectedFields" - units="fields" expires_after="2022-08-21"> - <owner>koerber@google.com</owner> - <owner>src/components/autofill/OWNERS</owner> - <summary> - Logs the number of fields that have been changed in the process of - succesfully updating an existing profile after an observed form submission. - This metric is only collected if the profile update is accepted by the user - without further edits. - </summary> -</histogram> - <histogram name="Autofill.ProfileImport.UpdateProfileNumberOfAffectedFields.{Decision}" units="fields" expires_after="M108">
diff --git a/tools/metrics/histograms/print_expanded_histograms.py b/tools/metrics/histograms/print_expanded_histograms.py index 8fc6faf..b04368d 100755 --- a/tools/metrics/histograms/print_expanded_histograms.py +++ b/tools/metrics/histograms/print_expanded_histograms.py
@@ -33,7 +33,7 @@ obsolete_node.appendChild(doc.createTextNode(histogram_dict['obsolete'])) histogram.appendChild(obsolete_node) # Populate owner nodes. - for owner in histogram_dict['owners']: + for owner in histogram_dict.get('owners', []): owner_node = doc.createElement('owner') owner_node.appendChild(doc.createTextNode(owner)) histogram.appendChild(owner_node)
diff --git a/ui/base/ime/ash/input_method_ash.cc b/ui/base/ime/ash/input_method_ash.cc index aa56ce7d..e67ef5a2 100644 --- a/ui/base/ime/ash/input_method_ash.cc +++ b/ui/base/ime/ash/input_method_ash.cc
@@ -373,8 +373,9 @@ if (!client->GetEditableSelectionRange(&range)) return false; - const gfx::Range composition_range(range.start() - before, - range.end() + after); + const gfx::Range composition_range( + range.start() >= before ? range.start() - before : 0, + range.end() + after); // Check that the composition range is valid. gfx::Range text_range;
diff --git a/ui/base/ime/ash/input_method_ash_unittest.cc b/ui/base/ime/ash/input_method_ash_unittest.cc index fb09edc..02e4d4a 100644 --- a/ui/base/ime/ash/input_method_ash_unittest.cc +++ b/ui/base/ime/ash/input_method_ash_unittest.cc
@@ -593,6 +593,18 @@ composition_text.ime_text_spans[0].thickness); } +TEST_F(InputMethodAshTest, SetCompositionTextFails) { + InputMethodAsh ime(this); + FakeTextInputClient fake_text_input_client(TEXT_INPUT_TYPE_TEXT); + ime.SetFocusedTextInputClient(&fake_text_input_client); + + EXPECT_EQ(ime.GetTextInputType(), TEXT_INPUT_TYPE_TEXT); + // Intentionally have a range start that does not exist. + EXPECT_FALSE(ime.SetCompositionRange(10000, 5, {})); + + ime.SetFocusedTextInputClient(nullptr); +} + TEST_F(InputMethodAshTest, ExtractCompositionTextTest_SingleUnderline) { const uint32_t kCursorPos = 2UL;